[AdgFontStyle] Removed PARENT_CLASS define
[adg.git] / adg / adg-font-style.c
blob1c748960076c00f66af354b3f9e0b0a56a907549
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.
20 /**
21 * SECTION:font-style
22 * @title: AdgFontStyle
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 #include "adg-font-style.h"
30 #include "adg-font-style-private.h"
31 #include "adg-context.h"
32 #include "adg-intl.h"
33 #include "adg-util.h"
36 enum {
37 PROP_0,
38 PROP_FAMILY,
39 PROP_SLANT,
40 PROP_WEIGHT,
41 PROP_SIZE,
42 PROP_ANTIALIAS,
43 PROP_SUBPIXEL_ORDER,
44 PROP_HINT_STYLE,
45 PROP_HINT_METRICS
49 static void get_property (GObject *object,
50 guint prop_id,
51 GValue *value,
52 GParamSpec *pspec);
53 static void set_property (GObject *object,
54 guint prop_id,
55 const GValue *value,
56 GParamSpec *pspec);
57 static GPtrArray * get_pool (void);
58 static void apply (AdgStyle *style,
59 cairo_t *cr);
60 static void set_family (AdgFontStyle *font_style,
61 const gchar *family);
64 G_DEFINE_TYPE(AdgFontStyle, adg_font_style, ADG_TYPE_STYLE)
67 static void
68 adg_font_style_class_init(AdgFontStyleClass *klass)
70 GObjectClass *gobject_class;
71 AdgStyleClass *style_class;
72 GParamSpec *param;
74 gobject_class = (GObjectClass *) klass;
75 style_class = (AdgStyleClass *) klass;
77 g_type_class_add_private(klass, sizeof(AdgFontStylePrivate));
79 gobject_class->get_property = get_property;
80 gobject_class->set_property = set_property;
82 style_class->get_pool = get_pool;
83 style_class->apply = apply;
85 param = g_param_spec_string("family",
86 P_("Font Family"),
88 ("The font family name, encoded in UTF-8"),
89 NULL, G_PARAM_READWRITE);
90 g_object_class_install_property(gobject_class, PROP_FAMILY, param);
92 param = g_param_spec_int("slant",
93 P_("Font Slant"),
95 ("Variant of a font face based on its slant"),
96 G_MININT, G_MAXINT, CAIRO_FONT_SLANT_NORMAL,
97 G_PARAM_READWRITE);
98 g_object_class_install_property(gobject_class, PROP_SLANT, param);
100 param = g_param_spec_int("weight",
101 P_("Font Weight"),
103 ("Variant of a font face based on its weight"),
104 G_MININT, G_MAXINT, CAIRO_FONT_WEIGHT_NORMAL,
105 G_PARAM_READWRITE);
106 g_object_class_install_property(gobject_class, PROP_WEIGHT, param);
108 param = g_param_spec_double("size",
109 P_("Font Size"),
110 P_("Font size in user space units"),
111 0., G_MAXDOUBLE, 10., G_PARAM_READWRITE);
112 g_object_class_install_property(gobject_class, PROP_SIZE, param);
114 param = g_param_spec_int("antialias",
115 P_("Font Antialiasing Mode"),
117 ("Type of antialiasing to do when rendering text"),
118 G_MININT, G_MAXINT, CAIRO_ANTIALIAS_DEFAULT,
119 G_PARAM_READWRITE);
120 g_object_class_install_property(gobject_class, PROP_ANTIALIAS, param);
122 param = g_param_spec_int("subpixel-order",
123 P_("Font Subpixel Order"),
125 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
126 G_MININT, G_MAXINT,
127 CAIRO_SUBPIXEL_ORDER_DEFAULT,
128 G_PARAM_READWRITE);
129 g_object_class_install_property(gobject_class, PROP_SUBPIXEL_ORDER,
130 param);
132 param = g_param_spec_int("hint-style",
133 P_("Type of Hinting"),
135 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
136 G_MININT, G_MAXINT, CAIRO_HINT_STYLE_DEFAULT,
137 G_PARAM_READWRITE);
138 g_object_class_install_property(gobject_class, PROP_HINT_STYLE, param);
140 param = g_param_spec_int("hint-metrics",
141 P_("Font Metric Hinting"),
143 ("Whether to hint font metrics, that is align them to integer values in device space"),
144 G_MININT, G_MAXINT,
145 CAIRO_HINT_METRICS_DEFAULT,
146 G_PARAM_READWRITE);
147 g_object_class_install_property(gobject_class, PROP_HINT_METRICS,
148 param);
151 static void
152 adg_font_style_init(AdgFontStyle *font_style)
154 AdgFontStylePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(font_style,
155 ADG_TYPE_FONT_STYLE,
156 AdgFontStylePrivate);
158 priv->family = NULL;
159 priv->slant = CAIRO_FONT_SLANT_NORMAL;
160 priv->weight = CAIRO_FONT_WEIGHT_NORMAL;
161 priv->size = 10.;
162 priv->antialias = CAIRO_ANTIALIAS_DEFAULT;
163 priv->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
164 priv->hint_style = CAIRO_HINT_STYLE_DEFAULT;
165 priv->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
167 font_style->priv = priv;
170 static void
171 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
173 AdgFontStyle *font_style = (AdgFontStyle *) object;
175 switch (prop_id) {
176 case PROP_FAMILY:
177 g_value_set_string(value, font_style->priv->family);
178 break;
179 case PROP_SLANT:
180 g_value_set_int(value, font_style->priv->slant);
181 break;
182 case PROP_WEIGHT:
183 g_value_set_int(value, font_style->priv->weight);
184 break;
185 case PROP_SIZE:
186 g_value_set_double(value, font_style->priv->size);
187 break;
188 case PROP_ANTIALIAS:
189 g_value_set_int(value, font_style->priv->antialias);
190 break;
191 case PROP_SUBPIXEL_ORDER:
192 g_value_set_int(value, font_style->priv->subpixel_order);
193 break;
194 case PROP_HINT_STYLE:
195 g_value_set_int(value, font_style->priv->hint_style);
196 break;
197 case PROP_HINT_METRICS:
198 g_value_set_int(value, font_style->priv->hint_metrics);
199 break;
200 default:
201 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
202 break;
206 static void
207 set_property(GObject *object,
208 guint prop_id, const GValue *value, GParamSpec *pspec)
210 AdgFontStyle *font_style = (AdgFontStyle *) object;
212 switch (prop_id) {
213 case PROP_FAMILY:
214 set_family(font_style, g_value_get_string(value));
215 break;
216 case PROP_SLANT:
217 font_style->priv->slant = g_value_get_int(value);
218 break;
219 case PROP_WEIGHT:
220 font_style->priv->weight = g_value_get_int(value);
221 break;
222 case PROP_SIZE:
223 font_style->priv->size = g_value_get_double(value);
224 break;
225 case PROP_ANTIALIAS:
226 font_style->priv->antialias = g_value_get_int(value);
227 break;
228 case PROP_SUBPIXEL_ORDER:
229 font_style->priv->subpixel_order = g_value_get_int(value);
230 break;
231 case PROP_HINT_STYLE:
232 font_style->priv->hint_style = g_value_get_int(value);
233 break;
234 case PROP_HINT_METRICS:
235 font_style->priv->hint_metrics = g_value_get_int(value);
236 break;
237 default:
238 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
239 break;
245 * adg_font_style_get_slot:
247 * Gets the slot id for this style class.
249 * Return value: the slot
251 AdgStyleSlot
252 adg_font_style_get_slot(void)
254 static AdgStyleSlot slot = -1;
256 if (G_UNLIKELY(slot < 0))
257 slot = adg_context_get_slot(ADG_TYPE_FONT_STYLE);
259 return slot;
263 * adg_font_style_new:
265 * Constructs a new font style initialized with default params.
267 * Return value: a new font style
269 AdgStyle *
270 adg_font_style_new(void)
272 return g_object_new(ADG_TYPE_FONT_STYLE, NULL);
276 * adg_font_style_get_family:
277 * @font_style: an #AdgFontStyle object
279 * Gets the family of @font_style. The returned pointer refers to
280 * internally managed text that must not be modified or freed.
282 * Return value: the requested family
284 const gchar *
285 adg_font_style_get_family(AdgFontStyle *font_style)
287 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), NULL);
289 return font_style->priv->family;
293 * adg_font_style_set_family:
294 * @font_style: an #AdgFontStyle object
295 * @family: the new family
297 * Sets a new family.
299 void
300 adg_font_style_set_family(AdgFontStyle *font_style, const gchar *family)
302 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
304 set_family(font_style, family);
305 g_object_notify((GObject *) font_style, "family");
309 * adg_font_style_get_slant:
310 * @font_style: an #AdgFontStyle object
312 * Gets the slant variant of @font_style.
314 * Return value: the slant variant
316 cairo_font_slant_t
317 adg_font_style_get_slant(AdgFontStyle *font_style)
319 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
320 CAIRO_FONT_SLANT_NORMAL);
322 return font_style->priv->slant;
326 * adg_font_style_set_slant:
327 * @font_style: an #AdgFontStyle object
328 * @slant: the new slant
330 * Sets a new slant variant on @font_style.
332 void
333 adg_font_style_set_slant(AdgFontStyle *font_style,
334 cairo_font_slant_t slant)
336 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
338 font_style->priv->slant = slant;
339 g_object_notify((GObject *) font_style, "slant");
343 * adg_font_style_get_weight:
344 * @font_style: an #AdgFontStyle object
346 * Gets the weight variant of @font_style.
348 * Return value: the weight variant
350 cairo_font_weight_t
351 adg_font_style_get_weight(AdgFontStyle *font_style)
353 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
354 CAIRO_FONT_WEIGHT_NORMAL);
356 return font_style->priv->weight;
360 * adg_font_style_set_weight:
361 * @font_style: an #AdgFontStyle object
362 * @weight: the new weight
364 * Sets a new weight variant on @font_style.
366 void
367 adg_font_style_set_weight(AdgFontStyle *font_style,
368 cairo_font_weight_t weight)
370 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
372 font_style->priv->weight = weight;
373 g_object_notify((GObject *) font_style, "weight");
377 * adg_font_style_get_size:
378 * @font_style: an #AdgFontStyle object
380 * Gets the size (in paper units) of @font_style.
382 * Return value: the size variant
384 gdouble
385 adg_font_style_get_size(AdgFontStyle *font_style)
387 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), 0.);
389 return font_style->priv->size;
393 * adg_font_style_set_size:
394 * @font_style: an #AdgFontStyle object
395 * @size: the new size
397 * Sets a new size (in paper units) on @font_style.
399 void
400 adg_font_style_set_size(AdgFontStyle *font_style, gdouble size)
402 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
404 font_style->priv->size = size;
405 g_object_notify((GObject *) font_style, "size");
409 * adg_font_style_get_antialias:
410 * @font_style: an #AdgFontStyle object
412 * Gets the antialias mode used.
414 * Return value: the requested antialias mode
416 cairo_antialias_t
417 adg_font_style_get_antialias(AdgFontStyle *font_style)
419 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
420 CAIRO_ANTIALIAS_DEFAULT);
422 return font_style->priv->antialias;
426 * adg_font_style_set_antialias:
427 * @font_style: an #AdgFontStyle object
428 * @antialias: the new antialias mode
430 * Sets a new antialias mode.
432 void
433 adg_font_style_set_antialias(AdgFontStyle *font_style,
434 cairo_antialias_t antialias)
436 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
438 font_style->priv->antialias = antialias;
439 g_object_notify((GObject *) font_style, "antialias");
443 * adg_font_style_get_subpixel_order:
444 * @font_style: an #AdgFontStyle object
446 * Gets the subpixel order mode used, that is the order of color elements
447 * within each pixel on the display device when rendering with an
448 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
450 * Return value: the requested subpixel order mode
452 cairo_subpixel_order_t
453 adg_font_style_get_subpixel_order(AdgFontStyle *font_style)
455 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
456 CAIRO_SUBPIXEL_ORDER_DEFAULT);
458 return font_style->priv->subpixel_order;
462 * adg_font_style_set_subpixel_order:
463 * @font_style: an #AdgFontStyle object
464 * @subpixel_order: the new subpixel order mode
466 * Sets a new subpixel order mode.
468 void
469 adg_font_style_set_subpixel_order(AdgFontStyle *font_style,
470 cairo_subpixel_order_t subpixel_order)
472 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
474 font_style->priv->subpixel_order = subpixel_order;
475 g_object_notify((GObject *) font_style, "subpixel-order");
479 * adg_font_style_get_hint_style:
480 * @font_style: an #AdgFontStyle object
482 * Gets the hint style mode used, that is how to fit outlines
483 * to the pixel grid in order to improve the appearance of the result.
485 * Return value: the requested hint style mode
487 cairo_hint_style_t
488 adg_font_style_get_hint_style(AdgFontStyle *font_style)
490 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
491 CAIRO_HINT_STYLE_DEFAULT);
493 return font_style->priv->hint_style;
497 * adg_font_style_set_hint_style:
498 * @font_style: an #AdgFontStyle object
499 * @hint_style: the new hint style mode
501 * Sets a new hint style mode.
503 void
504 adg_font_style_set_hint_style(AdgFontStyle *font_style,
505 cairo_hint_style_t hint_style)
507 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
509 font_style->priv->hint_style = hint_style;
510 g_object_notify((GObject *) font_style, "hint-style");
514 * adg_font_style_get_hint_metrics:
515 * @font_style: an #AdgFontStyle object
517 * Gets the state on whether to hint font metrics.
519 * Return value: the requested hint metrics state
521 cairo_hint_metrics_t
522 adg_font_style_get_hint_metrics(AdgFontStyle *font_style)
524 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
525 CAIRO_HINT_METRICS_DEFAULT);
527 return font_style->priv->hint_metrics;
531 * adg_font_style_set_hint_metrics:
532 * @font_style: an #AdgFontStyle object
533 * @hint_metrics: the new hint metrics state
535 * Sets a new hint metrics state.
537 void
538 adg_font_style_set_hint_metrics(AdgFontStyle *font_style,
539 cairo_hint_metrics_t hint_metrics)
541 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
543 font_style->priv->hint_metrics = hint_metrics;
544 g_object_notify((GObject *) font_style, "hint-metrics");
548 static GPtrArray *
549 get_pool(void)
551 static GPtrArray *pool = NULL;
553 if (G_UNLIKELY(pool == NULL)) {
554 pool = g_ptr_array_sized_new(ADG_FONT_STYLE_LAST);
556 pool->pdata[ADG_FONT_STYLE_TEXT] =
557 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Serif", "size",
558 14., NULL);
559 pool->pdata[ADG_FONT_STYLE_QUOTE] =
560 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
561 12., "weight", CAIRO_FONT_WEIGHT_BOLD, NULL);
562 pool->pdata[ADG_FONT_STYLE_TOLERANCE] =
563 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size", 8.,
564 NULL);
565 pool->pdata[ADG_FONT_STYLE_NOTE] =
566 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
567 12., NULL);
569 pool->len = ADG_FONT_STYLE_LAST;
572 return pool;
575 static void
576 apply(AdgStyle *style, cairo_t *cr)
578 AdgFontStyle *font_style;
579 AdgStyleClass *style_class;
580 double size;
581 cairo_font_options_t *options;
582 cairo_matrix_t matrix;
583 cairo_matrix_t font_matrix;
585 font_style = (AdgFontStyle *) style;
586 style_class = (AdgStyleClass *) adg_font_style_parent_class;
587 cairo_get_matrix(cr, &matrix);
588 size = font_style->priv->size;
590 if (style_class->apply != NULL)
591 style_class->apply(style, cr);
593 if (font_style->priv->family)
594 cairo_select_font_face(cr, font_style->priv->family,
595 font_style->priv->slant,
596 font_style->priv->weight);
598 cairo_matrix_init_scale(&font_matrix,
599 size / (matrix.xx - matrix.yx),
600 size / (matrix.yy + matrix.xy));
601 cairo_set_font_matrix(cr, &font_matrix);
603 options = cairo_font_options_create();
605 cairo_font_options_set_antialias(options, font_style->priv->antialias);
606 cairo_font_options_set_subpixel_order(options,
607 font_style->priv->
608 subpixel_order);
609 cairo_font_options_set_hint_style(options,
610 font_style->priv->hint_style);
611 cairo_font_options_set_hint_metrics(options,
612 font_style->priv->hint_metrics);
614 cairo_set_font_options(cr, options);
615 cairo_font_options_destroy(options);
618 static void
619 set_family(AdgFontStyle *font_style, const gchar *family)
621 g_free(font_style->priv->family);
622 font_style->priv->family = g_strdup(family);