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/&num;dominant-baseline">http://www.w3.org/TR/xsl11/&num;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