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.
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"
49 static void get_property (GObject
*object
,
53 static void set_property (GObject
*object
,
57 static GPtrArray
* get_pool (void);
58 static void apply (AdgStyle
*style
,
60 static void set_family (AdgFontStyle
*font_style
,
64 G_DEFINE_TYPE(AdgFontStyle
, adg_font_style
, ADG_TYPE_STYLE
)
68 adg_font_style_class_init(AdgFontStyleClass
*klass
)
70 GObjectClass
*gobject_class
;
71 AdgStyleClass
*style_class
;
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",
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",
95 ("Variant of a font face based on its slant"),
96 G_MININT
, G_MAXINT
, CAIRO_FONT_SLANT_NORMAL
,
98 g_object_class_install_property(gobject_class
, PROP_SLANT
, param
);
100 param
= g_param_spec_int("weight",
103 ("Variant of a font face based on its weight"),
104 G_MININT
, G_MAXINT
, CAIRO_FONT_WEIGHT_NORMAL
,
106 g_object_class_install_property(gobject_class
, PROP_WEIGHT
, param
);
108 param
= g_param_spec_double("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
,
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"),
127 CAIRO_SUBPIXEL_ORDER_DEFAULT
,
129 g_object_class_install_property(gobject_class
, PROP_SUBPIXEL_ORDER
,
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
,
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"),
145 CAIRO_HINT_METRICS_DEFAULT
,
147 g_object_class_install_property(gobject_class
, PROP_HINT_METRICS
,
152 adg_font_style_init(AdgFontStyle
*font_style
)
154 AdgFontStylePrivate
*priv
= G_TYPE_INSTANCE_GET_PRIVATE(font_style
,
156 AdgFontStylePrivate
);
159 priv
->slant
= CAIRO_FONT_SLANT_NORMAL
;
160 priv
->weight
= CAIRO_FONT_WEIGHT_NORMAL
;
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
;
171 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
173 AdgFontStyle
*font_style
= (AdgFontStyle
*) object
;
177 g_value_set_string(value
, font_style
->priv
->family
);
180 g_value_set_int(value
, font_style
->priv
->slant
);
183 g_value_set_int(value
, font_style
->priv
->weight
);
186 g_value_set_double(value
, font_style
->priv
->size
);
189 g_value_set_int(value
, font_style
->priv
->antialias
);
191 case PROP_SUBPIXEL_ORDER
:
192 g_value_set_int(value
, font_style
->priv
->subpixel_order
);
194 case PROP_HINT_STYLE
:
195 g_value_set_int(value
, font_style
->priv
->hint_style
);
197 case PROP_HINT_METRICS
:
198 g_value_set_int(value
, font_style
->priv
->hint_metrics
);
201 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
207 set_property(GObject
*object
,
208 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
210 AdgFontStyle
*font_style
= (AdgFontStyle
*) object
;
214 set_family(font_style
, g_value_get_string(value
));
217 font_style
->priv
->slant
= g_value_get_int(value
);
220 font_style
->priv
->weight
= g_value_get_int(value
);
223 font_style
->priv
->size
= g_value_get_double(value
);
226 font_style
->priv
->antialias
= g_value_get_int(value
);
228 case PROP_SUBPIXEL_ORDER
:
229 font_style
->priv
->subpixel_order
= g_value_get_int(value
);
231 case PROP_HINT_STYLE
:
232 font_style
->priv
->hint_style
= g_value_get_int(value
);
234 case PROP_HINT_METRICS
:
235 font_style
->priv
->hint_metrics
= g_value_get_int(value
);
238 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
245 * adg_font_style_get_slot:
247 * Gets the slot id for this style class.
249 * Return value: the slot
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
);
263 * adg_font_style_new:
265 * Constructs a new font style initialized with default params.
267 * Return value: a new font style
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
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
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
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.
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
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.
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
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.
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
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.
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.
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
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.
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
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.
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");
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",
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.,
565 pool
->pdata
[ADG_FONT_STYLE_NOTE
] =
566 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
569 pool
->len
= ADG_FONT_STYLE_LAST
;
576 apply(AdgStyle
*style
, cairo_t
*cr
)
578 AdgFontStyle
*font_style
;
579 AdgStyleClass
*style_class
;
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
,
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
);
619 set_family(AdgFontStyle
*font_style
, const gchar
*family
)
621 g_free(font_style
->priv
->family
);
622 font_style
->priv
->family
= g_strdup(family
);