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 * 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.
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
38 #include "adg-font-style.h"
39 #include "adg-font-style-private.h"
40 #include "adg-context.h"
58 static void get_property (GObject
*object
,
62 static void set_property (GObject
*object
,
66 static GPtrArray
* get_pool (void);
67 static void apply (AdgStyle
*style
,
69 static void set_family (AdgFontStyle
*font_style
,
73 G_DEFINE_TYPE(AdgFontStyle
, adg_font_style
, ADG_TYPE_STYLE
)
77 adg_font_style_class_init(AdgFontStyleClass
*klass
)
79 GObjectClass
*gobject_class
;
80 AdgStyleClass
*style_class
;
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",
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",
104 ("Variant of a font face based on its slant"),
105 G_MININT
, G_MAXINT
, CAIRO_FONT_SLANT_NORMAL
,
107 g_object_class_install_property(gobject_class
, PROP_SLANT
, param
);
109 param
= g_param_spec_int("weight",
112 ("Variant of a font face based on its weight"),
113 G_MININT
, G_MAXINT
, CAIRO_FONT_WEIGHT_NORMAL
,
115 g_object_class_install_property(gobject_class
, PROP_WEIGHT
, param
);
117 param
= g_param_spec_double("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
,
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"),
136 CAIRO_SUBPIXEL_ORDER_DEFAULT
,
138 g_object_class_install_property(gobject_class
, PROP_SUBPIXEL_ORDER
,
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
,
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"),
154 CAIRO_HINT_METRICS_DEFAULT
,
156 g_object_class_install_property(gobject_class
, PROP_HINT_METRICS
,
161 adg_font_style_init(AdgFontStyle
*font_style
)
163 AdgFontStylePrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(font_style
,
165 AdgFontStylePrivate
);
168 data
->slant
= CAIRO_FONT_SLANT_NORMAL
;
169 data
->weight
= CAIRO_FONT_WEIGHT_NORMAL
;
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
;
180 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
182 AdgFontStylePrivate
*data
= ((AdgFontStyle
*) object
)->data
;
186 g_value_set_string(value
, data
->family
);
189 g_value_set_int(value
, data
->slant
);
192 g_value_set_int(value
, data
->weight
);
195 g_value_set_double(value
, data
->size
);
198 g_value_set_int(value
, data
->antialias
);
200 case PROP_SUBPIXEL_ORDER
:
201 g_value_set_int(value
, data
->subpixel_order
);
203 case PROP_HINT_STYLE
:
204 g_value_set_int(value
, data
->hint_style
);
206 case PROP_HINT_METRICS
:
207 g_value_set_int(value
, data
->hint_metrics
);
210 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
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
;
227 set_family(font_style
, g_value_get_string(value
));
230 data
->slant
= g_value_get_int(value
);
233 data
->weight
= g_value_get_int(value
);
236 data
->size
= g_value_get_double(value
);
239 data
->antialias
= g_value_get_int(value
);
241 case PROP_SUBPIXEL_ORDER
:
242 data
->subpixel_order
= g_value_get_int(value
);
244 case PROP_HINT_STYLE
:
245 data
->hint_style
= g_value_get_int(value
);
247 case PROP_HINT_METRICS
:
248 data
->hint_metrics
= g_value_get_int(value
);
251 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
258 * adg_font_style_get_slot:
260 * Gets the slot id for this style class.
262 * Return value: the slot
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
);
276 * adg_font_style_new:
278 * Constructs a new font style initialized with default params.
280 * Return value: a new font style
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
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
;
310 * adg_font_style_set_family:
311 * @font_style: an #AdgFontStyle object
312 * @family: the new family
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
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
;
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.
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
;
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
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
;
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.
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
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
;
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.
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
;
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
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.
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.
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
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.
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
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.
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");
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",
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.,
638 pool
->pdata
[ADG_FONT_STYLE_NOTE
] =
639 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
642 pool
->len
= ADG_FONT_STYLE_LAST
;
649 apply(AdgStyle
*style
, cairo_t
*cr
)
651 AdgFontStyle
*font_style
;
652 AdgFontStylePrivate
*data
;
653 AdgStyleClass
*style_class
;
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
);
665 if (style_class
->apply
!= NULL
)
666 style_class
->apply(style
, cr
);
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
);
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
);