[AdgPoint] Removed from ADG
[adg.git] / adg / adg-font-style.c
blobcf3c375df47c1eeba6232171f0c2357534ab0755
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 * @title: AdgFontStyle
24 * @short_description: Font style related stuff
26 * Contains parameters on how to draw texts such as font family, slanting,
27 * weight, hinting and so on.
30 /**
31 * AdgFontStyle:
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
35 **/
38 #include "adg-font-style.h"
39 #include "adg-font-style-private.h"
40 #include "adg-context.h"
41 #include "adg-intl.h"
42 #include "adg-util.h"
45 enum {
46 PROP_0,
47 PROP_FAMILY,
48 PROP_SLANT,
49 PROP_WEIGHT,
50 PROP_SIZE,
51 PROP_ANTIALIAS,
52 PROP_SUBPIXEL_ORDER,
53 PROP_HINT_STYLE,
54 PROP_HINT_METRICS
58 static void get_property (GObject *object,
59 guint prop_id,
60 GValue *value,
61 GParamSpec *pspec);
62 static void set_property (GObject *object,
63 guint prop_id,
64 const GValue *value,
65 GParamSpec *pspec);
66 static GPtrArray * get_pool (void);
67 static void apply (AdgStyle *style,
68 cairo_t *cr);
69 static void set_family (AdgFontStyle *font_style,
70 const gchar *family);
73 G_DEFINE_TYPE(AdgFontStyle, adg_font_style, ADG_TYPE_STYLE)
76 static void
77 adg_font_style_class_init(AdgFontStyleClass *klass)
79 GObjectClass *gobject_class;
80 AdgStyleClass *style_class;
81 GParamSpec *param;
83 gobject_class = (GObjectClass *) klass;
84 style_class = (AdgStyleClass *) klass;
86 g_type_class_add_private(klass, sizeof(AdgFontStylePrivate));
88 gobject_class->get_property = get_property;
89 gobject_class->set_property = set_property;
91 style_class->get_pool = get_pool;
92 style_class->apply = apply;
94 param = g_param_spec_string("family",
95 P_("Font Family"),
97 ("The font family name, encoded in UTF-8"),
98 NULL, G_PARAM_READWRITE);
99 g_object_class_install_property(gobject_class, PROP_FAMILY, param);
101 param = g_param_spec_int("slant",
102 P_("Font Slant"),
104 ("Variant of a font face based on its slant"),
105 G_MININT, G_MAXINT, CAIRO_FONT_SLANT_NORMAL,
106 G_PARAM_READWRITE);
107 g_object_class_install_property(gobject_class, PROP_SLANT, param);
109 param = g_param_spec_int("weight",
110 P_("Font Weight"),
112 ("Variant of a font face based on its weight"),
113 G_MININT, G_MAXINT, CAIRO_FONT_WEIGHT_NORMAL,
114 G_PARAM_READWRITE);
115 g_object_class_install_property(gobject_class, PROP_WEIGHT, param);
117 param = g_param_spec_double("size",
118 P_("Font Size"),
119 P_("Font size in user space units"),
120 0., G_MAXDOUBLE, 10., G_PARAM_READWRITE);
121 g_object_class_install_property(gobject_class, PROP_SIZE, param);
123 param = g_param_spec_int("antialias",
124 P_("Font Antialiasing Mode"),
126 ("Type of antialiasing to do when rendering text"),
127 G_MININT, G_MAXINT, CAIRO_ANTIALIAS_DEFAULT,
128 G_PARAM_READWRITE);
129 g_object_class_install_property(gobject_class, PROP_ANTIALIAS, param);
131 param = g_param_spec_int("subpixel-order",
132 P_("Font Subpixel Order"),
134 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
135 G_MININT, G_MAXINT,
136 CAIRO_SUBPIXEL_ORDER_DEFAULT,
137 G_PARAM_READWRITE);
138 g_object_class_install_property(gobject_class, PROP_SUBPIXEL_ORDER,
139 param);
141 param = g_param_spec_int("hint-style",
142 P_("Type of Hinting"),
144 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
145 G_MININT, G_MAXINT, CAIRO_HINT_STYLE_DEFAULT,
146 G_PARAM_READWRITE);
147 g_object_class_install_property(gobject_class, PROP_HINT_STYLE, param);
149 param = g_param_spec_int("hint-metrics",
150 P_("Font Metric Hinting"),
152 ("Whether to hint font metrics, that is align them to integer values in device space"),
153 G_MININT, G_MAXINT,
154 CAIRO_HINT_METRICS_DEFAULT,
155 G_PARAM_READWRITE);
156 g_object_class_install_property(gobject_class, PROP_HINT_METRICS,
157 param);
160 static void
161 adg_font_style_init(AdgFontStyle *font_style)
163 AdgFontStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(font_style,
164 ADG_TYPE_FONT_STYLE,
165 AdgFontStylePrivate);
167 data->family = NULL;
168 data->slant = CAIRO_FONT_SLANT_NORMAL;
169 data->weight = CAIRO_FONT_WEIGHT_NORMAL;
170 data->size = 10.;
171 data->antialias = CAIRO_ANTIALIAS_DEFAULT;
172 data->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
173 data->hint_style = CAIRO_HINT_STYLE_DEFAULT;
174 data->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
176 font_style->data = data;
179 static void
180 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
182 AdgFontStylePrivate *data = ((AdgFontStyle *) object)->data;
184 switch (prop_id) {
185 case PROP_FAMILY:
186 g_value_set_string(value, data->family);
187 break;
188 case PROP_SLANT:
189 g_value_set_int(value, data->slant);
190 break;
191 case PROP_WEIGHT:
192 g_value_set_int(value, data->weight);
193 break;
194 case PROP_SIZE:
195 g_value_set_double(value, data->size);
196 break;
197 case PROP_ANTIALIAS:
198 g_value_set_int(value, data->antialias);
199 break;
200 case PROP_SUBPIXEL_ORDER:
201 g_value_set_int(value, data->subpixel_order);
202 break;
203 case PROP_HINT_STYLE:
204 g_value_set_int(value, data->hint_style);
205 break;
206 case PROP_HINT_METRICS:
207 g_value_set_int(value, data->hint_metrics);
208 break;
209 default:
210 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
211 break;
215 static void
216 set_property(GObject *object,
217 guint prop_id, const GValue *value, GParamSpec *pspec)
219 AdgFontStyle *font_style;
220 AdgFontStylePrivate *data;
222 font_style = (AdgFontStyle *) object;
223 data = font_style->data;
225 switch (prop_id) {
226 case PROP_FAMILY:
227 set_family(font_style, g_value_get_string(value));
228 break;
229 case PROP_SLANT:
230 data->slant = g_value_get_int(value);
231 break;
232 case PROP_WEIGHT:
233 data->weight = g_value_get_int(value);
234 break;
235 case PROP_SIZE:
236 data->size = g_value_get_double(value);
237 break;
238 case PROP_ANTIALIAS:
239 data->antialias = g_value_get_int(value);
240 break;
241 case PROP_SUBPIXEL_ORDER:
242 data->subpixel_order = g_value_get_int(value);
243 break;
244 case PROP_HINT_STYLE:
245 data->hint_style = g_value_get_int(value);
246 break;
247 case PROP_HINT_METRICS:
248 data->hint_metrics = g_value_get_int(value);
249 break;
250 default:
251 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
252 break;
258 * adg_font_style_get_slot:
260 * Gets the slot id for this style class.
262 * Return value: the slot
264 AdgStyleSlot
265 adg_font_style_get_slot(void)
267 static AdgStyleSlot slot = -1;
269 if (G_UNLIKELY(slot < 0))
270 slot = adg_context_get_slot(ADG_TYPE_FONT_STYLE);
272 return slot;
276 * adg_font_style_new:
278 * Constructs a new font style initialized with default params.
280 * Return value: a new font style
282 AdgStyle *
283 adg_font_style_new(void)
285 return g_object_new(ADG_TYPE_FONT_STYLE, NULL);
289 * adg_font_style_get_family:
290 * @font_style: an #AdgFontStyle object
292 * Gets the family of @font_style. The returned pointer refers to
293 * internally managed text that must not be modified or freed.
295 * Return value: the requested family
297 const gchar *
298 adg_font_style_get_family(AdgFontStyle *font_style)
300 AdgFontStylePrivate *data;
302 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), NULL);
304 data = font_style->data;
306 return data->family;
310 * adg_font_style_set_family:
311 * @font_style: an #AdgFontStyle object
312 * @family: the new family
314 * Sets a new family.
316 void
317 adg_font_style_set_family(AdgFontStyle *font_style, const gchar *family)
319 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
321 set_family(font_style, family);
322 g_object_notify((GObject *) font_style, "family");
326 * adg_font_style_get_slant:
327 * @font_style: an #AdgFontStyle object
329 * Gets the slant variant of @font_style.
331 * Return value: the slant variant
333 cairo_font_slant_t
334 adg_font_style_get_slant(AdgFontStyle *font_style)
336 AdgFontStylePrivate *data;
338 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
339 CAIRO_FONT_SLANT_NORMAL);
341 data = font_style->data;
343 return data->slant;
347 * adg_font_style_set_slant:
348 * @font_style: an #AdgFontStyle object
349 * @slant: the new slant
351 * Sets a new slant variant on @font_style.
353 void
354 adg_font_style_set_slant(AdgFontStyle *font_style,
355 cairo_font_slant_t slant)
357 AdgFontStylePrivate *data;
359 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
361 data = font_style->data;
362 data->slant = slant;
364 g_object_notify((GObject *) font_style, "slant");
368 * adg_font_style_get_weight:
369 * @font_style: an #AdgFontStyle object
371 * Gets the weight variant of @font_style.
373 * Return value: the weight variant
375 cairo_font_weight_t
376 adg_font_style_get_weight(AdgFontStyle *font_style)
378 AdgFontStylePrivate *data;
380 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
381 CAIRO_FONT_WEIGHT_NORMAL);
383 data = font_style->data;
385 return data->weight;
389 * adg_font_style_set_weight:
390 * @font_style: an #AdgFontStyle object
391 * @weight: the new weight
393 * Sets a new weight variant on @font_style.
395 void
396 adg_font_style_set_weight(AdgFontStyle *font_style,
397 cairo_font_weight_t weight)
399 AdgFontStylePrivate *data;
401 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
403 data = font_style->data;
404 data->weight = weight;
406 g_object_notify((GObject *) font_style, "weight");
410 * adg_font_style_get_size:
411 * @font_style: an #AdgFontStyle object
413 * Gets the size (in paper units) of @font_style.
415 * Return value: the size variant
417 gdouble
418 adg_font_style_get_size(AdgFontStyle *font_style)
420 AdgFontStylePrivate *data;
422 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style), 0.);
424 data = font_style->data;
426 return data->size;
430 * adg_font_style_set_size:
431 * @font_style: an #AdgFontStyle object
432 * @size: the new size
434 * Sets a new size (in paper units) on @font_style.
436 void
437 adg_font_style_set_size(AdgFontStyle *font_style, gdouble size)
439 AdgFontStylePrivate *data;
441 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
443 data = font_style->data;
444 data->size = size;
446 g_object_notify((GObject *) font_style, "size");
450 * adg_font_style_get_antialias:
451 * @font_style: an #AdgFontStyle object
453 * Gets the antialias mode used.
455 * Return value: the requested antialias mode
457 cairo_antialias_t
458 adg_font_style_get_antialias(AdgFontStyle *font_style)
460 AdgFontStylePrivate *data;
462 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
463 CAIRO_ANTIALIAS_DEFAULT);
465 data = font_style->data;
467 return data->antialias;
471 * adg_font_style_set_antialias:
472 * @font_style: an #AdgFontStyle object
473 * @antialias: the new antialias mode
475 * Sets a new antialias mode.
477 void
478 adg_font_style_set_antialias(AdgFontStyle *font_style,
479 cairo_antialias_t antialias)
481 AdgFontStylePrivate *data;
483 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
485 data = font_style->data;
486 data->antialias = antialias;
488 g_object_notify((GObject *) font_style, "antialias");
492 * adg_font_style_get_subpixel_order:
493 * @font_style: an #AdgFontStyle object
495 * Gets the subpixel order mode used, that is the order of color elements
496 * within each pixel on the display device when rendering with an
497 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
499 * Return value: the requested subpixel order mode
501 cairo_subpixel_order_t
502 adg_font_style_get_subpixel_order(AdgFontStyle *font_style)
504 AdgFontStylePrivate *data;
506 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
507 CAIRO_SUBPIXEL_ORDER_DEFAULT);
509 data = font_style->data;
511 return data->subpixel_order;
515 * adg_font_style_set_subpixel_order:
516 * @font_style: an #AdgFontStyle object
517 * @subpixel_order: the new subpixel order mode
519 * Sets a new subpixel order mode.
521 void
522 adg_font_style_set_subpixel_order(AdgFontStyle *font_style,
523 cairo_subpixel_order_t subpixel_order)
525 AdgFontStylePrivate *data;
527 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
529 data = font_style->data;
530 data->subpixel_order = subpixel_order;
532 g_object_notify((GObject *) font_style, "subpixel-order");
536 * adg_font_style_get_hint_style:
537 * @font_style: an #AdgFontStyle object
539 * Gets the hint style mode used, that is how to fit outlines
540 * to the pixel grid in order to improve the appearance of the result.
542 * Return value: the requested hint style mode
544 cairo_hint_style_t
545 adg_font_style_get_hint_style(AdgFontStyle *font_style)
547 AdgFontStylePrivate *data;
549 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
550 CAIRO_HINT_STYLE_DEFAULT);
552 data = font_style->data;
554 return data->hint_style;
558 * adg_font_style_set_hint_style:
559 * @font_style: an #AdgFontStyle object
560 * @hint_style: the new hint style mode
562 * Sets a new hint style mode.
564 void
565 adg_font_style_set_hint_style(AdgFontStyle *font_style,
566 cairo_hint_style_t hint_style)
568 AdgFontStylePrivate *data;
570 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
572 data = font_style->data;
573 data->hint_style = hint_style;
575 g_object_notify((GObject *) font_style, "hint-style");
579 * adg_font_style_get_hint_metrics:
580 * @font_style: an #AdgFontStyle object
582 * Gets the state on whether to hint font metrics.
584 * Return value: the requested hint metrics state
586 cairo_hint_metrics_t
587 adg_font_style_get_hint_metrics(AdgFontStyle *font_style)
589 AdgFontStylePrivate *data;
591 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style),
592 CAIRO_HINT_METRICS_DEFAULT);
594 data = font_style->data;
596 return data->hint_metrics;
600 * adg_font_style_set_hint_metrics:
601 * @font_style: an #AdgFontStyle object
602 * @hint_metrics: the new hint metrics state
604 * Sets a new hint metrics state.
606 void
607 adg_font_style_set_hint_metrics(AdgFontStyle *font_style,
608 cairo_hint_metrics_t hint_metrics)
610 AdgFontStylePrivate *data;
612 g_return_if_fail(ADG_IS_FONT_STYLE(font_style));
614 data = font_style->data;
615 data->hint_metrics = hint_metrics;
617 g_object_notify((GObject *) font_style, "hint-metrics");
621 static GPtrArray *
622 get_pool(void)
624 static GPtrArray *pool = NULL;
626 if (G_UNLIKELY(pool == NULL)) {
627 pool = g_ptr_array_sized_new(ADG_FONT_STYLE_LAST);
629 pool->pdata[ADG_FONT_STYLE_TEXT] =
630 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Serif", "size",
631 14., NULL);
632 pool->pdata[ADG_FONT_STYLE_QUOTE] =
633 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
634 12., "weight", CAIRO_FONT_WEIGHT_BOLD, NULL);
635 pool->pdata[ADG_FONT_STYLE_TOLERANCE] =
636 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size", 8.,
637 NULL);
638 pool->pdata[ADG_FONT_STYLE_NOTE] =
639 g_object_new(ADG_TYPE_FONT_STYLE, "family", "Sans", "size",
640 12., NULL);
642 pool->len = ADG_FONT_STYLE_LAST;
645 return pool;
648 static void
649 apply(AdgStyle *style, cairo_t *cr)
651 AdgFontStyle *font_style;
652 AdgFontStylePrivate *data;
653 AdgStyleClass *style_class;
654 double size;
655 cairo_font_options_t *options;
656 cairo_matrix_t matrix;
657 cairo_matrix_t font_matrix;
659 font_style = (AdgFontStyle *) style;
660 data = font_style->data;
661 style_class = (AdgStyleClass *) adg_font_style_parent_class;
662 cairo_get_matrix(cr, &matrix);
663 size = data->size;
665 if (style_class->apply != NULL)
666 style_class->apply(style, cr);
668 if (data->family)
669 cairo_select_font_face(cr, data->family,
670 data->slant, data->weight);
672 cairo_matrix_init_scale(&font_matrix,
673 size / (matrix.xx - matrix.yx),
674 size / (matrix.yy + matrix.xy));
675 cairo_set_font_matrix(cr, &font_matrix);
677 options = cairo_font_options_create();
679 cairo_font_options_set_antialias(options, data->antialias);
680 cairo_font_options_set_subpixel_order(options, data->subpixel_order);
681 cairo_font_options_set_hint_style(options, data->hint_style);
682 cairo_font_options_set_hint_metrics(options, data->hint_metrics);
684 cairo_set_font_options(cr, options);
685 cairo_font_options_destroy(options);
688 static void
689 set_family(AdgFontStyle *font_style, const gchar *family)
691 AdgFontStylePrivate *data = font_style->data;
693 g_free(data->family);
694 data->family = g_strdup(family);