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