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"
35 #define PARENT_CLASS ((AdgStyleClass *) adg_font_style_parent_class)
51 static void get_property (GObject
*object
,
55 static void set_property (GObject
*object
,
59 static GPtrArray
* get_pool (void);
60 static void apply (AdgStyle
*style
,
62 static void set_family (AdgFontStyle
*font_style
,
66 G_DEFINE_TYPE(AdgFontStyle
, adg_font_style
, ADG_TYPE_STYLE
)
70 adg_font_style_class_init(AdgFontStyleClass
*klass
)
72 GObjectClass
*gobject_class
;
73 AdgStyleClass
*style_class
;
76 gobject_class
= (GObjectClass
*) klass
;
77 style_class
= (AdgStyleClass
*) klass
;
79 g_type_class_add_private(klass
, sizeof(AdgFontStylePrivate
));
81 gobject_class
->get_property
= get_property
;
82 gobject_class
->set_property
= set_property
;
84 style_class
->get_pool
= get_pool
;
85 style_class
->apply
= apply
;
87 param
= g_param_spec_string("family",
90 ("The font family name, encoded in UTF-8"),
91 NULL
, G_PARAM_READWRITE
);
92 g_object_class_install_property(gobject_class
, PROP_FAMILY
, param
);
94 param
= g_param_spec_int("slant",
97 ("Variant of a font face based on its slant"),
98 G_MININT
, G_MAXINT
, CAIRO_FONT_SLANT_NORMAL
,
100 g_object_class_install_property(gobject_class
, PROP_SLANT
, param
);
102 param
= g_param_spec_int("weight",
105 ("Variant of a font face based on its weight"),
106 G_MININT
, G_MAXINT
, CAIRO_FONT_WEIGHT_NORMAL
,
108 g_object_class_install_property(gobject_class
, PROP_WEIGHT
, param
);
110 param
= g_param_spec_double("size",
112 P_("Font size in user space units"),
113 0., G_MAXDOUBLE
, 10., G_PARAM_READWRITE
);
114 g_object_class_install_property(gobject_class
, PROP_SIZE
, param
);
116 param
= g_param_spec_int("antialias",
117 P_("Font Antialiasing Mode"),
119 ("Type of antialiasing to do when rendering text"),
120 G_MININT
, G_MAXINT
, CAIRO_ANTIALIAS_DEFAULT
,
122 g_object_class_install_property(gobject_class
, PROP_ANTIALIAS
, param
);
124 param
= g_param_spec_int("subpixel-order",
125 P_("Font Subpixel Order"),
127 ("The order of color elements within each pixel on the display device when rendering with subpixel antialiasing mode"),
129 CAIRO_SUBPIXEL_ORDER_DEFAULT
,
131 g_object_class_install_property(gobject_class
, PROP_SUBPIXEL_ORDER
,
134 param
= g_param_spec_int("hint-style",
135 P_("Type of Hinting"),
137 ("How outlines must fit to the pixel grid in order to improve the glyph appearance"),
138 G_MININT
, G_MAXINT
, CAIRO_HINT_STYLE_DEFAULT
,
140 g_object_class_install_property(gobject_class
, PROP_HINT_STYLE
, param
);
142 param
= g_param_spec_int("hint-metrics",
143 P_("Font Metric Hinting"),
145 ("Whether to hint font metrics, that is align them to integer values in device space"),
147 CAIRO_HINT_METRICS_DEFAULT
,
149 g_object_class_install_property(gobject_class
, PROP_HINT_METRICS
,
154 adg_font_style_init(AdgFontStyle
*font_style
)
156 AdgFontStylePrivate
*priv
= G_TYPE_INSTANCE_GET_PRIVATE(font_style
,
158 AdgFontStylePrivate
);
161 priv
->slant
= CAIRO_FONT_SLANT_NORMAL
;
162 priv
->weight
= CAIRO_FONT_WEIGHT_NORMAL
;
164 priv
->antialias
= CAIRO_ANTIALIAS_DEFAULT
;
165 priv
->subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
166 priv
->hint_style
= CAIRO_HINT_STYLE_DEFAULT
;
167 priv
->hint_metrics
= CAIRO_HINT_METRICS_DEFAULT
;
169 font_style
->priv
= priv
;
173 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
175 AdgFontStyle
*font_style
= (AdgFontStyle
*) object
;
179 g_value_set_string(value
, font_style
->priv
->family
);
182 g_value_set_int(value
, font_style
->priv
->slant
);
185 g_value_set_int(value
, font_style
->priv
->weight
);
188 g_value_set_double(value
, font_style
->priv
->size
);
191 g_value_set_int(value
, font_style
->priv
->antialias
);
193 case PROP_SUBPIXEL_ORDER
:
194 g_value_set_int(value
, font_style
->priv
->subpixel_order
);
196 case PROP_HINT_STYLE
:
197 g_value_set_int(value
, font_style
->priv
->hint_style
);
199 case PROP_HINT_METRICS
:
200 g_value_set_int(value
, font_style
->priv
->hint_metrics
);
203 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
209 set_property(GObject
*object
,
210 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
212 AdgFontStyle
*font_style
= (AdgFontStyle
*) object
;
216 set_family(font_style
, g_value_get_string(value
));
219 font_style
->priv
->slant
= g_value_get_int(value
);
222 font_style
->priv
->weight
= g_value_get_int(value
);
225 font_style
->priv
->size
= g_value_get_double(value
);
228 font_style
->priv
->antialias
= g_value_get_int(value
);
230 case PROP_SUBPIXEL_ORDER
:
231 font_style
->priv
->subpixel_order
= g_value_get_int(value
);
233 case PROP_HINT_STYLE
:
234 font_style
->priv
->hint_style
= g_value_get_int(value
);
236 case PROP_HINT_METRICS
:
237 font_style
->priv
->hint_metrics
= g_value_get_int(value
);
240 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
247 * adg_font_style_get_slot:
249 * Gets the slot id for this style class.
251 * Return value: the slot
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
);
265 * adg_font_style_new:
267 * Constructs a new font style initialized with default params.
269 * Return value: a new font style
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
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
302 adg_font_style_set_family(AdgFontStyle
*font_style
, const gchar
*family
)
304 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
306 set_family(font_style
, family
);
307 g_object_notify((GObject
*) font_style
, "family");
311 * adg_font_style_get_slant:
312 * @font_style: an #AdgFontStyle object
314 * Gets the slant variant of @font_style.
316 * Return value: the slant variant
319 adg_font_style_get_slant(AdgFontStyle
*font_style
)
321 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
322 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.
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
353 adg_font_style_get_weight(AdgFontStyle
*font_style
)
355 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
356 CAIRO_FONT_WEIGHT_NORMAL
);
358 return font_style
->priv
->weight
;
362 * adg_font_style_set_weight:
363 * @font_style: an #AdgFontStyle object
364 * @weight: the new weight
366 * Sets a new weight variant on @font_style.
369 adg_font_style_set_weight(AdgFontStyle
*font_style
,
370 cairo_font_weight_t weight
)
372 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
374 font_style
->priv
->weight
= weight
;
375 g_object_notify((GObject
*) font_style
, "weight");
379 * adg_font_style_get_size:
380 * @font_style: an #AdgFontStyle object
382 * Gets the size (in paper units) of @font_style.
384 * Return value: the size variant
387 adg_font_style_get_size(AdgFontStyle
*font_style
)
389 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
), 0.);
391 return font_style
->priv
->size
;
395 * adg_font_style_set_size:
396 * @font_style: an #AdgFontStyle object
397 * @size: the new size
399 * Sets a new size (in paper units) on @font_style.
402 adg_font_style_set_size(AdgFontStyle
*font_style
, 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
419 adg_font_style_get_antialias(AdgFontStyle
*font_style
)
421 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
422 CAIRO_ANTIALIAS_DEFAULT
);
424 return font_style
->priv
->antialias
;
428 * adg_font_style_set_antialias:
429 * @font_style: an #AdgFontStyle object
430 * @antialias: the new antialias mode
432 * Sets a new antialias mode.
435 adg_font_style_set_antialias(AdgFontStyle
*font_style
,
436 cairo_antialias_t antialias
)
438 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
440 font_style
->priv
->antialias
= antialias
;
441 g_object_notify((GObject
*) font_style
, "antialias");
445 * adg_font_style_get_subpixel_order:
446 * @font_style: an #AdgFontStyle object
448 * Gets the subpixel order mode used, that is the order of color elements
449 * within each pixel on the display device when rendering with an
450 * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
452 * Return value: the requested subpixel order mode
454 cairo_subpixel_order_t
455 adg_font_style_get_subpixel_order(AdgFontStyle
*font_style
)
457 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
458 CAIRO_SUBPIXEL_ORDER_DEFAULT
);
460 return font_style
->priv
->subpixel_order
;
464 * adg_font_style_set_subpixel_order:
465 * @font_style: an #AdgFontStyle object
466 * @subpixel_order: the new subpixel order mode
468 * Sets a new subpixel order mode.
471 adg_font_style_set_subpixel_order(AdgFontStyle
*font_style
,
472 cairo_subpixel_order_t subpixel_order
)
474 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
476 font_style
->priv
->subpixel_order
= subpixel_order
;
477 g_object_notify((GObject
*) font_style
, "subpixel-order");
481 * adg_font_style_get_hint_style:
482 * @font_style: an #AdgFontStyle object
484 * Gets the hint style mode used, that is how to fit outlines
485 * to the pixel grid in order to improve the appearance of the result.
487 * Return value: the requested hint style mode
490 adg_font_style_get_hint_style(AdgFontStyle
*font_style
)
492 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
493 CAIRO_HINT_STYLE_DEFAULT
);
495 return font_style
->priv
->hint_style
;
499 * adg_font_style_set_hint_style:
500 * @font_style: an #AdgFontStyle object
501 * @hint_style: the new hint style mode
503 * Sets a new hint style mode.
506 adg_font_style_set_hint_style(AdgFontStyle
*font_style
,
507 cairo_hint_style_t hint_style
)
509 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
511 font_style
->priv
->hint_style
= hint_style
;
512 g_object_notify((GObject
*) font_style
, "hint-style");
516 * adg_font_style_get_hint_metrics:
517 * @font_style: an #AdgFontStyle object
519 * Gets the state on whether to hint font metrics.
521 * Return value: the requested hint metrics state
524 adg_font_style_get_hint_metrics(AdgFontStyle
*font_style
)
526 g_return_val_if_fail(ADG_IS_FONT_STYLE(font_style
),
527 CAIRO_HINT_METRICS_DEFAULT
);
529 return font_style
->priv
->hint_metrics
;
533 * adg_font_style_set_hint_metrics:
534 * @font_style: an #AdgFontStyle object
535 * @hint_metrics: the new hint metrics state
537 * Sets a new hint metrics state.
540 adg_font_style_set_hint_metrics(AdgFontStyle
*font_style
,
541 cairo_hint_metrics_t hint_metrics
)
543 g_return_if_fail(ADG_IS_FONT_STYLE(font_style
));
545 font_style
->priv
->hint_metrics
= hint_metrics
;
546 g_object_notify((GObject
*) font_style
, "hint-metrics");
553 static GPtrArray
*pool
= NULL
;
555 if (G_UNLIKELY(pool
== NULL
)) {
556 pool
= g_ptr_array_sized_new(ADG_FONT_STYLE_LAST
);
558 pool
->pdata
[ADG_FONT_STYLE_TEXT
] =
559 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Serif", "size",
561 pool
->pdata
[ADG_FONT_STYLE_QUOTE
] =
562 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
563 12., "weight", CAIRO_FONT_WEIGHT_BOLD
, NULL
);
564 pool
->pdata
[ADG_FONT_STYLE_TOLERANCE
] =
565 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size", 8.,
567 pool
->pdata
[ADG_FONT_STYLE_NOTE
] =
568 g_object_new(ADG_TYPE_FONT_STYLE
, "family", "Sans", "size",
571 pool
->len
= ADG_FONT_STYLE_LAST
;
578 apply(AdgStyle
*style
, cairo_t
*cr
)
580 AdgFontStyle
*font_style
;
581 cairo_font_options_t
*options
;
582 cairo_matrix_t matrix
;
584 cairo_matrix_t font_matrix
;
586 font_style
= (AdgFontStyle
*) style
;
587 cairo_get_matrix(cr
, &matrix
);
588 size
= font_style
->priv
->size
;
590 PARENT_CLASS
->apply(style
, cr
);
592 if (font_style
->priv
->family
)
593 cairo_select_font_face(cr
, font_style
->priv
->family
,
594 font_style
->priv
->slant
,
595 font_style
->priv
->weight
);
597 cairo_matrix_init_scale(&font_matrix
,
598 size
/ (matrix
.xx
- matrix
.yx
),
599 size
/ (matrix
.yy
+ matrix
.xy
));
600 cairo_set_font_matrix(cr
, &font_matrix
);
602 options
= cairo_font_options_create();
604 cairo_font_options_set_antialias(options
, font_style
->priv
->antialias
);
605 cairo_font_options_set_subpixel_order(options
,
608 cairo_font_options_set_hint_style(options
,
609 font_style
->priv
->hint_style
);
610 cairo_font_options_set_hint_metrics(options
,
611 font_style
->priv
->hint_metrics
);
613 cairo_set_font_options(cr
, options
);
614 cairo_font_options_destroy(options
);
618 set_family(AdgFontStyle
*font_style
, const gchar
*family
)
620 g_free(font_style
->priv
->family
);
621 font_style
->priv
->family
= g_strdup(family
);