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 * @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.
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
38 * ADG_SLOT_FONT_STYLE:
40 * Gets the slot id for this style class.
42 * Return value: the requested slot id
46 #include "adg-font-style.h"
47 #include "adg-font-style-private.h"
48 #include "adg-context.h"
66 static void get_property (GObject
*object
,
70 static void set_property (GObject
*object
,
74 static GPtrArray
* get_pool (void);
75 static void apply (AdgStyle
*style
,
77 static void set_family (AdgFontStyle
*font_style
,
81 G_DEFINE_TYPE(AdgFontStyle
, adg_font_style
, ADG_TYPE_STYLE
)
85 adg_font_style_class_init(AdgFontStyleClass
*klass
)
87 GObjectClass
*gobject_class
;
88 AdgStyleClass
*style_class
;
91 gobject_class
= (GObjectClass
*) klass
;
92 style_class
= (AdgStyleClass
*) klass
;
94 g_type_class_add_private(klass
, sizeof(AdgFontStylePrivate
));
96 gobject_class
->get_property
= get_property
;
97 gobject_class
->set_property
= set_property
;
99 style_class
->get_pool
= get_pool
;
100 style_class
->apply
= apply
;
102 param
= g_param_spec_string("family",
105 ("The font family name, encoded in UTF-8"),
106 NULL
, G_PARAM_READWRITE
);
107 g_object_class_install_property(gobject_class
, PROP_FAMILY
, param
);
109 param
= g_param_spec_int("slant",
112 ("Variant of a font face based on its slant"),
113 G_MININT
, G_MAXINT
, CAIRO_FONT_SLANT_NORMAL
,
115 g_object_class_install_property(gobject_class
, PROP_SLANT
, param
);
117 param
= g_param_spec_int("weight",
120 ("Variant of a font face based on its weight"),
121 G_MININT
, G_MAXINT
, CAIRO_FONT_WEIGHT_NORMAL
,
123 g_object_class_install_property(gobject_class
, PROP_WEIGHT
, param
);
125 param
= g_param_spec_double("size",
127 P_("Font size in user space units"),
128 0., G_MAXDOUBLE
, 10., G_PARAM_READWRITE
);
129 g_object_class_install_property(gobject_class
, PROP_SIZE
, param
);
131 param
= g_param_spec_int("antialias",
132 P_("Font Antialiasing Mode"),
134 ("Type of antialiasing to do when rendering text"),
135 G_MININT
, G_MAXINT
, CAIRO_ANTIALIAS_DEFAULT
,
137 g_object_class_install_property(gobject_class
, PROP_ANTIALIAS
, param
);
139 param
= g_param_spec_int("subpixel-order",
140 P_("Font Subpixel Order"),
142 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
144 CAIRO_SUBPIXEL_ORDER_DEFAULT
,
146 g_object_class_install_property(gobject_class
, PROP_SUBPIXEL_ORDER
,
149 param
= g_param_spec_int("hint-style",
150 P_("Type of Hinting"),
152 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
153 G_MININT
, G_MAXINT
, CAIRO_HINT_STYLE_DEFAULT
,
155 g_object_class_install_property(gobject_class
, PROP_HINT_STYLE
, param
);
157 param
= g_param_spec_int("hint-metrics",
158 P_("Font Metric Hinting"),
160 ("Whether to hint font metrics, that is align them to integer values in device space"),
162 CAIRO_HINT_METRICS_DEFAULT
,
164 g_object_class_install_property(gobject_class
, PROP_HINT_METRICS
,
169 adg_font_style_init(AdgFontStyle
*font_style
)
171 AdgFontStylePrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(font_style
,
173 AdgFontStylePrivate
);
176 data
->slant
= CAIRO_FONT_SLANT_NORMAL
;
177 data
->weight
= CAIRO_FONT_WEIGHT_NORMAL
;
179 data
->antialias
= CAIRO_ANTIALIAS_DEFAULT
;
180 data
->subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
181 data
->hint_style
= CAIRO_HINT_STYLE_DEFAULT
;
182 data
->hint_metrics
= CAIRO_HINT_METRICS_DEFAULT
;
184 font_style
->data
= data
;
188 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
190 AdgFontStylePrivate
*data
= ((AdgFontStyle
*) object
)->data
;
194 g_value_set_string(value
, data
->family
);
197 g_value_set_int(value
, data
->slant
);
200 g_value_set_int(value
, data
->weight
);
203 g_value_set_double(value
, data
->size
);
206 g_value_set_int(value
, data
->antialias
);
208 case PROP_SUBPIXEL_ORDER
:
209 g_value_set_int(value
, data
->subpixel_order
);
211 case PROP_HINT_STYLE
:
212 g_value_set_int(value
, data
->hint_style
);
214 case PROP_HINT_METRICS
:
215 g_value_set_int(value
, data
->hint_metrics
);
218 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
224 set_property(GObject
*object
,
225 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
227 AdgFontStyle
*font_style
;
228 AdgFontStylePrivate
*data
;
230 font_style
= (AdgFontStyle
*) object
;
231 data
= font_style
->data
;
235 set_family(font_style
, g_value_get_string(value
));
238 data
->slant
= g_value_get_int(value
);
241 data
->weight
= g_value_get_int(value
);
244 data
->size
= g_value_get_double(value
);
247 data
->antialias
= g_value_get_int(value
);
249 case PROP_SUBPIXEL_ORDER
:
250 data
->subpixel_order
= g_value_get_int(value
);
252 case PROP_HINT_STYLE
:
253 data
->hint_style
= g_value_get_int(value
);
255 case PROP_HINT_METRICS
:
256 data
->hint_metrics
= g_value_get_int(value
);
259 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
266 _adg_font_style_get_slot(void)
268 static AdgStyleSlot slot
= -1;
270 if (G_UNLIKELY(slot
< 0))
271 slot
= adg_context_get_slot(ADG_TYPE_FONT_STYLE
);
277 * adg_font_style_new:
279 * Constructs a new font style initialized with default params.
281 * Return value: a new font style
284 adg_font_style_new(void)
286 return g_object_new(ADG_TYPE_FONT_STYLE
, NULL
);
290 * adg_font_style_get_family:
291 * @font_style: an #AdgFontStyle object
293 * Gets the family of @font_style. The returned pointer refers to
294 * internally managed text that must not be modified or freed.
296 * Return value: the requested family
299 adg_font_style_get_family(AdgFontStyle
*font_style
)
301 AdgFontStylePrivate
*data
;
303 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
), NULL
);
305 data
= font_style
->data
;
311 * adg_font_style_set_family:
312 * @font_style: an #AdgFontStyle object
313 * @family: the new family
318 adg_font_style_set_family(AdgFontStyle
*font_style
, const gchar
*family
)
320 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
322 set_family(font_style
, family
);
323 g_object_notify((GObject
*) font_style
, "family");
327 * adg_font_style_get_slant:
328 * @font_style: an #AdgFontStyle object
330 * Gets the slant variant of @font_style.
332 * Return value: the slant variant
335 adg_font_style_get_slant(AdgFontStyle
*font_style
)
337 AdgFontStylePrivate
*data
;
339 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
340 CAIRO_FONT_SLANT_NORMAL
);
342 data
= font_style
->data
;
348 * adg_font_style_set_slant:
349 * @font_style: an #AdgFontStyle object
350 * @slant: the new slant
352 * Sets a new slant variant on @font_style.
355 adg_font_style_set_slant(AdgFontStyle
*font_style
,
356 cairo_font_slant_t slant
)
358 AdgFontStylePrivate
*data
;
360 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
362 data
= font_style
->data
;
365 g_object_notify((GObject
*) font_style
, "slant");
369 * adg_font_style_get_weight:
370 * @font_style: an #AdgFontStyle object
372 * Gets the weight variant of @font_style.
374 * Return value: the weight variant
377 adg_font_style_get_weight(AdgFontStyle
*font_style
)
379 AdgFontStylePrivate
*data
;
381 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
382 CAIRO_FONT_WEIGHT_NORMAL
);
384 data
= font_style
->data
;
390 * adg_font_style_set_weight:
391 * @font_style: an #AdgFontStyle object
392 * @weight: the new weight
394 * Sets a new weight variant on @font_style.
397 adg_font_style_set_weight(AdgFontStyle
*font_style
,
398 cairo_font_weight_t weight
)
400 AdgFontStylePrivate
*data
;
402 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
404 data
= font_style
->data
;
405 data
->weight
= weight
;
407 g_object_notify((GObject
*) font_style
, "weight");
411 * adg_font_style_get_size:
412 * @font_style: an #AdgFontStyle object
414 * Gets the size (in global space) of @font_style.
416 * Return value: the size variant
419 adg_font_style_get_size(AdgFontStyle
*font_style
)
421 AdgFontStylePrivate
*data
;
423 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
), 0.);
425 data
= font_style
->data
;
431 * adg_font_style_set_size:
432 * @font_style: an #AdgFontStyle object
433 * @size: the new size
435 * Sets a new size (in global space) on @font_style.
438 adg_font_style_set_size(AdgFontStyle
*font_style
, gdouble size
)
440 AdgFontStylePrivate
*data
;
442 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
444 data
= font_style
->data
;
447 g_object_notify((GObject
*) font_style
, "size");
451 * adg_font_style_get_antialias:
452 * @font_style: an #AdgFontStyle object
454 * Gets the antialias mode used.
456 * Return value: the requested antialias mode
459 adg_font_style_get_antialias(AdgFontStyle
*font_style
)
461 AdgFontStylePrivate
*data
;
463 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
464 CAIRO_ANTIALIAS_DEFAULT
);
466 data
= font_style
->data
;
468 return data
->antialias
;
472 * adg_font_style_set_antialias:
473 * @font_style: an #AdgFontStyle object
474 * @antialias: the new antialias mode
476 * Sets a new antialias mode.
479 adg_font_style_set_antialias(AdgFontStyle
*font_style
,
480 cairo_antialias_t antialias
)
482 AdgFontStylePrivate
*data
;
484 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
486 data
= font_style
->data
;
487 data
->antialias
= antialias
;
489 g_object_notify((GObject
*) font_style
, "antialias");
493 * adg_font_style_get_subpixel_order:
494 * @font_style: an #AdgFontStyle object
496 * Gets the subpixel order mode used, that is the order of color elements
497 * within each pixel on the display device when rendering with an
498 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
500 * Return value: the requested subpixel order mode
502 cairo_subpixel_order_t
503 adg_font_style_get_subpixel_order(AdgFontStyle
*font_style
)
505 AdgFontStylePrivate
*data
;
507 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
508 CAIRO_SUBPIXEL_ORDER_DEFAULT
);
510 data
= font_style
->data
;
512 return data
->subpixel_order
;
516 * adg_font_style_set_subpixel_order:
517 * @font_style: an #AdgFontStyle object
518 * @subpixel_order: the new subpixel order mode
520 * Sets a new subpixel order mode.
523 adg_font_style_set_subpixel_order(AdgFontStyle
*font_style
,
524 cairo_subpixel_order_t subpixel_order
)
526 AdgFontStylePrivate
*data
;
528 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
530 data
= font_style
->data
;
531 data
->subpixel_order
= subpixel_order
;
533 g_object_notify((GObject
*) font_style
, "subpixel-order");
537 * adg_font_style_get_hint_style:
538 * @font_style: an #AdgFontStyle object
540 * Gets the hint style mode used, that is how to fit outlines
541 * to the pixel grid in order to improve the appearance of the result.
543 * Return value: the requested hint style mode
546 adg_font_style_get_hint_style(AdgFontStyle
*font_style
)
548 AdgFontStylePrivate
*data
;
550 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
551 CAIRO_HINT_STYLE_DEFAULT
);
553 data
= font_style
->data
;
555 return data
->hint_style
;
559 * adg_font_style_set_hint_style:
560 * @font_style: an #AdgFontStyle object
561 * @hint_style: the new hint style mode
563 * Sets a new hint style mode.
566 adg_font_style_set_hint_style(AdgFontStyle
*font_style
,
567 cairo_hint_style_t hint_style
)
569 AdgFontStylePrivate
*data
;
571 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
573 data
= font_style
->data
;
574 data
->hint_style
= hint_style
;
576 g_object_notify((GObject
*) font_style
, "hint-style");
580 * adg_font_style_get_hint_metrics:
581 * @font_style: an #AdgFontStyle object
583 * Gets the state on whether to hint font metrics.
585 * Return value: the requested hint metrics state
588 adg_font_style_get_hint_metrics(AdgFontStyle
*font_style
)
590 AdgFontStylePrivate
*data
;
592 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
593 CAIRO_HINT_METRICS_DEFAULT
);
595 data
= font_style
->data
;
597 return data
->hint_metrics
;
601 * adg_font_style_set_hint_metrics:
602 * @font_style: an #AdgFontStyle object
603 * @hint_metrics: the new hint metrics state
605 * Sets a new hint metrics state.
608 adg_font_style_set_hint_metrics(AdgFontStyle
*font_style
,
609 cairo_hint_metrics_t hint_metrics
)
611 AdgFontStylePrivate
*data
;
613 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
615 data
= font_style
->data
;
616 data
->hint_metrics
= hint_metrics
;
618 g_object_notify((GObject
*) font_style
, "hint-metrics");
625 static GPtrArray
*pool
= NULL
;
627 if (G_UNLIKELY(pool
== NULL
)) {
628 pool
= g_ptr_array_sized_new(ADG_FONT_STYLE_LAST
);
630 pool
->pdata
[ADG_FONT_STYLE_TEXT
] =
631 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Serif", "size",
633 pool
->pdata
[ADG_FONT_STYLE_VALUE
] =
634 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
635 12., "weight", CAIRO_FONT_WEIGHT_BOLD
, NULL
);
636 pool
->pdata
[ADG_FONT_STYLE_TOLERANCE
] =
637 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size", 8.,
639 pool
->pdata
[ADG_FONT_STYLE_NOTE
] =
640 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
643 pool
->len
= ADG_FONT_STYLE_LAST
;
650 apply(AdgStyle
*style
, cairo_t
*cr
)
652 AdgFontStyle
*font_style
;
653 AdgFontStylePrivate
*data
;
654 AdgStyleClass
*style_class
;
656 cairo_font_options_t
*options
;
657 cairo_matrix_t matrix
;
658 cairo_matrix_t font_matrix
;
660 font_style
= (AdgFontStyle
*) style
;
661 data
= font_style
->data
;
662 style_class
= (AdgStyleClass
*) adg_font_style_parent_class
;
663 cairo_get_matrix(cr
, &matrix
);
666 if (style_class
->apply
!= NULL
)
667 style_class
->apply(style
, cr
);
670 cairo_select_font_face(cr
, data
->family
,
671 data
->slant
, data
->weight
);
673 cairo_matrix_init_scale(&font_matrix
,
674 size
/ (matrix
.xx
- matrix
.yx
),
675 size
/ (matrix
.yy
+ matrix
.xy
));
676 cairo_set_font_matrix(cr
, &font_matrix
);
678 options
= cairo_font_options_create();
680 cairo_font_options_set_antialias(options
, data
->antialias
);
681 cairo_font_options_set_subpixel_order(options
, data
->subpixel_order
);
682 cairo_font_options_set_hint_style(options
, data
->hint_style
);
683 cairo_font_options_set_hint_metrics(options
, data
->hint_metrics
);
685 cairo_set_font_options(cr
, options
);
686 cairo_font_options_destroy(options
);
690 set_family(AdgFontStyle
*font_style
, const gchar
*family
)
692 AdgFontStylePrivate
*data
= font_style
->data
;
694 g_free(data
->family
);
695 data
->family
= g_strdup(family
);