1 /* Fo
2 * fo-property-reference-orientation.c: 'reference-orientation' 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-font-size.h"
17 #include "property/fo-property-reference-orientation.h"
18
19 /**
20 * SECTION:fo-property-reference-orientation
21 * @short_description: 'reference-orientation' property
22 *
23 * Inherited: TRUE
24 *
25 * Shorthand: FALSE
26 *
27 * Value: 0 | 90 | 180 | 270 | -90 | -180 | -270 | inherit
28 *
29 * Initial value: 0
30 *
31 * Definition: <ulink url="http://www.w3.org/TR/xsl11/#reference-orientation">http://www.w3.org/TR/xsl11/#reference-orientation</ulink>
32 */
33
34 struct _FoPropertyReferenceOrientation
35 {
36 FoProperty parent_instance;
37 };
38
39 struct _FoPropertyReferenceOrientationClass
40 {
41 FoPropertyClass parent_class;
42 };
43
44 static void _init (FoPropertyReferenceOrientation *property_reference_orientation);
45 static void _class_init (FoPropertyReferenceOrientationClass *klass);
46
47 static FoDatatype * _resolve_enum (const gchar *token,
48 FoContext *context,
49 GError **error);
50 static FoDatatype * _validate (FoDatatype *datatype,
51 FoContext *context,
52 GError **error);
53
54 static const gchar class_name[] = "reference-orientation";
55 static gpointer parent_class;
56
57 /**
58 * fo_property_reference_orientation_get_type:
59 *
60 * Register the #FoPropertyReferenceOrientation type if not already registered and
61 * return its #GType value.
62 *
63 * Return value: #GType of #FoPropertyReferenceOrientation.
64 **/
65 GType
fo_property_reference_orientation_get_type(void)66 fo_property_reference_orientation_get_type (void)
67 {
68 static GType object_type = 0;
69
70 if (!object_type)
71 {
72 static const GTypeInfo object_info =
73 {
74 sizeof (FoPropertyReferenceOrientationClass),
75 NULL, /* base_init */
76 NULL, /* base_finalize */
77 (GClassInitFunc) _class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (FoPropertyReferenceOrientation),
81 0, /* n_preallocs */
82 (GInstanceInitFunc) _init,
83 NULL /* value_table */
84 };
85
86 object_type = g_type_register_static (FO_TYPE_PROPERTY,
87 class_name,
88 &object_info, 0);
89 }
90
91 return object_type;
92 }
93
94 /**
95 * _init:
96 * @reference_orientation: #FoPropertyReferenceOrientation object to initialise.
97 *
98 * Implements #GInstanceInitFunc for #FoPropertyReferenceOrientation.
99 **/
100 static void
_init(FoPropertyReferenceOrientation * reference_orientation)101 _init (FoPropertyReferenceOrientation *reference_orientation)
102 {
103 FO_PROPERTY (reference_orientation)->value =
104 g_object_ref (fo_enum_factory_get_enum_by_value (FO_ENUM_ENUM_0));
105 }
106
107 /**
108 * _class_init:
109 * @klass: #FoPropertyReferenceOrientationClass object to initialise.
110 *
111 * Implements #GClassInitFunc for #FoPropertyReferenceOrientationClass.
112 **/
113 static void
_class_init(FoPropertyReferenceOrientationClass * klass)114 _class_init (FoPropertyReferenceOrientationClass *klass)
115 {
116 FoPropertyClass *property_class = FO_PROPERTY_CLASS (klass);
117
118 parent_class = g_type_class_peek_parent (klass);
119
120 property_class->is_inherited = TRUE;
121 property_class->is_shorthand = FALSE;
122 property_class->resolve_enum =
123 _resolve_enum;
124 property_class->validate =
125 _validate;
126 property_class->get_initial =
127 fo_property_reference_orientation_get_initial;
128 }
129
130 /**
131 * fo_property_reference_orientation_new:
132 *
133 * Creates a new #FoPropertyReferenceOrientation initialized to default value.
134 *
135 * Return value: the new #FoPropertyReferenceOrientation.
136 **/
137 FoProperty*
fo_property_reference_orientation_new(void)138 fo_property_reference_orientation_new (void)
139 {
140 FoProperty* reference_orientation;
141
142 reference_orientation =
143 FO_PROPERTY (g_object_new (fo_property_reference_orientation_get_type (),
144 NULL));
145
146 return reference_orientation;
147 }
148
149 /**
150 * _resolve_enum:
151 * @token: Token from the XML attribute value to be evaluated as an
152 * enumeration token.
153 * @context: #FoContext object from which to possibly inherit values.
154 * @error: Information about any error that has occurred.
155 *
156 * Compare @token against the enumeration tokens that are valid for the
157 * current FO property. If @token is valid, returns either an #FoEnum datatype
158 * representing the enumeration token or a different datatype representing
159 * the enumeration token's resolved value. If @token is not valid,
160 * sets @error and returns NULL.
161 *
162 * Return value: Resolved enumeration value or NULL.
163 **/
164 static FoDatatype *
_resolve_enum(const gchar * token,FoContext * context,GError ** error)165 _resolve_enum (const gchar *token,
166 FoContext *context,
167 GError **error)
168 {
169 g_return_val_if_fail (token != NULL, NULL);
170 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
171 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
172
173 if ((strcmp (token, "0") == 0) ||
174 (strcmp (token, "90") == 0) ||
175 (strcmp (token, "180") == 0) ||
176 (strcmp (token, "270") == 0) ||
177 (strcmp (token, "-90") == 0) ||
178 (strcmp (token, "-180") == 0) ||
179 (strcmp (token, "-270") == 0))
180 {
181 return g_object_ref (fo_enum_factory_get_enum_by_nick (token));
182 }
183 else
184 {
185 g_set_error (error,
186 FO_FO_ERROR,
187 FO_FO_ERROR_ENUMERATION_TOKEN,
188 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
189 class_name,
190 token);
191 return NULL;
192 }
193 }
194
195 /**
196 * _validate:
197 * @datatype: #FoDatatype to be validated against allowed datatypes and
198 * values for current property.
199 * @context: #FoContext object from which to possibly inherit values.
200 * @error: Information about any error that has occurred.
201 *
202 * Validates @datatype against allowed values. Returns @datatype, a
203 * replacement datatype value, or NULL if validation failed.
204 *
205 * Return value: Valid datatype value or NULL.
206 **/
207 FoDatatype*
_validate(FoDatatype * datatype,FoContext * context,GError ** error)208 _validate (FoDatatype *datatype,
209 FoContext *context,
210 GError **error)
211 {
212 FoDatatype *new_datatype;
213 GError *tmp_error = NULL;
214 gchar *token;
215
216 g_return_val_if_fail (datatype != NULL, NULL);
217 g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL);
218 g_return_val_if_fail (context != NULL, NULL);
219 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
220 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
221
222 if (FO_IS_ENUM (datatype))
223 {
224 FoEnumEnum value = fo_enum_get_value (datatype);
225
226 if ((value == FO_ENUM_ENUM_0) ||
227 (value == FO_ENUM_ENUM_90) ||
228 (value == FO_ENUM_ENUM_180) ||
229 (value == FO_ENUM_ENUM_270) ||
230 (value == FO_ENUM_ENUM__90) ||
231 (value == FO_ENUM_ENUM__180) ||
232 (value == FO_ENUM_ENUM__270))
233 {
234 return datatype;
235 }
236 else
237 {
238 gchar *datatype_sprintf = fo_object_sprintf (datatype);
239
240 g_set_error (error,
241 FO_FO_ERROR,
242 FO_FO_ERROR_ENUMERATION_TOKEN,
243 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
244 class_name,
245 datatype_sprintf,
246 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
247
248 g_object_unref (datatype);
249
250 g_free (datatype_sprintf);
251
252 return NULL;
253 }
254 }
255 else if (FO_IS_STRING (datatype))
256 {
257 token = fo_string_get_value (datatype);
258
259 new_datatype =
260 _resolve_enum (token, context, &tmp_error);
261
262 g_object_unref (datatype);
263
264 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
265
266 return new_datatype;
267 }
268 else if (FO_IS_NAME (datatype))
269 {
270 token = fo_name_get_value (datatype);
271
272 new_datatype =
273 _resolve_enum (token, context, &tmp_error);
274
275 g_object_unref (datatype);
276
277 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
278
279 return new_datatype;
280 }
281 else if (FO_IS_NUMBER (datatype))
282 {
283 gfloat float_value = fo_number_get_value (datatype);
284
285 if ((float_value == 0) || (float_value == 90) ||
286 (float_value == 180) || (float_value == 270) ||
287 (float_value == -90) || (float_value == -180) ||
288 (float_value == -270))
289 {
290 new_datatype = fo_integer_new_with_value ((int) float_value);
291 g_object_unref (datatype);
292
293 return new_datatype;
294 }
295 else
296 {
297 gchar *datatype_sprintf = fo_object_sprintf (datatype);
298
299 g_set_error (error,
300 FO_FO_ERROR,
301 FO_FO_ERROR_DATATYPE,
302 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
303 class_name,
304 datatype_sprintf,
305 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
306
307 g_object_unref (datatype);
308
309 g_free (datatype_sprintf);
310
311 return NULL;
312 }
313 }
314 else if (FO_IS_INTEGER (datatype))
315 {
316 gint int_value = fo_integer_get_value (datatype);
317
318 if ((int_value == 0) || (int_value == 90) ||
319 (int_value == 180) || (int_value == 270) ||
320 (int_value == -90) || (int_value == -180) ||
321 (int_value == -270))
322 {
323 return datatype;
324 }
325 else
326 {
327 gchar *datatype_sprintf = fo_object_sprintf (datatype);
328
329 g_set_error (error,
330 FO_FO_ERROR,
331 FO_FO_ERROR_DATATYPE,
332 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
333 class_name,
334 datatype_sprintf,
335 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
336
337 g_object_unref (datatype);
338
339 g_free (datatype_sprintf);
340
341 return NULL;
342 }
343 }
344 else
345 {
346 gchar *datatype_sprintf = fo_object_sprintf (datatype);
347
348 g_set_error (error,
349 FO_FO_ERROR,
350 FO_FO_ERROR_DATATYPE,
351 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
352 class_name,
353 datatype_sprintf,
354 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
355
356 g_object_unref (datatype);
357
358 g_free (datatype_sprintf);
359
360 return NULL;
361 }
362 }
363
364 /**
365 * fo_property_reference_orientation_get_initial:
366 *
367 * Get an instance of the property with the correct initial value.
368 *
369 * Return value: An instance of the property.
370 **/
371 FoProperty*
fo_property_reference_orientation_get_initial(void)372 fo_property_reference_orientation_get_initial (void)
373 {
374 static FoProperty *reference_orientation = NULL;
375
376 if (reference_orientation == NULL)
377 {
378 reference_orientation =
379 fo_property_reference_orientation_new ();
380 }
381
382 return reference_orientation;
383 }
384