[AdgContainer] Adding child with g_slist_prepend()
[adg.git] / adg / adg-font-style.c
blob17158c7009322423db871a9e2f5c15db3dd3829f
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 /**
22 * SECTION:adg-font-style
23 * @short_description: Font style related stuff
25 * Contains parameters on how to draw texts such as font family, slanting,
26 * weight, hinting and so on.
29 /**
30 * AdgFontStyle:
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
34 **/
37 /**
38 * ADG_SLOT_FONT_STYLE:
40 * Gets the slot id for this style class.
42 * Returns: the requested slot id
43 **/
46 #include "adg-font-style.h"
47 #include "adg-font-style-private.h"
48 #include "adg-context.h"
49 #include "adg-intl.h"
50 #include "adg-util.h"
52 #define PARENT_STYLE_CLASS ((AdgStyleClass *) adg_font_style_parent_class)
55 enum {
56 PROP_0,
57 PROP_FAMILY,
58 PROP_SLANT,
59 PROP_WEIGHT,
60 PROP_SIZE,
61 PROP_ANTIALIAS,
62 PROP_SUBPIXEL_ORDER,
63 PROP_HINT_STYLE,
64 PROP_HINT_METRICS
68 static void get_property (GObject *object,
69 guint prop_id,
70 GValue *value,
71 GParamSpec *pspec);
72 static void set_property (GObject *object,
73 guint prop_id,
74 const GValue *value,
75 GParamSpec *pspec);
76 static GPtrArray * get_pool (void);
77 static void apply (AdgStyle *style,
78 cairo_t *cr);
79 static void set_family (AdgFontStyle *font_style,
80 const gchar *family);
83 G_DEFINE_TYPE(AdgFontStyle, adg_font_style, ADG_TYPE_STYLE)
86 static void
87 adg_font_style_class_init(AdgFontStyleClass *klass)
89 GObjectClass *gobject_class;
90 AdgStyleClass *style_class;
91 GParamSpec *param;
93 gobject_class = (GObjectClass *) klass;
94 style_class = (AdgStyleClass *) klass;
96 g_type_class_add_private(klass, sizeof(AdgFontStylePrivate));
98 gobject_class->get_property = get_property;
99 gobject_class->set_property = set_property;
101 style_class->get_pool = get_pool;
102 style_class->apply = apply;
104 param = g_param_spec_string("family",
105 P_("Font Family"),
107 ("The font family name, encoded in UTF-8"),
108 NULL, G_PARAM_READWRITE);
109 g_object_class_install_property(gobject_class, PROP_FAMILY, param);
111 param = g_param_spec_int("slant",
112 P_("Font Slant"),
114 ("Variant of a font face based on its slant"),
115 G_MININT, G_MAXINT, CAIRO_FONT_SLANT_NORMAL,
116 G_PARAM_READWRITE);
117 g_object_class_install_property(gobject_class, PROP_SLANT, param);
119 param = g_param_spec_int("weight",
120 P_("Font Weight"),
122 ("Variant of a font face based on its weight"),
123 G_MININT, G_MAXINT, CAIRO_FONT_WEIGHT_NORMAL,
124 G_PARAM_READWRITE);
125 g_object_class_install_property(gobject_class, PROP_WEIGHT, param);
127 param = g_param_spec_double("size",
128 P_("Font Size"),
129 P_("Font size in user space units"),
130 0., G_MAXDOUBLE, 10., G_PARAM_READWRITE);
131 g_object_class_install_property(gobject_class, PROP_SIZE, param);
133 param = g_param_spec_int("antialias",
134 P_("Font Antialiasing Mode"),
136 ("Type of antialiasing to do when rendering text"),
137 G_MININT, G_MAXINT, CAIRO_ANTIALIAS_DEFAULT,
138 G_PARAM_READWRITE);
139 g_object_class_install_property(gobject_class, PROP_ANTIALIAS, param);
141 param = g_param_spec_int("subpixel-order",
142 P_("Font Subpixel Order"),
144 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
145 G_MININT, G_MAXINT,
146 CAIRO_SUBPIXEL_ORDER_DEFAULT,
147 G_PARAM_READWRITE);
148 g_object_class_install_property(gobject_class, PROP_SUBPIXEL_ORDER,
149 param);
151 param = g_param_spec_int("hint-style",
152 P_("Type of Hinting"),
154 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
155 G_MININT, G_MAXINT, CAIRO_HINT_STYLE_DEFAULT,
156 G_PARAM_READWRITE);
157 g_object_class_install_property(gobject_class, PROP_HINT_STYLE, param);
159 param = g_param_spec_int("hint-metrics",
160 P_("Font Metric Hinting"),
162 ("Whether to hint font metrics, that is align them to integer values in device space"),
163 G_MININT, G_MAXINT,
164 CAIRO_HINT_METRICS_DEFAULT,
165 G_PARAM_READWRITE);
166 g_object_class_install_property(gobject_class, PROP_HINT_METRICS,
167 param);
170 static void
171 adg_font_style_init(AdgFontStyle *font_style)
173 AdgFontStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(font_style,
174 ADG_TYPE_FONT_STYLE,
175 AdgFontStylePrivate);
177 data->family = NULL;
178 data->slant = CAIRO_FONT_SLANT_NORMAL;
179 data->weight = CAIRO_FONT_WEIGHT_NORMAL;
180 data->size = 10.;
181 data->antialias = CAIRO_ANTIALIAS_DEFAULT;
182 data->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
183 data->hint_style = CAIRO_HINT_STYLE_DEFAULT;
184 data->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
186 font_style->data = data;
189 static void
190 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
192 AdgFontStylePrivate *data = ((AdgFontStyle *) object)->data;
194 switch (prop_id) {
195 case PROP_FAMILY:
196 g_value_set_string(value, data->family);
197 break;
198 case PROP_SLANT:
199 g_value_set_int(value, data->slant);
200 break;
201 case PROP_WEIGHT:
202 g_value_set_int(value, data->weight);
203 break;
204 case PROP_SIZE:
205 g_value_set_double(value, data->size);
206 break;
207 case PROP_ANTIALIAS:
208 g_value_set_int(value, data->antialias);
209 break;
210 case PROP_SUBPIXEL_ORDER:
211 g_value_set_int(value, data->subpixel_order);
212 break;
213 case PROP_HINT_STYLE:
214 g_value_set_int(value, data->hint_style);
215 break;
216 case PROP_HINT_METRICS:
217 g_value_set_int(value, data->hint_metrics);
218 break;
219 default:
220 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
221 break;
225 static void
226 set_property(GObject *object,
227 guint prop_id, const GValue *value, GParamSpec *pspec)
229 AdgFontStyle *font_style;
230 AdgFontStylePrivate *data;
232 font_style = (AdgFontStyle *) object;
233 data = font_style->data;
235 switch (prop_id) {
236 case PROP_FAMILY:
237 set_family(font_style, g_value_get_string(value));
238 break;
239 case PROP_SLANT:
240 data->slant = g_value_get_int(value);
241 break;
242 case PROP_WEIGHT:
243 data->weight = g_value_get_int(value);
244 break;
245 case PROP_SIZE:
246 data->size = g_value_get_double(value);
247 break;
248 case PROP_ANTIALIAS:
249 data->antialias = g_value_get_int(value);
250 break;
251 case PROP_SUBPIXEL_ORDER:
252 data->subpixel_order = g_value_get_int(value);
253 break;
254 case PROP_HINT_STYLE:
255 data->hint_style = g_value_get_int(value);
256 break;
257 case PROP_HINT_METRICS:
258 data->hint_metrics = g_value_get_int(value);
259 break;
260 default:
261 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
262 break;
267 AdgStyleSlot
268 _adg_font_style_get_slot(void)
270 static AdgStyleSlot slot = -1;
272 if (G_UNLIKELY(slot < 0))
273 slot = adg_context_get_slot(ADG_TYPE_FONT_STYLE);
275 return slot;
279 * adg_font_style_new:
281 * Constructs a new font style initialized with default params.
283 * Returns: a new font style
285 AdgStyle *
286 adg_font_style_new(void)
288 return g_object_new(ADG_TYPE_FONT_STYLE, NULL);
292 * adg_font_style_get_family:
293 * @font_style: an #AdgFontStyle object
295 * Gets the family of @font_style. The returned pointer refers to
296 * internally managed text that must not be modified or freed.
298 * Returns: the requested family
300 const gchar *
301 adg_font_style_get_family(AdgFontStyle *font_style)
303 AdgFontStylePrivate *data;
305 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), NULL);
307 data = font_style->data;
309 return data->family;
313 * adg_font_style_set_family:
314 * @font_style: an #AdgFontStyle object
315 * @family: the new family
317 * Sets a new family.
319 void
320 adg_font_style_set_family(AdgFontStyle *font_style, const gchar *family)
322 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
324 set_family(font_style, family);
325 g_object_notify((GObject *) font_style, "family");
329 * adg_font_style_get_slant:
330 * @font_style: an #AdgFontStyle object
332 * Gets the slant variant of @font_style.
334 * Returns: the slant variant
336 cairo_font_slant_t
337 adg_font_style_get_slant(AdgFontStyle *font_style)
339 AdgFontStylePrivate *data;
341 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
342 CAIRO_FONT_SLANT_NORMAL);
344 data = font_style->data;
346 return data->slant;
350 * adg_font_style_set_slant:
351 * @font_style: an #AdgFontStyle object
352 * @slant: the new slant
354 * Sets a new slant variant on @font_style.
356 void
357 adg_font_style_set_slant(AdgFontStyle *font_style,
358 cairo_font_slant_t slant)
360 AdgFontStylePrivate *data;
362 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
364 data = font_style->data;
365 data->slant = slant;
367 g_object_notify((GObject *) font_style, "slant");
371 * adg_font_style_get_weight:
372 * @font_style: an #AdgFontStyle object
374 * Gets the weight variant of @font_style.
376 * Returns: the weight variant
378 cairo_font_weight_t
379 adg_font_style_get_weight(AdgFontStyle *font_style)
381 AdgFontStylePrivate *data;
383 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
384 CAIRO_FONT_WEIGHT_NORMAL);
386 data = font_style->data;
388 return data->weight;
392 * adg_font_style_set_weight:
393 * @font_style: an #AdgFontStyle object
394 * @weight: the new weight
396 * Sets a new weight variant on @font_style.
398 void
399 adg_font_style_set_weight(AdgFontStyle *font_style,
400 cairo_font_weight_t weight)
402 AdgFontStylePrivate *data;
404 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
406 data = font_style->data;
407 data->weight = weight;
409 g_object_notify((GObject *) font_style, "weight");
413 * adg_font_style_get_size:
414 * @font_style: an #AdgFontStyle object
416 * Gets the size (in global space) of @font_style.
418 * Returns: the size variant
420 gdouble
421 adg_font_style_get_size(AdgFontStyle *font_style)
423 AdgFontStylePrivate *data;
425 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), 0.);
427 data = font_style->data;
429 return data->size;
433 * adg_font_style_set_size:
434 * @font_style: an #AdgFontStyle object
435 * @size: the new size
437 * Sets a new size (in global space) on @font_style.
439 void
440 adg_font_style_set_size(AdgFontStyle *font_style, gdouble size)
442 AdgFontStylePrivate *data;
444 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
446 data = font_style->data;
447 data->size = size;
449 g_object_notify((GObject *) font_style, "size");
453 * adg_font_style_get_antialias:
454 * @font_style: an #AdgFontStyle object
456 * Gets the antialias mode used.
458 * Returns: the requested antialias mode
460 cairo_antialias_t
461 adg_font_style_get_antialias(AdgFontStyle *font_style)
463 AdgFontStylePrivate *data;
465 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
466 CAIRO_ANTIALIAS_DEFAULT);
468 data = font_style->data;
470 return data->antialias;
474 * adg_font_style_set_antialias:
475 * @font_style: an #AdgFontStyle object
476 * @antialias: the new antialias mode
478 * Sets a new antialias mode.
480 void
481 adg_font_style_set_antialias(AdgFontStyle *font_style,
482 cairo_antialias_t antialias)
484 AdgFontStylePrivate *data;
486 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
488 data = font_style->data;
489 data->antialias = antialias;
491 g_object_notify((GObject *) font_style, "antialias");
495 * adg_font_style_get_subpixel_order:
496 * @font_style: an #AdgFontStyle object
498 * Gets the subpixel order mode used, that is the order of color elements
499 * within each pixel on the display device when rendering with an
500 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
502 * Returns: the requested subpixel order mode
504 cairo_subpixel_order_t
505 adg_font_style_get_subpixel_order(AdgFontStyle *font_style)
507 AdgFontStylePrivate *data;
509 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
510 CAIRO_SUBPIXEL_ORDER_DEFAULT);
512 data = font_style->data;
514 return data->subpixel_order;
518 * adg_font_style_set_subpixel_order:
519 * @font_style: an #AdgFontStyle object
520 * @subpixel_order: the new subpixel order mode
522 * Sets a new subpixel order mode.
524 void
525 adg_font_style_set_subpixel_order(AdgFontStyle *font_style,
526 cairo_subpixel_order_t subpixel_order)
528 AdgFontStylePrivate *data;
530 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
532 data = font_style->data;
533 data->subpixel_order = subpixel_order;
535 g_object_notify((GObject *) font_style, "subpixel-order");
539 * adg_font_style_get_hint_style:
540 * @font_style: an #AdgFontStyle object
542 * Gets the hint style mode used, that is how to fit outlines
543 * to the pixel grid in order to improve the appearance of the result.
545 * Returns: the requested hint style mode
547 cairo_hint_style_t
548 adg_font_style_get_hint_style(AdgFontStyle *font_style)
550 AdgFontStylePrivate *data;
552 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
553 CAIRO_HINT_STYLE_DEFAULT);
555 data = font_style->data;
557 return data->hint_style;
561 * adg_font_style_set_hint_style:
562 * @font_style: an #AdgFontStyle object
563 * @hint_style: the new hint style mode
565 * Sets a new hint style mode.
567 void
568 adg_font_style_set_hint_style(AdgFontStyle *font_style,
569 cairo_hint_style_t hint_style)
571 AdgFontStylePrivate *data;
573 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
575 data = font_style->data;
576 data->hint_style = hint_style;
578 g_object_notify((GObject *) font_style, "hint-style");
582 * adg_font_style_get_hint_metrics:
583 * @font_style: an #AdgFontStyle object
585 * Gets the state on whether to hint font metrics.
587 * Returns: the requested hint metrics state
589 cairo_hint_metrics_t
590 adg_font_style_get_hint_metrics(AdgFontStyle *font_style)
592 AdgFontStylePrivate *data;
594 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
595 CAIRO_HINT_METRICS_DEFAULT);
597 data = font_style->data;
599 return data->hint_metrics;
603 * adg_font_style_set_hint_metrics:
604 * @font_style: an #AdgFontStyle object
605 * @hint_metrics: the new hint metrics state
607 * Sets a new hint metrics state.
609 void
610 adg_font_style_set_hint_metrics(AdgFontStyle *font_style,
611 cairo_hint_metrics_t hint_metrics)
613 AdgFontStylePrivate *data;
615 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
617 data = font_style->data;
618 data->hint_metrics = hint_metrics;
620 g_object_notify((GObject *) font_style, "hint-metrics");
624 static GPtrArray *
625 get_pool(void)
627 static GPtrArray *pool = NULL;
629 if (G_UNLIKELY(pool == NULL)) {
630 pool = g_ptr_array_sized_new(ADG_FONT_STYLE_LAST);
632 pool->pdata[ADG_FONT_STYLE_TEXT] =
633 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Serif", "size",
634 14., NULL);
635 pool->pdata[ADG_FONT_STYLE_VALUE] =
636 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
637 12., "weight", CAIRO_FONT_WEIGHT_BOLD, NULL);
638 pool->pdata[ADG_FONT_STYLE_TOLERANCE] =
639 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size", 8.,
640 NULL);
641 pool->pdata[ADG_FONT_STYLE_NOTE] =
642 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
643 12., NULL);
645 pool->len = ADG_FONT_STYLE_LAST;
648 return pool;
651 static void
652 apply(AdgStyle *style, cairo_t *cr)
654 AdgFontStyle *font_style;
655 AdgFontStylePrivate *data;
656 cairo_font_options_t *options;
658 font_style = (AdgFontStyle *) style;
659 data = font_style->data;
661 if (PARENT_STYLE_CLASS->apply != NULL)
662 PARENT_STYLE_CLASS->apply(style, cr);
664 if (data->family)
665 cairo_select_font_face(cr, data->family, data->slant, data->weight);
667 cairo_set_font_size(cr, data->size);
669 options = cairo_font_options_create();
671 cairo_font_options_set_antialias(options, data->antialias);
672 cairo_font_options_set_subpixel_order(options, data->subpixel_order);
673 cairo_font_options_set_hint_style(options, data->hint_style);
674 cairo_font_options_set_hint_metrics(options, data->hint_metrics);
675 cairo_set_font_options(cr, options);
677 cairo_font_options_destroy(options);
680 static void
681 set_family(AdgFontStyle *font_style, const gchar *family)
683 AdgFontStylePrivate *data = font_style->data;
685 g_free(data->family);
686 data->family = g_strdup(family);