1 /* Fo
2 * fo-property-baseline-shift.c: 'baseline-shift' property
3 *
4 * Copyright (C) 2001 Sun Microsystems
5 * Copyright (C) 2007 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 #include "property/fo-property-text-property.h"
16 #include "property/fo-property-font-size.h"
17 #include "property/fo-property-baseline-shift.h"
18
19 /* baseline-shift */
20 /* Inherited: FALSE */
21 /* Shorthand: FALSE */
22 /* baseline | sub | super | <percentage> | <length> | inherit */
23 /* Initial value: baseline */
24
25 struct _FoPropertyBaselineShift
26 {
27 FoProperty parent_instance;
28 };
29
30 struct _FoPropertyBaselineShiftClass
31 {
32 FoPropertyClass parent_class;
33 };
34
35 static void fo_property_baseline_shift_init (FoPropertyBaselineShift *property_baseline_shift);
36 static void fo_property_baseline_shift_class_init (FoPropertyBaselineShiftClass *klass);
37 static void fo_property_baseline_shift_finalize (GObject *object);
38 static void fo_property_baseline_shift_text_property_init (FoPropertyTextPropertyIface *iface);
39
40 static FoDatatype* fo_property_baseline_shift_resolve_enum (const gchar *token,
41 FoContext *context,
42 GError **error);
43 static FoDatatype* fo_property_baseline_shift_validate (FoDatatype *datatype,
44 FoContext *context,
45 GError **error);
46 static PangoAttribute * fo_property_baseline_shift_new_attr (FoProperty *property);
47
48 static const gchar class_name[] = "baseline-shift";
49 static gpointer parent_class;
50
51 /**
52 * fo_property_baseline_shift_get_type:
53 *
54 * Register the #FoPropertyBaselineShift type if not already registered and
55 * return its #GType value.
56 *
57 * Return value: #GType of #FoPropertyBaselineShift.
58 **/
59 GType
fo_property_baseline_shift_get_type(void)60 fo_property_baseline_shift_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 (FoPropertyBaselineShiftClass),
69 NULL, /* base_init */
70 NULL, /* base_finalize */
71 (GClassInitFunc) fo_property_baseline_shift_class_init,
72 NULL, /* class_finalize */
73 NULL, /* class_data */
74 sizeof (FoPropertyBaselineShift),
75 0, /* n_preallocs */
76 (GInstanceInitFunc) fo_property_baseline_shift_init,
77 NULL /* value_table */
78 };
79
80 static const GInterfaceInfo fo_property_text_property_info =
81 {
82 (GInterfaceInitFunc) fo_property_baseline_shift_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_baseline_shift_init:
101 * @baseline_shift: #FoPropertyBaselineShift object to initialise.
102 *
103 * Implements #GInstanceInitFunc for #FoPropertyBaselineShift.
104 **/
105 void
fo_property_baseline_shift_init(FoPropertyBaselineShift * baseline_shift)106 fo_property_baseline_shift_init (FoPropertyBaselineShift *baseline_shift)
107 {
108 FO_PROPERTY (baseline_shift)->value =
109 g_object_ref (fo_length_get_length_zero ());
110 }
111
112 /**
113 * fo_property_baseline_shift_class_init:
114 * @klass: #FoPropertyBaselineShiftClass object to initialise.
115 *
116 * Implements #GClassInitFunc for #FoPropertyBaselineShiftClass.
117 **/
118 void
fo_property_baseline_shift_class_init(FoPropertyBaselineShiftClass * klass)119 fo_property_baseline_shift_class_init (FoPropertyBaselineShiftClass *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_baseline_shift_finalize;
127
128 property_class->is_inherited = FALSE;
129 property_class->is_shorthand = FALSE;
130 property_class->resolve_enum =
131 fo_property_baseline_shift_resolve_enum;
132 property_class->validate =
133 fo_property_baseline_shift_validate;
134 property_class->get_initial =
135 fo_property_baseline_shift_get_initial;
136 }
137
138 /**
139 * fo_property_baseline_shift_finalize:
140 * @object: #FoPropertyBaselineShift object to finalize.
141 *
142 * Implements #GObjectFinalizeFunc for #FoPropertyBaselineShift.
143 **/
144 void
fo_property_baseline_shift_finalize(GObject * object)145 fo_property_baseline_shift_finalize (GObject *object)
146 {
147 FoPropertyBaselineShift *baseline_shift;
148
149 baseline_shift = FO_PROPERTY_BASELINE_SHIFT (object);
150
151 G_OBJECT_CLASS (parent_class)->finalize (object);
152 }
153
154 /**
155 * fo_property_baseline_shift_text_property_init:
156 * @iface: #FoPropertyTextPropertyIFace structure for this class.
157 *
158 * Initialize #FoPropertyTextPropertyIface interface for this class.
159 **/
160 void
fo_property_baseline_shift_text_property_init(FoPropertyTextPropertyIface * iface)161 fo_property_baseline_shift_text_property_init (FoPropertyTextPropertyIface *iface)
162 {
163 iface->new_attr = fo_property_baseline_shift_new_attr;
164 }
165
166 /**
167 * fo_property_baseline_shift_new:
168 *
169 * Creates a new #FoPropertyBaselineShift initialized to default value.
170 *
171 * Return value: the new #FoPropertyBaselineShift.
172 **/
173 FoProperty*
fo_property_baseline_shift_new(void)174 fo_property_baseline_shift_new (void)
175 {
176 FoProperty* baseline_shift;
177
178 baseline_shift =
179 FO_PROPERTY (g_object_new (fo_property_baseline_shift_get_type (),
180 NULL));
181
182 return baseline_shift;
183 }
184
185 /**
186 * fo_property_baseline_shift_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_baseline_shift_resolve_enum(const gchar * token,FoContext * context,GError ** error)201 fo_property_baseline_shift_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, "baseline") == 0)
210 {
211 return g_object_ref (fo_length_get_length_zero ());
212 }
213 else if (strcmp (token, "sub") == 0)
214 {
215 return g_object_ref (fo_length_get_length_minus_3pt ());
216 }
217 else if (strcmp (token, "super") == 0)
218 {
219 return g_object_ref (fo_length_get_length_3pt ());
220 }
221 else
222 {
223 g_set_error (error,
224 FO_FO_ERROR,
225 FO_FO_ERROR_ENUMERATION_TOKEN,
226 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
227 class_name,
228 token);
229 return NULL;
230 }
231 }
232
233 /**
234 * fo_property_baseline_shift_validate:
235 * @datatype: #FoDatatype to be validated against allowed datatypes and
236 * values for current property.
237 * @context: #FoContext object from which to possibly inherit values.
238 * @error: Information about any error that has occurred.
239 *
240 * Validates @datatype against allowed values. Returns @datatype, a
241 * replacement datatype value, or NULL if validation failed.
242 *
243 * Return value: Valid datatype value or NULL.
244 **/
245 FoDatatype*
fo_property_baseline_shift_validate(FoDatatype * datatype,FoContext * context,GError ** error)246 fo_property_baseline_shift_validate (FoDatatype *datatype,
247 FoContext *context,
248 GError **error)
249 {
250 FoDatatype *new_datatype;
251 GError *tmp_error = NULL;
252 gchar *token;
253
254 g_return_val_if_fail (datatype != NULL, NULL);
255 g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL);
256 g_return_val_if_fail (context != NULL, NULL);
257 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
258 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
259
260 if (FO_IS_ENUM (datatype))
261 {
262 FoEnumEnum value = fo_enum_get_value (datatype);
263
264 if ((value == FO_ENUM_ENUM_BASELINE) ||
265 (value == FO_ENUM_ENUM_SUB) ||
266 (value == FO_ENUM_ENUM_SUPER))
267 {
268 return datatype;
269 }
270 else
271 {
272 gchar *datatype_sprintf = fo_object_sprintf (datatype);
273
274 g_set_error (error,
275 FO_FO_ERROR,
276 FO_FO_ERROR_ENUMERATION_TOKEN,
277 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
278 class_name,
279 datatype_sprintf,
280 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
281
282 g_object_unref (datatype);
283
284 g_free (datatype_sprintf);
285
286 return NULL;
287 }
288 }
289 else if (FO_IS_STRING (datatype))
290 {
291 token = fo_string_get_value (datatype);
292
293 new_datatype =
294 fo_property_baseline_shift_resolve_enum (token, context, &tmp_error);
295
296 g_object_unref (datatype);
297
298 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
299
300 return new_datatype;
301 }
302 else if (FO_IS_NAME (datatype))
303 {
304 token = fo_name_get_value (datatype);
305
306 new_datatype =
307 fo_property_baseline_shift_resolve_enum (token, context, &tmp_error);
308
309 g_object_unref (datatype);
310
311 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
312
313 return new_datatype;
314 }
315 else if (FO_IS_PERCENTAGE (datatype))
316 {
317 return datatype;
318 }
319 else if (FO_IS_LENGTH (datatype))
320 {
321 return datatype;
322 }
323 else
324 {
325 gchar *datatype_sprintf = fo_object_sprintf (datatype);
326
327 g_set_error (error,
328 FO_FO_ERROR,
329 FO_FO_ERROR_DATATYPE,
330 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
331 class_name,
332 datatype_sprintf,
333 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
334
335 g_object_unref (datatype);
336
337 g_free (datatype_sprintf);
338
339 return NULL;
340 }
341 }
342
343 /**
344 * fo_property_baseline_shift_get_initial:
345 *
346 * Get an instance of the property with the correct initial value.
347 *
348 * Return value: An instance of the property.
349 **/
350 FoProperty*
fo_property_baseline_shift_get_initial(void)351 fo_property_baseline_shift_get_initial (void)
352 {
353 static FoProperty *baseline_shift = NULL;
354
355 if (baseline_shift == NULL)
356 {
357 baseline_shift =
358 fo_property_baseline_shift_new ();
359 }
360
361 return baseline_shift;
362 }
363
364 /**
365 * fo_property_baseline_shift_new_attr:
366 * @property: Property from which to create a PangoAttribute
367 *
368 * Makes a new PangoAttribute representing the current property
369 *
370 * Return value: New PangoAttribute
371 **/
372 PangoAttribute*
fo_property_baseline_shift_new_attr(FoProperty * property)373 fo_property_baseline_shift_new_attr (FoProperty *property)
374 {
375 gint pango_baseline_shift;
376
377 g_return_val_if_fail (FO_IS_PROPERTY_BASELINE_SHIFT (property), NULL);
378
379 pango_baseline_shift =
380 (int) (fo_length_get_value (property->value) *
381 PANGO_SCALE);
382
383 return pango_attr_rise_new (pango_baseline_shift);
384 }
385