Implemented stlye slots on AdgFontStyle
[adg.git] / adg / adg-font-style.c
blobc83315bc649d7fa8042414a38ee70c92f5f0c268
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2008, 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 Library 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 * Library 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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 /**
22 * SECTION: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 #include "adg-font-style.h"
31 #include "adg-font-style-private.h"
32 #include "adg-intl.h"
33 #include "adg-util.h"
35 #define PARENT_CLASS ((AdgStyleClass *) adg_font_style_parent_class)
38 enum
40 PROP_0,
41 PROP_FAMILY,
42 PROP_SLANT,
43 PROP_WEIGHT,
44 PROP_SIZE,
45 PROP_ANTIALIAS,
46 PROP_SUBPIXEL_ORDER,
47 PROP_HINT_STYLE,
48 PROP_HINT_METRICS
52 static void get_property (GObject *object,
53 guint prop_id,
54 GValue *value,
55 GParamSpec *pspec);
56 static void set_property (GObject *object,
57 guint prop_id,
58 const GValue *value,
59 GParamSpec *pspec);
61 static GPtrArray * get_pool (void);
62 static void apply (AdgStyle *style,
63 cairo_t *cr);
64 static void set_family (AdgFontStyle *font_style,
65 const gchar *family);
68 G_DEFINE_TYPE (AdgFontStyle, adg_font_style, ADG_TYPE_STYLE)
71 static void
72 adg_font_style_class_init (AdgFontStyleClass *klass)
74 GObjectClass *gobject_class;
75 AdgStyleClass *style_class;
76 GParamSpec *param;
78 gobject_class = (GObjectClass *) klass;
79 style_class = (AdgStyleClass *) klass;
81 g_type_class_add_private (klass, sizeof (AdgFontStylePrivate));
83 gobject_class->get_property = get_property;
84 gobject_class->set_property = set_property;
86 style_class->get_pool = get_pool;
87 style_class->apply = apply;
89 param = g_param_spec_string ("family",
90 P_("Font Family"),
91 P_("The font family name, encoded in UTF-8"),
92 NULL,
93 G_PARAM_READWRITE);
94 g_object_class_install_property (gobject_class, PROP_FAMILY, param);
96 param = g_param_spec_int ("slant",
97 P_("Font Slant"),
98 P_("Variant of a font face based on its slant"),
99 G_MININT, G_MAXINT, CAIRO_FONT_SLANT_NORMAL,
100 G_PARAM_READWRITE);
101 g_object_class_install_property (gobject_class, PROP_SLANT, param);
103 param = g_param_spec_int ("weight",
104 P_("Font Weight"),
105 P_("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.,
114 G_PARAM_READWRITE);
115 g_object_class_install_property (gobject_class, PROP_SIZE, param);
117 param = g_param_spec_int ("antialias",
118 P_("Font Antialiasing Mode"),
119 P_("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"),
126 P_("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
127 G_MININT, G_MAXINT, CAIRO_SUBPIXEL_ORDER_DEFAULT,
128 G_PARAM_READWRITE);
129 g_object_class_install_property (gobject_class, PROP_SUBPIXEL_ORDER, param);
131 param = g_param_spec_int ("hint-style",
132 P_("Type of Hinting"),
133 P_("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
134 G_MININT, G_MAXINT, CAIRO_HINT_STYLE_DEFAULT,
135 G_PARAM_READWRITE);
136 g_object_class_install_property (gobject_class, PROP_HINT_STYLE, param);
138 param = g_param_spec_int ("hint-metrics",
139 P_("Font Metric Hinting"),
140 P_("Whether to hint font metrics, that is align them to integer values in device space"),
141 G_MININT, G_MAXINT, CAIRO_HINT_METRICS_DEFAULT,
142 G_PARAM_READWRITE);
143 g_object_class_install_property (gobject_class, PROP_HINT_METRICS, param);
146 static void
147 adg_font_style_init (AdgFontStyle *font_style)
149 AdgFontStylePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (font_style,
150 ADG_TYPE_FONT_STYLE,
151 AdgFontStylePrivate);
153 priv->family = NULL;
154 priv->slant = CAIRO_FONT_SLANT_NORMAL;
155 priv->weight = CAIRO_FONT_WEIGHT_NORMAL;
156 priv->size = 10.;
157 priv->antialias = CAIRO_ANTIALIAS_DEFAULT;
158 priv->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
159 priv->hint_style = CAIRO_HINT_STYLE_DEFAULT;
160 priv->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
162 font_style->priv = priv;
165 static void
166 get_property (GObject *object,
167 guint prop_id,
168 GValue *value,
169 GParamSpec *pspec)
171 AdgFontStyle *font_style = (AdgFontStyle *) object;
173 switch (prop_id)
175 case PROP_FAMILY:
176 g_value_set_string (value, font_style->priv->family);
177 break;
178 case PROP_SLANT:
179 g_value_set_int (value, font_style->priv->slant);
180 break;
181 case PROP_WEIGHT:
182 g_value_set_int (value, font_style->priv->weight);
183 break;
184 case PROP_SIZE:
185 g_value_set_double (value, font_style->priv->size);
186 break;
187 case PROP_ANTIALIAS:
188 g_value_set_int (value, font_style->priv->antialias);
189 break;
190 case PROP_SUBPIXEL_ORDER:
191 g_value_set_int (value, font_style->priv->subpixel_order);
192 break;
193 case PROP_HINT_STYLE:
194 g_value_set_int (value, font_style->priv->hint_style);
195 break;
196 case PROP_HINT_METRICS:
197 g_value_set_int (value, font_style->priv->hint_metrics);
198 break;
199 default:
200 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
201 break;
205 static void
206 set_property (GObject *object,
207 guint prop_id,
208 const GValue *value,
209 GParamSpec *pspec)
211 AdgFontStyle *font_style = (AdgFontStyle *) object;
213 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,
303 const gchar *family)
305 g_return_if_fail (ADG_IS_FONT_STYLE (font_style));
307 set_family (font_style, family);
308 g_object_notify ((GObject *) font_style, "family");
312 * adg_font_style_get_slant:
313 * @font_style: an #AdgFontStyle object
315 * Gets the slant variant of @font_style.
317 * Return value: the slant variant
319 cairo_font_slant_t
320 adg_font_style_get_slant (AdgFontStyle *font_style)
322 g_return_val_if_fail (ADG_IS_FONT_STYLE (font_style), 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), CAIRO_FONT_WEIGHT_NORMAL);
357 return font_style->priv->weight;
361 * adg_font_style_set_weight:
362 * @font_style: an #AdgFontStyle object
363 * @weight: the new weight
365 * Sets a new weight variant on @font_style.
367 void
368 adg_font_style_set_weight (AdgFontStyle *font_style,
369 cairo_font_weight_t weight)
371 g_return_if_fail (ADG_IS_FONT_STYLE (font_style));
373 font_style->priv->weight = weight;
374 g_object_notify ((GObject *) font_style, "weight");
378 * adg_font_style_get_size:
379 * @font_style: an #AdgFontStyle object
381 * Gets the size (in paper units) of @font_style.
383 * Return value: the size variant
385 gdouble
386 adg_font_style_get_size (AdgFontStyle *font_style)
388 g_return_val_if_fail (ADG_IS_FONT_STYLE (font_style), 0.);
390 return font_style->priv->size;
394 * adg_font_style_set_size:
395 * @font_style: an #AdgFontStyle object
396 * @size: the new size
398 * Sets a new size (in paper units) on @font_style.
400 void
401 adg_font_style_set_size (AdgFontStyle *font_style,
402 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), CAIRO_ANTIALIAS_DEFAULT);
423 return font_style->priv->antialias;
427 * adg_font_style_set_antialias:
428 * @font_style: an #AdgFontStyle object
429 * @antialias: the new antialias mode
431 * Sets a new antialias mode.
433 void
434 adg_font_style_set_antialias (AdgFontStyle *font_style,
435 cairo_antialias_t antialias)
437 g_return_if_fail (ADG_IS_FONT_STYLE (font_style));
439 font_style->priv->antialias = antialias;
440 g_object_notify ((GObject *) font_style, "antialias");
444 * adg_font_style_get_subpixel_order:
445 * @font_style: an #AdgFontStyle object
447 * Gets the subpixel order mode used, that is the order of color elements
448 * within each pixel on the display device when rendering with an
449 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
451 * Return value: the requested subpixel order mode
453 cairo_subpixel_order_t
454 adg_font_style_get_subpixel_order (AdgFontStyle *font_style)
456 g_return_val_if_fail (ADG_IS_FONT_STYLE (font_style), 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), CAIRO_HINT_STYLE_DEFAULT);
492 return font_style->priv->hint_style;
496 * adg_font_style_set_hint_style:
497 * @font_style: an #AdgFontStyle object
498 * @hint_style: the new hint style mode
500 * Sets a new hint style mode.
502 void
503 adg_font_style_set_hint_style (AdgFontStyle *font_style,
504 cairo_hint_style_t hint_style)
506 g_return_if_fail (ADG_IS_FONT_STYLE (font_style));
508 font_style->priv->hint_style = hint_style;
509 g_object_notify ((GObject *) font_style, "hint-style");
513 * adg_font_style_get_hint_metrics:
514 * @font_style: an #AdgFontStyle object
516 * Gets the state on whether to hint font metrics.
518 * Return value: the requested hint metrics state
520 cairo_hint_metrics_t
521 adg_font_style_get_hint_metrics (AdgFontStyle *font_style)
523 g_return_val_if_fail (ADG_IS_FONT_STYLE (font_style), CAIRO_HINT_METRICS_DEFAULT);
525 return font_style->priv->hint_metrics;
529 * adg_font_style_set_hint_metrics:
530 * @font_style: an #AdgFontStyle object
531 * @hint_metrics: the new hint metrics state
533 * Sets a new hint metrics state.
535 void
536 adg_font_style_set_hint_metrics (AdgFontStyle *font_style,
537 cairo_hint_metrics_t hint_metrics)
539 g_return_if_fail (ADG_IS_FONT_STYLE (font_style));
541 font_style->priv->hint_metrics = hint_metrics;
542 g_object_notify ((GObject *) font_style, "hint-metrics");
546 static GPtrArray *
547 get_pool (void)
549 static GPtrArray *pool = NULL;
551 if G_UNLIKELY (pool == NULL)
553 pool = g_ptr_array_sized_new (ADG_FONT_STYLE_LAST);
555 pool->pdata[ADG_FONT_STYLE_TEXT] = g_object_new (ADG_TYPE_FONT_STYLE,
556 "family", "Serif",
557 "size", 14.,
558 NULL);
559 pool->pdata[ADG_FONT_STYLE_QUOTE] = g_object_new (ADG_TYPE_FONT_STYLE,
560 "family", "Sans",
561 "size", 12.,
562 "weight", CAIRO_FONT_WEIGHT_BOLD,
563 NULL);
564 pool->pdata[ADG_FONT_STYLE_TOLERANCE] = g_object_new (ADG_TYPE_FONT_STYLE,
565 "family", "Sans",
566 "size", 8.,
567 NULL);
568 pool->pdata[ADG_FONT_STYLE_NOTE] = g_object_new (ADG_TYPE_FONT_STYLE,
569 "family", "Sans",
570 "size", 12.,
571 NULL);
573 pool->len = ADG_FONT_STYLE_LAST;
576 return pool;
579 static void
580 apply (AdgStyle *style,
581 cairo_t *cr)
583 AdgFontStyle *font_style;
584 cairo_font_options_t *options;
585 cairo_matrix_t matrix;
586 double size;
587 cairo_matrix_t font_matrix;
589 font_style = (AdgFontStyle *) style;
590 cairo_get_matrix (cr, &matrix);
591 size = font_style->priv->size;
593 PARENT_CLASS->apply (style, cr);
595 if (font_style->priv->family)
596 cairo_select_font_face (cr, font_style->priv->family,
597 font_style->priv->slant, font_style->priv->weight);
599 cairo_matrix_init_scale (&font_matrix,
600 size / (matrix.xx - matrix.yx),
601 size / (matrix.yy + matrix.xy));
602 cairo_set_font_matrix (cr, &font_matrix);
604 options = cairo_font_options_create ();
606 cairo_font_options_set_antialias (options, font_style->priv->antialias);
607 cairo_font_options_set_subpixel_order (options, font_style->priv->subpixel_order);
608 cairo_font_options_set_hint_style (options, font_style->priv->hint_style);
609 cairo_font_options_set_hint_metrics (options, font_style->priv->hint_metrics);
611 cairo_set_font_options (cr, options);
612 cairo_font_options_destroy (options);
615 static void
616 set_family (AdgFontStyle *font_style,
617 const gchar *family)
619 g_free (font_style->priv->family);
620 font_style->priv->family = g_strdup (family);