1 /* Fo
2 * fo-property-font-variant.c: 'font-variant' property
3 *
4 * Copyright (C) 2001-2006 Sun Microsystems
5 * Copyright (C) 2007-2008 Menteith Consulting Ltd
6 *
7 * See COPYING for the status of this software.
8 */
9
10 #include <string.h>
11 #include "libfo/fo-utils.h"
12 #include "fo-context.h"
13 #include "datatype/fo-datatype.h"
14 #include "property/fo-property-private.h"
15 #include "property/fo-property-text-property.h"
16 #include "property/fo-property-font-size.h"
17 #include "property/fo-property-font-variant.h"
18
19 /* font-variant */
20 /* Inherited: TRUE */
21 /* Shorthand: FALSE */
22 /* normal | small-caps | inherit */
23 /* Initial value: normal */
24
25 struct _FoPropertyFontVariant
26 {
27 FoProperty parent_instance;
28 };
29
30 struct _FoPropertyFontVariantClass
31 {
32 FoPropertyClass parent_class;
33 };
34
35 static void fo_property_font_variant_init (FoPropertyFontVariant *property_font_variant);
36 static void fo_property_font_variant_class_init (FoPropertyFontVariantClass *klass);
37 static void fo_property_font_variant_finalize (GObject *object);
38 static void fo_property_font_variant_text_property_init (FoPropertyTextPropertyIface *iface);
39
40 static FoDatatype * fo_property_font_variant_resolve_enum (const gchar *token,
41 FoContext *context,
42 GError **error);
43 static FoDatatype * fo_property_font_variant_validate (FoDatatype *datatype,
44 FoContext *context,
45 GError **error);
46 static PangoAttribute * fo_property_font_variant_new_attr (FoProperty *property);
47
48 static const gchar class_name[] = "font-variant";
49 static gpointer parent_class;
50
51 /**
52 * fo_property_font_variant_get_type:
53 *
54 * Register the #FoPropertyFontVariant type if not already registered and
55 * return its #GType value.
56 *
57 * Return value: #GType of #FoPropertyFontVariant.
58 **/
59 GType
fo_property_font_variant_get_type(void)60 fo_property_font_variant_get_type (void)
61 {
62 static GType object_type = 0;
63
64 if (!object_type)
65 {
66 static const GTypeInfo object_info =
67 {
68 sizeof (FoPropertyFontVariantClass),
69 NULL, /* base_init */
70 NULL, /* base_finalize */
71 (GClassInitFunc) fo_property_font_variant_class_init,
72 NULL, /* class_finalize */
73 NULL, /* class_data */
74 sizeof (FoPropertyFontVariant),
75 0, /* n_preallocs */
76 (GInstanceInitFunc) fo_property_font_variant_init,
77 NULL /* value_table */
78 };
79
80 static const GInterfaceInfo fo_property_text_property_info =
81 {
82 (GInterfaceInitFunc) fo_property_font_variant_text_property_init, /* interface_init */
83 NULL,
84 NULL
85 };
86
87 object_type = g_type_register_static (FO_TYPE_PROPERTY,
88 class_name,
89 &object_info, 0);
90
91 g_type_add_interface_static (object_type,
92 FO_TYPE_PROPERTY_TEXT_PROPERTY,
93 &fo_property_text_property_info);
94 }
95
96 return object_type;
97 }
98
99 /**
100 * fo_property_font_variant_init:
101 * @font_variant: #FoPropertyFontVariant object to initialise.
102 *
103 * Implements #GInstanceInitFunc for #FoPropertyFontVariant.
104 **/
105 void
fo_property_font_variant_init(FoPropertyFontVariant * font_variant)106 fo_property_font_variant_init (FoPropertyFontVariant *font_variant)
107 {
108 FO_PROPERTY (font_variant)->value =
109 g_object_ref (fo_enum_factory_get_enum_by_nick ("normal"));
110 }
111
112 /**
113 * fo_property_font_variant_class_init:
114 * @klass: #FoPropertyFontVariantClass object to initialise.
115 *
116 * Implements #GClassInitFunc for #FoPropertyFontVariantClass.
117 **/
118 void
fo_property_font_variant_class_init(FoPropertyFontVariantClass * klass)119 fo_property_font_variant_class_init (FoPropertyFontVariantClass *klass)
120 {
121 GObjectClass *object_class = G_OBJECT_CLASS (klass);
122 FoPropertyClass *property_class = FO_PROPERTY_CLASS (klass);
123
124 parent_class = g_type_class_peek_parent (klass);
125
126 object_class->finalize = fo_property_font_variant_finalize;
127
128 property_class->is_inherited = TRUE;
129 property_class->is_shorthand = FALSE;
130 property_class->resolve_enum =
131 fo_property_font_variant_resolve_enum;
132 property_class->validate =
133 fo_property_font_variant_validate;
134 property_class->get_initial =
135 fo_property_font_variant_get_initial;
136 }
137
138 /**
139 * fo_property_font_variant_finalize:
140 * @object: #FoPropertyFontVariant object to finalize.
141 *
142 * Implements #GObjectFinalizeFunc for #FoPropertyFontVariant.
143 **/
144 void
fo_property_font_variant_finalize(GObject * object)145 fo_property_font_variant_finalize (GObject *object)
146 {
147 FoPropertyFontVariant *font_variant;
148
149 font_variant = FO_PROPERTY_FONT_VARIANT (object);
150
151 G_OBJECT_CLASS (parent_class)->finalize (object);
152 }
153
154 /**
155 * fo_property_font_variant_text_property_init:
156 * @iface: #FoPropertyTextPropertyIFace structure for this class.
157 *
158 * Initialize #FoPropertyTextPropertyIface interface for this class.
159 **/
160 void
fo_property_font_variant_text_property_init(FoPropertyTextPropertyIface * iface)161 fo_property_font_variant_text_property_init (FoPropertyTextPropertyIface *iface)
162 {
163 iface->new_attr = fo_property_font_variant_new_attr;
164 }
165
166 /**
167 * fo_property_font_variant_new:
168 *
169 * Creates a new #FoPropertyFontVariant initialized to default value.
170 *
171 * Return value: the new #FoPropertyFontVariant.
172 **/
173 FoProperty*
fo_property_font_variant_new(void)174 fo_property_font_variant_new (void)
175 {
176 FoProperty* font_variant;
177
178 font_variant =
179 FO_PROPERTY (g_object_new (fo_property_font_variant_get_type (),
180 NULL));
181
182 return font_variant;
183 }
184
185 /**
186 * fo_property_font_variant_resolve_enum:
187 * @token: Token from the XML attribute value to be evaluated as an
188 * enumeration token.
189 * @context: #FoContext object from which to possibly inherit values.
190 * @error: Information about any error that has occurred.
191 *
192 * Compare @token against the enumeration tokens that are valid for the
193 * current FO property. If @token is valid, returns either an #FoEnum datatype
194 * representing the enumeration token or a different datatype representing
195 * the enumeration token's resolved value. If @token is not valid,
196 * sets @error and returns NULL.
197 *
198 * Return value: Resolved enumeration value or NULL.
199 **/
200 FoDatatype*
fo_property_font_variant_resolve_enum(const gchar * token,FoContext * context,GError ** error)201 fo_property_font_variant_resolve_enum (const gchar *token,
202 FoContext *context,
203 GError **error)
204 {
205 g_return_val_if_fail (token != NULL, NULL);
206 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
207 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
208
209 if ((strcmp (token, "normal") == 0) ||
210 (strcmp (token, "small-caps") == 0))
211 {
212 return g_object_ref (fo_enum_factory_get_enum_by_nick (token));
213 }
214 else
215 {
216 g_set_error (error,
217 FO_FO_ERROR,
218 FO_FO_ERROR_ENUMERATION_TOKEN,
219 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
220 class_name,
221 token);
222 return NULL;
223 }
224 }
225
226 /**
227 * fo_property_font_variant_validate:
228 * @datatype: #FoDatatype to be validated against allowed datatypes and
229 * values for current property.
230 * @context: #FoContext object from which to possibly inherit values.
231 * @error: Information about any error that has occurred.
232 *
233 * Validates @datatype against allowed values. Returns @datatype, a
234 * replacement datatype value, or NULL if validation failed.
235 *
236 * Return value: Valid datatype value or NULL.
237 **/
238 FoDatatype*
fo_property_font_variant_validate(FoDatatype * datatype,FoContext * context,GError ** error)239 fo_property_font_variant_validate (FoDatatype *datatype,
240 FoContext *context,
241 GError **error)
242 {
243 FoDatatype *new_datatype;
244 GError *tmp_error = NULL;
245 gchar *token;
246
247 g_return_val_if_fail (datatype != NULL, NULL);
248 g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL);
249 g_return_val_if_fail (context != NULL, NULL);
250 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
251 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
252
253 if (FO_IS_ENUM (datatype))
254 {
255 FoEnumEnum value = fo_enum_get_value (datatype);
256
257 if ((value == FO_ENUM_ENUM_NORMAL) ||
258 (value == FO_ENUM_ENUM_SMALL_CAPS))
259 {
260 return datatype;
261 }
262 else
263 {
264 gchar *datatype_sprintf = fo_object_sprintf (datatype);
265
266 g_set_error (error,
267 FO_FO_ERROR,
268 FO_FO_ERROR_ENUMERATION_TOKEN,
269 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
270 class_name,
271 datatype_sprintf,
272 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
273
274 g_object_unref (datatype);
275
276 g_free (datatype_sprintf);
277
278 return NULL;
279 }
280 }
281 else if (FO_IS_STRING (datatype))
282 {
283 token = fo_string_get_value (datatype);
284
285 new_datatype =
286 fo_property_font_variant_resolve_enum (token, context, &tmp_error);
287
288 g_object_unref (datatype);
289
290 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
291
292 return new_datatype;
293 }
294 else if (FO_IS_NAME (datatype))
295 {
296 token = fo_name_get_value (datatype);
297
298 new_datatype =
299 fo_property_font_variant_resolve_enum (token, context, &tmp_error);
300
301 g_object_unref (datatype);
302
303 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
304
305 return new_datatype;
306 }
307 else
308 {
309 gchar *datatype_sprintf = fo_object_sprintf (datatype);
310
311 g_set_error (error,
312 FO_FO_ERROR,
313 FO_FO_ERROR_DATATYPE,
314 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
315 class_name,
316 datatype_sprintf,
317 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
318
319 g_object_unref (datatype);
320
321 g_free (datatype_sprintf);
322
323 return NULL;
324 }
325 }
326
327 /**
328 * fo_property_font_variant_get_initial:
329 *
330 * Get an instance of the property with the correct initial value.
331 *
332 * Return value: An instance of the property.
333 **/
334 FoProperty*
fo_property_font_variant_get_initial(void)335 fo_property_font_variant_get_initial (void)
336 {
337 static FoProperty *font_variant = NULL;
338
339 if (font_variant == NULL)
340 {
341 font_variant =
342 fo_property_font_variant_new ();
343 }
344
345 return font_variant;
346 }
347
348 static PangoVariant
fo_property_font_variant_to_pango_variant(FoProperty * property)349 fo_property_font_variant_to_pango_variant (FoProperty *property)
350 {
351 FoEnumEnum font_variant;
352 PangoVariant pango_font_variant = PANGO_VARIANT_NORMAL;
353
354 /* No 'invalid' font variant so default to 'normal' if fail */
355 g_return_val_if_fail (FO_IS_PROPERTY_FONT_VARIANT (property),
356 pango_font_variant);
357
358
359 font_variant = fo_enum_get_value (property->value);
360
361 if (font_variant == FO_ENUM_ENUM_SMALL_CAPS)
362 {
363 pango_font_variant = PANGO_VARIANT_SMALL_CAPS;
364 }
365
366 return pango_font_variant;
367 }
368
369 /**
370 * fo_property_font_variant_new_attr:
371 * @property: #FoProperty from which to create a #PangoAttribute.
372 *
373 * Makes a new #PangoAttribute representing the current property.
374 *
375 * Return value: New #PangoAttribute.
376 **/
377 PangoAttribute*
fo_property_font_variant_new_attr(FoProperty * property)378 fo_property_font_variant_new_attr (FoProperty *property)
379 {
380 PangoVariant pango_font_variant;
381
382 g_return_val_if_fail (FO_IS_PROPERTY_FONT_VARIANT (property), NULL);
383
384 pango_font_variant =
385 fo_property_font_variant_to_pango_variant (property);
386
387 return pango_attr_variant_new (pango_font_variant);
388 }
389