[AdgADim] Removed PARENT_CLASS define
[adg.git] / adg / adg-font-style.c
blob1ee36d3241333be96ca0a699be8e8c0ade19767f
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"
35 #define PARENT_CLASS ((AdgStyleClass *) adg_font_style_parent_class)
38 enum {
39 PROP_0,
40 PROP_FAMILY,
41 PROP_SLANT,
42 PROP_WEIGHT,
43 PROP_SIZE,
44 PROP_ANTIALIAS,
45 PROP_SUBPIXEL_ORDER,
46 PROP_HINT_STYLE,
47 PROP_HINT_METRICS
51 static void get_property (GObject *object,
52 guint prop_id,
53 GValue *value,
54 GParamSpec *pspec);
55 static void set_property (GObject *object,
56 guint prop_id,
57 const GValue *value,
58 GParamSpec *pspec);
59 static GPtrArray * get_pool (void);
60 static void apply (AdgStyle *style,
61 cairo_t *cr);
62 static void set_family (AdgFontStyle *font_style,
63 const gchar *family);
66 G_DEFINE_TYPE(AdgFontStyle, adg_font_style, ADG_TYPE_STYLE)
69 static void
70 adg_font_style_class_init(AdgFontStyleClass *klass)
72 GObjectClass *gobject_class;
73 AdgStyleClass *style_class;
74 GParamSpec *param;
76 gobject_class = (GObjectClass *) klass;
77 style_class = (AdgStyleClass *) klass;
79 g_type_class_add_private(klass, sizeof(AdgFontStylePrivate));
81 gobject_class->get_property = get_property;
82 gobject_class->set_property = set_property;
84 style_class->get_pool = get_pool;
85 style_class->apply = apply;
87 param = g_param_spec_string("family",
88 P_("Font Family"),
90 ("The font family name, encoded in UTF-8"),
91 NULL, G_PARAM_READWRITE);
92 g_object_class_install_property(gobject_class, PROP_FAMILY, param);
94 param = g_param_spec_int("slant",
95 P_("Font Slant"),
97 ("Variant of a font face based on its slant"),
98 G_MININT, G_MAXINT, CAIRO_FONT_SLANT_NORMAL,
99 G_PARAM_READWRITE);
100 g_object_class_install_property(gobject_class, PROP_SLANT, param);
102 param = g_param_spec_int("weight",
103 P_("Font Weight"),
105 ("Variant of a font face based on its weight"),
106 G_MININT, G_MAXINT, CAIRO_FONT_WEIGHT_NORMAL,
107 G_PARAM_READWRITE);
108 g_object_class_install_property(gobject_class, PROP_WEIGHT, param);
110 param = g_param_spec_double("size",
111 P_("Font Size"),
112 P_("Font size in user space units"),
113 0., G_MAXDOUBLE, 10., G_PARAM_READWRITE);
114 g_object_class_install_property(gobject_class, PROP_SIZE, param);
116 param = g_param_spec_int("antialias",
117 P_("Font Antialiasing Mode"),
119 ("Type of antialiasing to do when rendering text"),
120 G_MININT, G_MAXINT, CAIRO_ANTIALIAS_DEFAULT,
121 G_PARAM_READWRITE);
122 g_object_class_install_property(gobject_class, PROP_ANTIALIAS, param);
124 param = g_param_spec_int("subpixel-order",
125 P_("Font Subpixel Order"),
127 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
128 G_MININT, G_MAXINT,
129 CAIRO_SUBPIXEL_ORDER_DEFAULT,
130 G_PARAM_READWRITE);
131 g_object_class_install_property(gobject_class, PROP_SUBPIXEL_ORDER,
132 param);
134 param = g_param_spec_int("hint-style",
135 P_("Type of Hinting"),
137 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
138 G_MININT, G_MAXINT, CAIRO_HINT_STYLE_DEFAULT,
139 G_PARAM_READWRITE);
140 g_object_class_install_property(gobject_class, PROP_HINT_STYLE, param);
142 param = g_param_spec_int("hint-metrics",
143 P_("Font Metric Hinting"),
145 ("Whether to hint font metrics, that is align them to integer values in device space"),
146 G_MININT, G_MAXINT,
147 CAIRO_HINT_METRICS_DEFAULT,
148 G_PARAM_READWRITE);
149 g_object_class_install_property(gobject_class, PROP_HINT_METRICS,
150 param);
153 static void
154 adg_font_style_init(AdgFontStyle *font_style)
156 AdgFontStylePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(font_style,
157 ADG_TYPE_FONT_STYLE,
158 AdgFontStylePrivate);
160 priv->family = NULL;
161 priv->slant = CAIRO_FONT_SLANT_NORMAL;
162 priv->weight = CAIRO_FONT_WEIGHT_NORMAL;
163 priv->size = 10.;
164 priv->antialias = CAIRO_ANTIALIAS_DEFAULT;
165 priv->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
166 priv->hint_style = CAIRO_HINT_STYLE_DEFAULT;
167 priv->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
169 font_style->priv = priv;
172 static void
173 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
175 AdgFontStyle *font_style = (AdgFontStyle *) object;
177 switch (prop_id) {
178 case PROP_FAMILY:
179 g_value_set_string(value, font_style->priv->family);
180 break;
181 case PROP_SLANT:
182 g_value_set_int(value, font_style->priv->slant);
183 break;
184 case PROP_WEIGHT:
185 g_value_set_int(value, font_style->priv->weight);
186 break;
187 case PROP_SIZE:
188 g_value_set_double(value, font_style->priv->size);
189 break;
190 case PROP_ANTIALIAS:
191 g_value_set_int(value, font_style->priv->antialias);
192 break;
193 case PROP_SUBPIXEL_ORDER:
194 g_value_set_int(value, font_style->priv->subpixel_order);
195 break;
196 case PROP_HINT_STYLE:
197 g_value_set_int(value, font_style->priv->hint_style);
198 break;
199 case PROP_HINT_METRICS:
200 g_value_set_int(value, font_style->priv->hint_metrics);
201 break;
202 default:
203 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
204 break;
208 static void
209 set_property(GObject *object,
210 guint prop_id, const GValue *value, GParamSpec *pspec)
212 AdgFontStyle *font_style = (AdgFontStyle *) object;
214 switch (prop_id) {
215 case PROP_FAMILY:
216 set_family(font_style, g_value_get_string(value));
217 break;
218 case PROP_SLANT:
219 font_style->priv->slant = g_value_get_int(value);
220 break;
221 case PROP_WEIGHT:
222 font_style->priv->weight = g_value_get_int(value);
223 break;
224 case PROP_SIZE:
225 font_style->priv->size = g_value_get_double(value);
226 break;
227 case PROP_ANTIALIAS:
228 font_style->priv->antialias = g_value_get_int(value);
229 break;
230 case PROP_SUBPIXEL_ORDER:
231 font_style->priv->subpixel_order = g_value_get_int(value);
232 break;
233 case PROP_HINT_STYLE:
234 font_style->priv->hint_style = g_value_get_int(value);
235 break;
236 case PROP_HINT_METRICS:
237 font_style->priv->hint_metrics = g_value_get_int(value);
238 break;
239 default:
240 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
241 break;
247 * adg_font_style_get_slot:
249 * Gets the slot id for this style class.
251 * Return value: the slot
253 AdgStyleSlot
254 adg_font_style_get_slot(void)
256 static AdgStyleSlot slot = -1;
258 if (G_UNLIKELY(slot < 0))
259 slot = adg_context_get_slot(ADG_TYPE_FONT_STYLE);
261 return slot;
265 * adg_font_style_new:
267 * Constructs a new font style initialized with default params.
269 * Return value: a new font style
271 AdgStyle *
272 adg_font_style_new(void)
274 return g_object_new(ADG_TYPE_FONT_STYLE, NULL);
278 * adg_font_style_get_family:
279 * @font_style: an #AdgFontStyle object
281 * Gets the family of @font_style. The returned pointer refers to
282 * internally managed text that must not be modified or freed.
284 * Return value: the requested family
286 const gchar *
287 adg_font_style_get_family(AdgFontStyle *font_style)
289 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), NULL);
291 return font_style->priv->family;
295 * adg_font_style_set_family:
296 * @font_style: an #AdgFontStyle object
297 * @family: the new family
299 * Sets a new family.
301 void
302 adg_font_style_set_family(AdgFontStyle *font_style, const gchar *family)
304 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
306 set_family(font_style, family);
307 g_object_notify((GObject *) font_style, "family");
311 * adg_font_style_get_slant:
312 * @font_style: an #AdgFontStyle object
314 * Gets the slant variant of @font_style.
316 * Return value: the slant variant
318 cairo_font_slant_t
319 adg_font_style_get_slant(AdgFontStyle *font_style)
321 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
322 CAIRO_FONT_SLANT_NORMAL);
324 return font_style->priv->slant;
328 * adg_font_style_set_slant:
329 * @font_style: an #AdgFontStyle object
330 * @slant: the new slant
332 * Sets a new slant variant on @font_style.
334 void
335 adg_font_style_set_slant(AdgFontStyle *font_style,
336 cairo_font_slant_t slant)
338 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
340 font_style->priv->slant = slant;
341 g_object_notify((GObject *) font_style, "slant");
345 * adg_font_style_get_weight:
346 * @font_style: an #AdgFontStyle object
348 * Gets the weight variant of @font_style.
350 * Return value: the weight variant
352 cairo_font_weight_t
353 adg_font_style_get_weight(AdgFontStyle *font_style)
355 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
356 CAIRO_FONT_WEIGHT_NORMAL);
358 return font_style->priv->weight;
362 * adg_font_style_set_weight:
363 * @font_style: an #AdgFontStyle object
364 * @weight: the new weight
366 * Sets a new weight variant on @font_style.
368 void
369 adg_font_style_set_weight(AdgFontStyle *font_style,
370 cairo_font_weight_t weight)
372 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
374 font_style->priv->weight = weight;
375 g_object_notify((GObject *) font_style, "weight");
379 * adg_font_style_get_size:
380 * @font_style: an #AdgFontStyle object
382 * Gets the size (in paper units) of @font_style.
384 * Return value: the size variant
386 gdouble
387 adg_font_style_get_size(AdgFontStyle *font_style)
389 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), 0.);
391 return font_style->priv->size;
395 * adg_font_style_set_size:
396 * @font_style: an #AdgFontStyle object
397 * @size: the new size
399 * Sets a new size (in paper units) on @font_style.
401 void
402 adg_font_style_set_size(AdgFontStyle *font_style, gdouble size)
404 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
406 font_style->priv->size = size;
407 g_object_notify((GObject *) font_style, "size");
411 * adg_font_style_get_antialias:
412 * @font_style: an #AdgFontStyle object
414 * Gets the antialias mode used.
416 * Return value: the requested antialias mode
418 cairo_antialias_t
419 adg_font_style_get_antialias(AdgFontStyle *font_style)
421 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
422 CAIRO_ANTIALIAS_DEFAULT);
424 return font_style->priv->antialias;
428 * adg_font_style_set_antialias:
429 * @font_style: an #AdgFontStyle object
430 * @antialias: the new antialias mode
432 * Sets a new antialias mode.
434 void
435 adg_font_style_set_antialias(AdgFontStyle *font_style,
436 cairo_antialias_t antialias)
438 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
440 font_style->priv->antialias = antialias;
441 g_object_notify((GObject *) font_style, "antialias");
445 * adg_font_style_get_subpixel_order:
446 * @font_style: an #AdgFontStyle object
448 * Gets the subpixel order mode used, that is the order of color elements
449 * within each pixel on the display device when rendering with an
450 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
452 * Return value: the requested subpixel order mode
454 cairo_subpixel_order_t
455 adg_font_style_get_subpixel_order(AdgFontStyle *font_style)
457 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
458 CAIRO_SUBPIXEL_ORDER_DEFAULT);
460 return font_style->priv->subpixel_order;
464 * adg_font_style_set_subpixel_order:
465 * @font_style: an #AdgFontStyle object
466 * @subpixel_order: the new subpixel order mode
468 * Sets a new subpixel order mode.
470 void
471 adg_font_style_set_subpixel_order(AdgFontStyle *font_style,
472 cairo_subpixel_order_t subpixel_order)
474 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
476 font_style->priv->subpixel_order = subpixel_order;
477 g_object_notify((GObject *) font_style, "subpixel-order");
481 * adg_font_style_get_hint_style:
482 * @font_style: an #AdgFontStyle object
484 * Gets the hint style mode used, that is how to fit outlines
485 * to the pixel grid in order to improve the appearance of the result.
487 * Return value: the requested hint style mode
489 cairo_hint_style_t
490 adg_font_style_get_hint_style(AdgFontStyle *font_style)
492 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
493 CAIRO_HINT_STYLE_DEFAULT);
495 return font_style->priv->hint_style;
499 * adg_font_style_set_hint_style:
500 * @font_style: an #AdgFontStyle object
501 * @hint_style: the new hint style mode
503 * Sets a new hint style mode.
505 void
506 adg_font_style_set_hint_style(AdgFontStyle *font_style,
507 cairo_hint_style_t hint_style)
509 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
511 font_style->priv->hint_style = hint_style;
512 g_object_notify((GObject *) font_style, "hint-style");
516 * adg_font_style_get_hint_metrics:
517 * @font_style: an #AdgFontStyle object
519 * Gets the state on whether to hint font metrics.
521 * Return value: the requested hint metrics state
523 cairo_hint_metrics_t
524 adg_font_style_get_hint_metrics(AdgFontStyle *font_style)
526 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
527 CAIRO_HINT_METRICS_DEFAULT);
529 return font_style->priv->hint_metrics;
533 * adg_font_style_set_hint_metrics:
534 * @font_style: an #AdgFontStyle object
535 * @hint_metrics: the new hint metrics state
537 * Sets a new hint metrics state.
539 void
540 adg_font_style_set_hint_metrics(AdgFontStyle *font_style,
541 cairo_hint_metrics_t hint_metrics)
543 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
545 font_style->priv->hint_metrics = hint_metrics;
546 g_object_notify((GObject *) font_style, "hint-metrics");
550 static GPtrArray *
551 get_pool(void)
553 static GPtrArray *pool = NULL;
555 if (G_UNLIKELY(pool == NULL)) {
556 pool = g_ptr_array_sized_new(ADG_FONT_STYLE_LAST);
558 pool->pdata[ADG_FONT_STYLE_TEXT] =
559 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Serif", "size",
560 14., NULL);
561 pool->pdata[ADG_FONT_STYLE_QUOTE] =
562 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
563 12., "weight", CAIRO_FONT_WEIGHT_BOLD, NULL);
564 pool->pdata[ADG_FONT_STYLE_TOLERANCE] =
565 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size", 8.,
566 NULL);
567 pool->pdata[ADG_FONT_STYLE_NOTE] =
568 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
569 12., NULL);
571 pool->len = ADG_FONT_STYLE_LAST;
574 return pool;
577 static void
578 apply(AdgStyle *style, cairo_t *cr)
580 AdgFontStyle *font_style;
581 cairo_font_options_t *options;
582 cairo_matrix_t matrix;
583 double size;
584 cairo_matrix_t font_matrix;
586 font_style = (AdgFontStyle *) style;
587 cairo_get_matrix(cr, &matrix);
588 size = font_style->priv->size;
590 PARENT_CLASS->apply(style, cr);
592 if (font_style->priv->family)
593 cairo_select_font_face(cr, font_style->priv->family,
594 font_style->priv->slant,
595 font_style->priv->weight);
597 cairo_matrix_init_scale(&font_matrix,
598 size / (matrix.xx - matrix.yx),
599 size / (matrix.yy + matrix.xy));
600 cairo_set_font_matrix(cr, &font_matrix);
602 options = cairo_font_options_create();
604 cairo_font_options_set_antialias(options, font_style->priv->antialias);
605 cairo_font_options_set_subpixel_order(options,
606 font_style->priv->
607 subpixel_order);
608 cairo_font_options_set_hint_style(options,
609 font_style->priv->hint_style);
610 cairo_font_options_set_hint_metrics(options,
611 font_style->priv->hint_metrics);
613 cairo_set_font_options(cr, options);
614 cairo_font_options_destroy(options);
617 static void
618 set_family(AdgFontStyle *font_style, const gchar *family)
620 g_free(font_style->priv->family);
621 font_style->priv->family = g_strdup(family);