1 /* Fo
2 * fo-property-dominant-baseline.c: 'dominant-baseline' property
3 *
4 * Copyright (C) 2001-2006 Sun Microsystems
5 * Copyright (C) 2007-2010 Menteith Consulting Ltd
6 *
7 * See COPYING for the status of this software.
8 */
9
10 #include <string.h>
11 #include "fo-utils.h"
12 #include "fo-context.h"
13 #include "datatype/fo-datatype.h"
14 #include "property/fo-property-private.h"
15 /*
16 Don't use until property is reimplemented in Pango.
17 #include "property/fo-property-text-property.h"
18 */
19 #include "property/fo-property-font-size.h"
20 #include "property/fo-property-font-style.h"
21 #include "property/fo-property-dominant-baseline.h"
22
23 /**
24 * SECTION:fo-property-dominant-baseline
25 * @short_description: 'dominant-baseline' property
26 *
27 * Inherited: FALSE
28 *
29 * Shorthand: FALSE
30 *
31 * Value: auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge | inherit
32 *
33 * Initial value: auto
34 *
35 * Definition: <ulink url="http://www.w3.org/TR/xsl11/#dominant-baseline">http://www.w3.org/TR/xsl11/#dominant-baseline</ulink>
36 */
37
38 struct _FoPropertyDominantBaseline
39 {
40 FoProperty parent_instance;
41 };
42
43 struct _FoPropertyDominantBaselineClass
44 {
45 FoPropertyClass parent_class;
46 };
47
48 static void _init (FoPropertyDominantBaseline *property_dominant_baseline);
49 static void _class_init (FoPropertyDominantBaselineClass *klass);
50
51 static FoDatatype * _resolve_enum (const gchar *token,
52 FoContext *context,
53 GError **error);
54 static FoDatatype * _validate (FoDatatype *datatype,
55 FoContext *context,
56 GError **error);
57 /*
58 static void _text_property_init (FoPropertyTextPropertyIface *iface);
59 PangoAttribute * fo_property_dominant_baseline_new_attr_from_context (FoProperty *property,
60 FoContext *context);
61 */
62 static const gchar class_name[] = "dominant-baseline";
63 static gpointer parent_class;
64
65 /**
66 * fo_property_dominant_baseline_get_type:
67 *
68 * Register the #FoPropertyDominantBaseline type if not already registered and
69 * return its #GType value.
70 *
71 * Return value: #GType of #FoPropertyDominantBaseline.
72 **/
73 GType
fo_property_dominant_baseline_get_type(void)74 fo_property_dominant_baseline_get_type (void)
75 {
76 static GType object_type = 0;
77
78 if (!object_type)
79 {
80 static const GTypeInfo object_info =
81 {
82 sizeof (FoPropertyDominantBaselineClass),
83 NULL, /* base_init */
84 NULL, /* base_finalize */
85 (GClassInitFunc) _class_init,
86 NULL, /* class_finalize */
87 NULL, /* class_data */
88 sizeof (FoPropertyDominantBaseline),
89 0, /* n_preallocs */
90 (GInstanceInitFunc) _init,
91 NULL /* value_table */
92 };
93 /*
94 static const GInterfaceInfo fo_property_text_property_info =
95 {
96 (GInterfaceInitFunc) _text_property_init, / * interface_init * /
97 NULL,
98 NULL
99 };
100 */
101 object_type = g_type_register_static (FO_TYPE_PROPERTY,
102 class_name,
103 &object_info, 0);
104 /*
105 g_type_add_interface_static (object_type,
106 FO_TYPE_PROPERTY_TEXT_PROPERTY,
107 &fo_property_text_property_info);
108 */
109 }
110
111 return object_type;
112 }
113
114 /**
115 * _init:
116 * @dominant_baseline: #FoPropertyDominantBaseline object to initialise.
117 *
118 * Implements #GInstanceInitFunc for #FoPropertyDominantBaseline.
119 **/
120 static void
_init(FoPropertyDominantBaseline * dominant_baseline)121 _init (FoPropertyDominantBaseline *dominant_baseline)
122 {
123 FO_PROPERTY (dominant_baseline)->value =
124 g_object_ref (fo_enum_factory_get_enum_by_value (FO_ENUM_ENUM_AUTO));
125 }
126
127 /**
128 * _class_init:
129 * @klass: #FoPropertyDominantBaselineClass object to initialise.
130 *
131 * Implements #GClassInitFunc for #FoPropertyDominantBaselineClass.
132 **/
133 static void
_class_init(FoPropertyDominantBaselineClass * klass)134 _class_init (FoPropertyDominantBaselineClass *klass)
135 {
136 GObjectClass *object_class = G_OBJECT_CLASS (klass);
137 FoPropertyClass *property_class = FO_PROPERTY_CLASS (klass);
138
139 parent_class = g_type_class_peek_parent (klass);
140
141
142 property_class->is_inherited = FALSE;
143 property_class->is_shorthand = FALSE;
144 property_class->resolve_enum =
145 _resolve_enum;
146 property_class->validate =
147 _validate;
148 property_class->get_initial =
149 fo_property_dominant_baseline_get_initial;
150 }
151
152 /**
153 * _text_property_init:
154 * @iface: #FoPropertyTextPropertyIFace structure for this class.
155 *
156 * Initialize #FoPropertyTextPropertyIface interface for this class.
157 **/
158 /*
159 static void
160 _text_property_init (FoPropertyTextPropertyIface *iface)
161 {
162 iface->new_attr = fo_property_dominant_baseline_new_attr;
163 }
164 */
165
166 /**
167 * fo_property_dominant_baseline_new:
168 *
169 * Creates a new #FoPropertyDominantBaseline initialized to default value.
170 *
171 * Return value: the new #FoPropertyDominantBaseline.
172 **/
173 FoProperty*
fo_property_dominant_baseline_new(void)174 fo_property_dominant_baseline_new (void)
175 {
176 FoProperty* dominant_baseline;
177
178 dominant_baseline =
179 FO_PROPERTY (g_object_new (fo_property_dominant_baseline_get_type (),
180 NULL));
181
182 return dominant_baseline;
183 }
184
185 /**
186 * _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 static FoDatatype *
_resolve_enum(const gchar * token,FoContext * context,GError ** error)201 _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, "auto") == 0) ||
210 (strcmp (token, "use-script") == 0) ||
211 (strcmp (token, "no-change") == 0) ||
212 (strcmp (token, "reset-size") == 0) ||
213 (strcmp (token, "ideographic") == 0) ||
214 (strcmp (token, "alphabetic") == 0) ||
215 (strcmp (token, "hanging") == 0) ||
216 (strcmp (token, "mathematical") == 0) ||
217 (strcmp (token, "central") == 0) ||
218 (strcmp (token, "middle") == 0) ||
219 (strcmp (token, "text-after-edge") == 0) ||
220 (strcmp (token, "text-before-edge") == 0))
221 {
222 return g_object_ref (fo_enum_factory_get_enum_by_nick (token));
223 }
224 else
225 {
226 g_set_error (error,
227 FO_FO_ERROR,
228 FO_FO_ERROR_ENUMERATION_TOKEN,
229 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
230 class_name,
231 token);
232 return NULL;
233 }
234 }
235
236 /**
237 * _validate:
238 * @datatype: #FoDatatype to be validated against allowed datatypes and
239 * values for current property.
240 * @context: #FoContext object from which to possibly inherit values.
241 * @error: Information about any error that has occurred.
242 *
243 * Validates @datatype against allowed values. Returns @datatype, a
244 * replacement datatype value, or NULL if validation failed.
245 *
246 * Return value: Valid datatype value or NULL.
247 **/
248 FoDatatype*
_validate(FoDatatype * datatype,FoContext * context,GError ** error)249 _validate (FoDatatype *datatype,
250 FoContext *context,
251 GError **error)
252 {
253 FoDatatype *new_datatype;
254 GError *tmp_error = NULL;
255 gchar *token;
256
257 g_return_val_if_fail (datatype != NULL, NULL);
258 g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL);
259 g_return_val_if_fail (context != NULL, NULL);
260 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
261 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
262
263 if (FO_IS_ENUM (datatype))
264 {
265 FoEnumEnum value = fo_enum_get_value (datatype);
266
267 if ((value == FO_ENUM_ENUM_AUTO) ||
268 (value == FO_ENUM_ENUM_USE_SCRIPT) ||
269 (value == FO_ENUM_ENUM_NO_CHANGE) ||
270 (value == FO_ENUM_ENUM_RESET_SIZE) ||
271 (value == FO_ENUM_ENUM_IDEOGRAPHIC) ||
272 (value == FO_ENUM_ENUM_ALPHABETIC) ||
273 (value == FO_ENUM_ENUM_HANGING) ||
274 (value == FO_ENUM_ENUM_MATHEMATICAL) ||
275 (value == FO_ENUM_ENUM_CENTRAL) ||
276 (value == FO_ENUM_ENUM_MIDDLE) ||
277 (value == FO_ENUM_ENUM_TEXT_AFTER_EDGE) ||
278 (value == FO_ENUM_ENUM_TEXT_BEFORE_EDGE))
279 {
280 return datatype;
281 }
282 else
283 {
284 gchar *datatype_sprintf = fo_object_sprintf (datatype);
285
286 g_set_error (error,
287 FO_FO_ERROR,
288 FO_FO_ERROR_ENUMERATION_TOKEN,
289 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
290 class_name,
291 datatype_sprintf,
292 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
293
294 g_object_unref (datatype);
295
296 g_free (datatype_sprintf);
297
298 return NULL;
299 }
300 }
301 else if (FO_IS_STRING (datatype))
302 {
303 token = fo_string_get_value (datatype);
304
305 new_datatype =
306 _resolve_enum (token, context, &tmp_error);
307
308 g_object_unref (datatype);
309
310 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
311
312 return new_datatype;
313 }
314 else if (FO_IS_NAME (datatype))
315 {
316 token = fo_name_get_value (datatype);
317
318 new_datatype =
319 _resolve_enum (token, context, &tmp_error);
320
321 g_object_unref (datatype);
322
323 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
324
325 return new_datatype;
326 }
327 else
328 {
329 gchar *datatype_sprintf = fo_object_sprintf (datatype);
330
331 g_set_error (error,
332 FO_FO_ERROR,
333 FO_FO_ERROR_DATATYPE,
334 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
335 class_name,
336 datatype_sprintf,
337 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
338
339 g_object_unref (datatype);
340
341 g_free (datatype_sprintf);
342
343 return NULL;
344 }
345 }
346
347 /**
348 * fo_property_dominant_baseline_get_initial:
349 *
350 * Get an instance of the property with the correct initial value.
351 *
352 * Return value: An instance of the property.
353 **/
354 FoProperty*
fo_property_dominant_baseline_get_initial(void)355 fo_property_dominant_baseline_get_initial (void)
356 {
357 static FoProperty *dominant_baseline = NULL;
358
359 if (dominant_baseline == NULL)
360 {
361 dominant_baseline =
362 fo_property_dominant_baseline_new ();
363 }
364
365 return dominant_baseline;
366 }
367
368 /**
369 * fo_property_dominant_baseline_to_pango_baseline:
370 * @baseline: #FoEnumDominantBaseline to convert to #PangoBaseline value.
371 *
372 * Gets the #PangoBaseline value corresponding to the value of
373 * @baseline.
374 *
375 * Return value: A #PangoBaseline value, which could be
376 * #PANGO_BASELINE_INVALID.
377 **/
378 /*
379 static PangoBaseline
380 fo_property_dominant_baseline_to_pango_baseline (FoEnumEnum baseline)
381 {
382 switch (baseline)
383 {
384 case FO_ENUM_ENUM_AUTO:
385 return PANGO_BASELINE_AUTO;
386 case FO_ENUM_ENUM_RESET_SIZE:
387 return PANGO_BASELINE_RESET_SIZE;
388 case FO_ENUM_ENUM_USE_SCRIPT:
389 return PANGO_BASELINE_USE_SCRIPT;
390 case FO_ENUM_ENUM_IDEOGRAPHIC:
391 return PANGO_BASELINE_IDEOGRAPHIC;
392 case FO_ENUM_ENUM_ALPHABETIC:
393 return PANGO_BASELINE_ALPHABETIC;
394 case FO_ENUM_ENUM_HANGING:
395 return PANGO_BASELINE_HANGING;
396 case FO_ENUM_ENUM_MATHEMATICAL:
397 return PANGO_BASELINE_MATHEMATICAL;
398 case FO_ENUM_ENUM_CENTRAL:
399 return PANGO_BASELINE_CENTRAL;
400 case FO_ENUM_ENUM_MIDDLE:
401 return PANGO_BASELINE_MIDDLE;
402 case FO_ENUM_ENUM_TEXT_BEFORE_EDGE:
403 return PANGO_BASELINE_TEXT_BEFORE_EDGE;
404 case FO_ENUM_ENUM_TEXT_AFTER_EDGE:
405 return PANGO_BASELINE_TEXT_AFTER_EDGE;
406 default:
407 return PANGO_BASELINE_INVALID;
408 }
409 }
410
411 static PangoStyle
412 fo_font_style_to_pango_style (gint font_style)
413 {
414 gint pango_font_style = PANGO_STYLE_NORMAL;
415
416 / * Pango doesn't support 'backslant' styles * /
417 if (font_style == FO_ENUM_FONT_STYLE_ITALIC)
418 {
419 pango_font_style = PANGO_STYLE_ITALIC;
420 }
421 else if (font_style == FO_ENUM_FONT_STYLE_OBLIQUE)
422 {
423 pango_font_style = PANGO_STYLE_OBLIQUE;
424 }
425
426 return pango_font_style;
427 }
428 */
429
430 /**
431 * fo_property_dominant_baseline_new_attr_from_context:
432 * @property: #FoProperty from which to create a #PangoAttribute.
433 * @context: #FoContext from which to take additional property values.
434 *
435 * Makes a new #PangoAttribute representing the value of @property.
436 *
437 * Return value: New #PangoAttribute for @property.
438 **/
439 /*
440 PangoAttribute*
441 fo_property_dominant_baseline_new_attr_from_context (FoProperty *property,
442 FoContext *context)
443 {
444 PangoFontDescription *font_desc = NULL;
445 FoEnumEnum dominant_baseline;
446
447 g_return_val_if_fail (FO_IS_PROPERTY_DOMINANT_BASELINE (property), NULL);
448 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
449
450 dominant_baseline =
451 fo_enum_get_value (fo_property_get_value (property));
452
453 if (dominant_baseline != FO_ENUM_ENUM_RESET_SIZE)
454 {
455 PangoBaseline pango_dominant_baseline =
456 fo_property_dominant_baseline_to_pango_baseline (dominant_baseline);
457
458 font_desc = pango_font_description_new ();
459
460 gchar *font_family = fo_string_get_value (fo_property_get_value (fo_context_get_font_family (context)));
461 pango_font_description_set_family (font_desc, font_family);
462 g_free (font_family);
463
464 pango_font_description_set_size (font_desc,
465 fo_length_get_value (fo_property_get_value (fo_context_get_font_size (context))) * PANGO_SCALE);
466 pango_font_description_set_weight (font_desc,
467 fo_integer_get_value (fo_property_get_value (fo_context_get_font_weight (context))));
468 pango_font_description_set_style (font_desc,
469 fo_font_style_to_pango_style (fo_enum_get_value (fo_property_get_value (fo_context_get_font_style (context)))));
470 pango_font_description_set_stretch (font_desc,
471 fo_enum_get_value (fo_property_get_value (fo_context_get_font_stretch (context))));
472 pango_font_description_set_variant (font_desc,
473 fo_enum_get_value (fo_property_get_value (fo_context_get_font_variant (context))));
474
475 PangoAttribute *pango_attr = pango_attr_dominant_baseline_new (pango_dominant_baseline,
476 font_desc);
477 pango_font_description_free (font_desc);
478 return pango_attr;
479 }
480 else
481 {
482 return pango_attr_db_reset_size_new (TRUE);
483 }
484 }
485 */
486