Privatized "glyphs_translate"
[adg.git] / adg / adg-dim.c
blob1f21aaa601d32247bc85dd5f198a28f6abd6813e
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.
20 /**
21 * SECTION:dim
22 * @title: AdgDim
23 * @short_description: Root abstract class for all dimension entities
25 * The #AdgDim class is the base stub of all the dimension entities.
28 #include "adg-dim.h"
29 #include "adg-dim-private.h"
30 #include "adg-util.h"
31 #include "adg-intl.h"
33 #define PARENT_CLASS ((AdgEntityClass *) adg_dim_parent_class)
36 enum {
37 PROP_0,
38 PROP_REF1,
39 PROP_REF2,
40 PROP_POS1,
41 PROP_POS2,
42 PROP_LEVEL,
43 PROP_QUOTE,
44 PROP_TOLERANCE_UP,
45 PROP_TOLERANCE_DOWN,
46 PROP_NOTE
50 static void finalize (GObject *object);
51 static void get_property (GObject *object,
52 guint param_id,
53 GValue *value,
54 GParamSpec *pspec);
55 static void set_property (GObject *object,
56 guint param_id,
57 const GValue *value,
58 GParamSpec *pspec);
59 static void model_matrix_changed (AdgEntity *entity,
60 AdgMatrix *parent_matrix);
61 static void invalidate (AdgEntity *entity);
62 static void invalidate_quote (AdgDim *dim);
63 static void invalidate_tolerance_up (AdgDim *dim);
64 static void invalidate_tolerance_down (AdgDim *dim);
65 static void invalidate_note (AdgDim *dim);
66 static gchar * default_quote (AdgDim *dim);
67 static void glyphs_translate (cairo_glyph_t *glyphs,
68 int num_glyphs,
69 const CpmlPair *shift);
70 static void quote_layout (AdgDim *dim,
71 cairo_t *cr);
74 G_DEFINE_ABSTRACT_TYPE(AdgDim, adg_dim, ADG_TYPE_ENTITY);
77 static void
78 adg_dim_class_init(AdgDimClass *klass)
80 GObjectClass *gobject_class;
81 AdgEntityClass *entity_class;
82 GParamSpec *param;
84 gobject_class = (GObjectClass *) klass;
85 entity_class = (AdgEntityClass *) klass;
87 g_type_class_add_private(klass, sizeof(AdgDimPrivate));
89 gobject_class->finalize = finalize;
90 gobject_class->get_property = get_property;
91 gobject_class->set_property = set_property;
93 entity_class->model_matrix_changed = model_matrix_changed;
94 entity_class->invalidate = invalidate;
96 klass->default_quote = default_quote;
97 klass->quote_layout = quote_layout;
99 param = g_param_spec_boxed("ref1",
100 P_("Reference 1"),
101 P_("First reference point of the dimension"),
102 ADG_TYPE_PAIR,
103 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
104 g_object_class_install_property(gobject_class, PROP_REF1, param);
106 param = g_param_spec_boxed("ref2",
107 P_("Reference 2"),
108 P_("Second reference point of the dimension"),
109 ADG_TYPE_PAIR,
110 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
111 g_object_class_install_property(gobject_class, PROP_REF2, param);
113 param = g_param_spec_boxed("pos1",
114 P_("Position 1"),
115 P_("First position point: it will be computed with the level property to get the real dimension position"),
116 ADG_TYPE_PAIR, G_PARAM_READWRITE);
117 g_object_class_install_property(gobject_class, PROP_POS1, param);
119 param = g_param_spec_boxed("pos2",
120 P_("Position 2"),
121 P_("Second position point: it will be computed with the level property to get the real dimension position"),
122 ADG_TYPE_PAIR, G_PARAM_READWRITE);
123 g_object_class_install_property(gobject_class, PROP_POS2, param);
125 param = g_param_spec_double("level",
126 P_("Level"),
127 P_("The dimension level, that is the factor to multiply dim_style->baseline_spacing to get the offset (in device units) from pos1..pos2 where render the dimension baseline"),
128 -G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
129 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
130 g_object_class_install_property(gobject_class, PROP_LEVEL, param);
132 param = g_param_spec_string("quote",
133 P_("Quote"),
134 P_("The quote to display: set to NULL to get the default quote"),
135 NULL, G_PARAM_READWRITE);
136 g_object_class_install_property(gobject_class, PROP_QUOTE, param);
138 param = g_param_spec_string("tolerance-up",
139 P_("Up Tolerance"),
140 P_("The up tolerance of the quote: set to NULL to suppress"),
141 NULL, G_PARAM_READWRITE);
142 g_object_class_install_property(gobject_class, PROP_TOLERANCE_UP, param);
144 param = g_param_spec_string("tolerance-down",
145 P_("Down Tolerance"),
146 P_("The down tolerance of the quote: set to NULL to suppress"),
147 NULL, G_PARAM_READWRITE);
148 g_object_class_install_property(gobject_class, PROP_TOLERANCE_DOWN, param);
150 param = g_param_spec_string("note",
151 P_("Note"),
152 P_("A custom note appended to the dimension quote"),
153 NULL, G_PARAM_READWRITE);
154 g_object_class_install_property(gobject_class, PROP_NOTE, param);
157 static void
158 adg_dim_init(AdgDim *dim)
160 AdgDimPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(dim, ADG_TYPE_DIM,
161 AdgDimPrivate);
163 priv->ref1.x = priv->ref1.y = 0.;
164 priv->ref2.x = priv->ref2.y = 0.;
165 priv->pos1.x = priv->pos1.y = 0.;
166 priv->pos2.x = priv->pos2.y = 0.;
167 priv->level = 1.;
168 priv->quote = NULL;
169 priv->tolerance_up = NULL;
170 priv->tolerance_down = NULL;
171 priv->note = NULL;
173 priv->quote_org.x = priv->quote_org.y = 0.;
174 priv->quote_angle = 0.;
175 priv->quote_num_glyphs = 0;
176 priv->quote_glyphs = NULL;
177 priv->tolerance_up_num_glyphs = 0;
178 priv->tolerance_up_glyphs = NULL;
179 priv->tolerance_down_num_glyphs = 0;
180 priv->tolerance_down_glyphs = NULL;
181 priv->note_num_glyphs = 0;
182 priv->note_glyphs = NULL;
184 dim->priv = priv;
187 static void
188 finalize(GObject *object)
190 AdgDim *dim = (AdgDim *) object;
192 g_free(dim->priv->quote);
193 g_free(dim->priv->tolerance_up);
194 g_free(dim->priv->tolerance_down);
196 invalidate((AdgEntity *) dim);
198 ((GObjectClass *) PARENT_CLASS)->finalize(object);
201 static void
202 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
204 AdgDim *dim = (AdgDim *) object;
206 switch (prop_id) {
207 case PROP_REF1:
208 g_value_set_boxed(value, &dim->priv->ref1);
209 break;
210 case PROP_REF2:
211 g_value_set_boxed(value, &dim->priv->ref2);
212 break;
213 case PROP_POS1:
214 g_value_set_boxed(value, &dim->priv->pos1);
215 break;
216 case PROP_POS2:
217 g_value_set_boxed(value, &dim->priv->pos1);
218 break;
219 case PROP_LEVEL:
220 g_value_set_double(value, dim->priv->level);
221 break;
222 case PROP_QUOTE:
223 g_value_set_string(value, dim->priv->quote);
224 break;
225 case PROP_TOLERANCE_UP:
226 g_value_set_string(value, dim->priv->tolerance_up);
227 break;
228 case PROP_TOLERANCE_DOWN:
229 g_value_set_string(value, dim->priv->tolerance_down);
230 break;
231 case PROP_NOTE:
232 g_value_set_string(value, dim->priv->note);
233 break;
234 default:
235 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
236 break;
240 static void
241 set_property(GObject *object, guint prop_id,
242 const GValue *value, GParamSpec *pspec)
244 AdgEntity *entity;
245 AdgDim *dim;
247 entity = (AdgEntity *) object;
248 dim = (AdgDim *) object;
250 switch (prop_id) {
251 case PROP_REF1:
252 cpml_pair_copy(&dim->priv->ref1, (AdgPair *) g_value_get_boxed(value));
253 invalidate(entity);
254 break;
255 case PROP_REF2:
256 cpml_pair_copy(&dim->priv->ref2, (AdgPair *) g_value_get_boxed(value));
257 invalidate(entity);
258 break;
259 case PROP_POS1:
260 cpml_pair_copy(&dim->priv->pos1, (AdgPair *) g_value_get_boxed(value));
261 invalidate(entity);
262 break;
263 case PROP_POS2:
264 cpml_pair_copy(&dim->priv->pos2, (AdgPair *) g_value_get_boxed(value));
265 invalidate(entity);
266 break;
267 case PROP_LEVEL:
268 dim->priv->level = g_value_get_double(value);
269 invalidate(entity);
270 break;
271 case PROP_QUOTE:
272 g_free(dim->priv->quote);
273 dim->priv->quote = g_value_dup_string(value);
274 invalidate_quote(dim);
275 break;
276 case PROP_TOLERANCE_UP:
277 g_free(dim->priv->tolerance_up);
278 dim->priv->tolerance_up = g_value_dup_string(value);
279 invalidate_tolerance_up(dim);
280 break;
281 case PROP_TOLERANCE_DOWN:
282 g_free(dim->priv->tolerance_down);
283 dim->priv->tolerance_down = g_value_dup_string(value);
284 invalidate_tolerance_down(dim);
285 break;
286 case PROP_NOTE:
287 g_free(dim->priv->note);
288 dim->priv->note = g_value_dup_string(value);
289 invalidate_note(dim);
290 break;
291 default:
292 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
293 break;
298 static void
299 model_matrix_changed(AdgEntity *entity, AdgMatrix *parent_matrix)
301 invalidate(entity);
302 PARENT_CLASS->model_matrix_changed(entity, parent_matrix);
305 static void
306 invalidate(AdgEntity *entity)
308 AdgDim *dim = (AdgDim *) entity;
310 dim->priv->quote_angle = 0.;
311 dim->priv->quote_org.x = 0.;
312 dim->priv->quote_org.y = 0.;
314 invalidate_quote(dim);
315 invalidate_tolerance_up(dim);
316 invalidate_tolerance_down(dim);
317 invalidate_note(dim);
320 static void
321 invalidate_quote(AdgDim *dim)
323 if (dim->priv->quote_glyphs) {
324 cairo_glyph_free(dim->priv->quote_glyphs);
325 dim->priv->quote_glyphs = NULL;
328 dim->priv->quote_num_glyphs = 0;
331 static void
332 invalidate_tolerance_up(AdgDim *dim)
334 if (dim->priv->tolerance_up_glyphs) {
335 cairo_glyph_free(dim->priv->tolerance_up_glyphs);
336 dim->priv->tolerance_up_glyphs = NULL;
339 dim->priv->tolerance_up_num_glyphs = 0;
342 static void
343 invalidate_tolerance_down(AdgDim *dim)
345 if (dim->priv->tolerance_down_glyphs) {
346 cairo_glyph_free(dim->priv->tolerance_down_glyphs);
347 dim->priv->tolerance_down_glyphs = NULL;
350 dim->priv->tolerance_down_num_glyphs = 0;
353 static void
354 invalidate_note(AdgDim *dim)
356 if (dim->priv->note_glyphs) {
357 cairo_glyph_free(dim->priv->note_glyphs);
358 dim->priv->note_glyphs = NULL;
361 dim->priv->note_num_glyphs = 0;
365 static gchar *
366 default_quote(AdgDim *dim)
368 g_warning("AdgDim::default_quote not implemented for `%s'",
369 g_type_name(G_TYPE_FROM_INSTANCE(dim)));
370 return g_strdup("undef");
373 static void
374 glyphs_translate(cairo_glyph_t *glyphs, int num_glyphs, const CpmlPair *shift)
376 cairo_glyph_t *glyph;
378 for (glyph = glyphs; num_glyphs --; ++ glyph) {
379 glyph->x += shift->x;
380 glyph->y += shift->y;
384 static void
385 quote_layout(AdgDim *dim, cairo_t *cr)
387 AdgDimPrivate *priv;
388 AdgDimStyle *dim_style;
389 AdgPair shift;
390 CpmlPair cp, org;
391 CpmlPair quote_org, tolerance_up_org, tolerance_down_org, note_org;
392 cairo_text_extents_t extents;
394 priv = dim->priv;
395 dim_style = (AdgDimStyle *) adg_entity_get_style((AdgEntity *) dim,
396 ADG_SLOT_DIM_STYLE);
398 /* Compute the quote */
399 adg_style_apply(adg_dim_style_get_quote_style(dim_style), cr);
400 quote_org.x = 0.;
401 quote_org.y = 0.;
403 if (!priv->quote_glyphs)
404 cairo_scaled_font_text_to_glyphs(cairo_get_scaled_font(cr),
405 quote_org.x, quote_org.y,
406 priv->quote, -1,
407 &priv->quote_glyphs,
408 &priv->quote_num_glyphs,
409 NULL, NULL, NULL);
411 cairo_glyph_extents(cr, priv->quote_glyphs, priv->quote_num_glyphs,
412 &extents);
413 cairo_user_to_device_distance(cr, &extents.width, &extents.height);
415 cp.x = extents.width;
416 cp.y = extents.height / -2.;
418 /* Compute the tolerances */
419 if (priv->tolerance_up != NULL || priv->tolerance_down != NULL) {
420 double width;
421 double midspacing;
423 adg_style_apply(adg_dim_style_get_tolerance_style(dim_style), cr);
425 width = 0.;
426 midspacing = adg_dim_style_get_tolerance_spacing(dim_style) / 2.;
427 cpml_pair_copy(&shift, adg_dim_style_get_tolerance_shift(dim_style));
428 cp.x += shift.x;
430 if (priv->tolerance_up) {
431 if (!priv->tolerance_up_glyphs)
432 cairo_scaled_font_text_to_glyphs(cairo_get_scaled_font(cr),
433 0., 0.,
434 priv->tolerance_up, -1,
435 &priv->tolerance_up_glyphs,
436 &priv->tolerance_up_num_glyphs,
437 NULL, NULL, NULL);
439 cairo_glyph_extents(cr, priv->tolerance_up_glyphs,
440 priv->tolerance_up_num_glyphs, &extents);
441 cairo_user_to_device_distance(cr, &extents.width, &extents.height);
443 tolerance_up_org.x = cp.x;
444 tolerance_up_org.y = cp.y + shift.y - midspacing;
446 width = extents.width;
449 if (priv->tolerance_down) {
450 if (!priv->tolerance_down_glyphs)
451 cairo_scaled_font_text_to_glyphs(cairo_get_scaled_font(cr),
452 0., 0.,
453 priv->tolerance_down, -1,
454 &priv->tolerance_down_glyphs,
455 &priv->tolerance_down_num_glyphs,
456 NULL, NULL, NULL);
458 cairo_glyph_extents(cr, priv->tolerance_down_glyphs,
459 priv->tolerance_down_num_glyphs, &extents);
460 cairo_user_to_device_distance(cr, &extents.width, &extents.height);
462 tolerance_down_org.x = cp.x;
463 tolerance_down_org.y = cp.y + shift.y + midspacing + extents.height;
465 if (extents.width > width)
466 width = extents.width;
469 cp.x += width;
472 /* Compute the note */
473 if (priv->note != NULL) {
474 adg_style_apply(adg_dim_style_get_note_style(dim_style), cr);
476 cpml_pair_copy(&shift, adg_dim_style_get_note_shift(dim_style));
477 cp.x += shift.x;
479 if (!priv->note_glyphs)
480 cairo_scaled_font_text_to_glyphs(cairo_get_scaled_font(cr),
481 0., 0.,
482 priv->note, -1,
483 &priv->note_glyphs,
484 &priv->note_num_glyphs,
485 NULL, NULL, NULL);
487 cairo_glyph_extents(cr, priv->note_glyphs, priv->note_num_glyphs,
488 &extents);
489 cairo_user_to_device_distance(cr, &extents.width, &extents.height);
491 note_org.x = cp.x;
492 note_org.y = cp.y + shift.y + extents.height / 2.;
494 cp.x += extents.width;
497 /* Centering and shifting the whole group */
498 cpml_pair_copy(&shift, adg_dim_style_get_quote_shift(dim_style));
499 shift.x -= cp.x / 2.;
501 if (priv->quote_glyphs) {
502 quote_org.x += shift.x;
503 quote_org.y += shift.y;
504 cairo_device_to_user_distance(cr, &quote_org.x, &quote_org.y);
505 glyphs_translate(priv->quote_glyphs,
506 priv->quote_num_glyphs,
507 &quote_org);
510 if (priv->tolerance_up_glyphs) {
511 tolerance_up_org.x += shift.x;
512 tolerance_up_org.y += shift.y;
513 cairo_device_to_user_distance(cr, &tolerance_up_org.x,
514 &tolerance_up_org.y);
515 glyphs_translate(priv->tolerance_up_glyphs,
516 priv->tolerance_up_num_glyphs,
517 &tolerance_up_org);
520 if (priv->tolerance_down_glyphs) {
521 tolerance_down_org.x += shift.x;
522 tolerance_down_org.y += shift.y;
523 cairo_device_to_user_distance(cr, &tolerance_down_org.x,
524 &tolerance_down_org.y);
525 glyphs_translate(priv->tolerance_down_glyphs,
526 priv->tolerance_down_num_glyphs,
527 &tolerance_down_org);
530 if (priv->note_glyphs) {
531 note_org.x += shift.x;
532 note_org.y += shift.y;
533 cairo_device_to_user_distance(cr, &note_org.x, &note_org.y);
534 glyphs_translate(priv->note_glyphs, priv->note_num_glyphs,
535 &note_org);
540 const AdgPair *
541 adg_dim_get_ref1(AdgDim *dim)
543 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
545 return &dim->priv->ref1;
548 const AdgPair *
549 adg_dim_get_ref2(AdgDim *dim)
551 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
553 return &dim->priv->ref2;
556 void
557 adg_dim_set_ref(AdgDim *dim, const AdgPair *ref1, const AdgPair *ref2)
559 g_return_if_fail(ADG_IS_DIM(dim));
561 if (ref1 != NULL || ref2 != NULL) {
562 GObject *object = (GObject *) dim;
564 g_object_freeze_notify(object);
566 if (ref1 != NULL) {
567 dim->priv->ref1 = *ref1;
568 g_object_notify(object, "ref1");
571 if (ref2 != NULL) {
572 dim->priv->ref2 = *ref2;
573 g_object_notify(object, "ref2");
576 g_object_thaw_notify(object);
577 invalidate((AdgEntity *) dim);
581 void
582 adg_dim_set_ref_explicit(AdgDim *dim, double ref1_x, double ref1_y,
583 double ref2_x, double ref2_y)
585 AdgPair ref1;
586 AdgPair ref2;
588 ref1.x = ref1_x;
589 ref1.y = ref1_y;
590 ref2.x = ref2_x;
591 ref2.y = ref2_y;
593 adg_dim_set_ref(dim, &ref1, &ref2);
596 const AdgPair *
597 adg_dim_get_pos1(AdgDim *dim)
599 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
601 return &dim->priv->pos1;
604 const AdgPair *
605 adg_dim_get_pos2(AdgDim *dim)
607 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
609 return &dim->priv->pos2;
612 void
613 adg_dim_set_pos(AdgDim *dim, AdgPair *pos1, AdgPair *pos2)
615 g_return_if_fail(ADG_IS_DIM(dim));
617 if (pos1 != NULL || pos2 != NULL) {
618 GObject *object = (GObject *) dim;
620 g_object_freeze_notify(object);
622 if (pos1 != NULL) {
623 dim->priv->pos1 = *pos1;
624 g_object_notify(object, "pos1");
626 if (pos2 != NULL) {
627 dim->priv->pos2 = *pos2;
628 g_object_notify(object, "pos2");
631 g_object_thaw_notify(object);
632 invalidate((AdgEntity *) dim);
636 void
637 adg_dim_set_pos_explicit(AdgDim *dim, double pos1_x, double pos1_y,
638 double pos2_x, double pos2_y)
640 AdgPair pos1;
641 AdgPair pos2;
643 pos1.x = pos1_x;
644 pos1.y = pos1_y;
645 pos2.x = pos2_x;
646 pos2.y = pos2_y;
648 adg_dim_set_pos(dim, &pos1, &pos2);
651 double
652 adg_dim_get_level(AdgDim *dim)
654 g_return_val_if_fail(ADG_IS_DIM(dim), 0.0);
656 return dim->priv->level;
659 void
660 adg_dim_set_level(AdgDim *dim, double level)
662 g_return_if_fail(ADG_IS_DIM(dim));
664 dim->priv->level = level;
665 g_object_notify((GObject *) dim, "level");
668 const gchar *
669 adg_dim_get_quote(AdgDim *dim)
671 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
673 return dim->priv->quote;
676 void
677 adg_dim_set_quote(AdgDim *dim, const gchar *quote)
679 g_return_if_fail(ADG_IS_DIM(dim));
681 g_free(dim->priv->quote);
682 dim->priv->quote = g_strdup(quote);
683 g_object_notify((GObject *) dim, "quote");
685 invalidate_quote(dim);
688 const gchar *
689 adg_dim_get_tolerance_up(AdgDim *dim)
691 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
693 return dim->priv->tolerance_up;
696 void
697 adg_dim_set_tolerance_up(AdgDim *dim, const gchar *tolerance_up)
699 g_return_if_fail(ADG_IS_DIM(dim));
701 g_free(dim->priv->tolerance_up);
702 dim->priv->tolerance_up = g_strdup(tolerance_up);
703 g_object_notify((GObject *) dim, "tolerance-up");
705 invalidate_tolerance_up(dim);
708 const gchar *
709 adg_dim_get_tolerance_down(AdgDim *dim)
711 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
713 return dim->priv->tolerance_down;
716 void
717 adg_dim_set_tolerance_down(AdgDim *dim, const gchar *tolerance_down)
719 g_return_if_fail(ADG_IS_DIM(dim));
721 g_free(dim->priv->tolerance_down);
722 dim->priv->tolerance_down = g_strdup(tolerance_down);
723 g_object_notify((GObject *) dim, "tolerance-down");
725 invalidate_tolerance_down(dim);
728 void
729 adg_dim_set_tolerances(AdgDim *dim,
730 const gchar *tolerance_up, const gchar *tolerance_down)
732 g_return_if_fail(ADG_IS_DIM(dim));
734 g_object_freeze_notify((GObject *) dim);
735 adg_dim_set_tolerance_up(dim, tolerance_up);
736 adg_dim_set_tolerance_down(dim, tolerance_down);
737 g_object_thaw_notify((GObject *) dim);
740 const gchar *
741 adg_dim_get_note(AdgDim *dim)
743 g_return_val_if_fail(ADG_IS_DIM(dim), NULL);
745 return dim->priv->note;
748 void
749 adg_dim_set_note(AdgDim *dim, const gchar *note)
751 g_return_if_fail(ADG_IS_DIM(dim));
753 g_free(dim->priv->note);
754 dim->priv->note = g_strdup(note);
755 g_object_notify((GObject *) dim, "note");
757 invalidate_note(dim);
762 * adg_dim_render_quote:
763 * @dim: an #AdgDim object
764 * @cr: a #cairo_t drawing context
766 * Renders the quote of @dim at the @org position. This function
767 * is only useful in new dimension implementations.
769 void
770 adg_dim_render_quote(AdgDim *dim, cairo_t *cr)
772 AdgDimPrivate *priv;
773 AdgDimStyle *dim_style;
775 g_return_if_fail(ADG_IS_DIM(dim));
777 priv = dim->priv;
778 dim_style = (AdgDimStyle *) adg_entity_get_style((AdgEntity *) dim,
779 ADG_SLOT_DIM_STYLE);
781 if (priv->quote == NULL)
782 adg_dim_set_quote(dim, ADG_DIM_GET_CLASS(dim)->default_quote(dim));
784 ADG_DIM_GET_CLASS(dim)->quote_layout(dim, cr);
786 cairo_save(cr);
787 cairo_translate(cr, priv->quote_org.x, priv->quote_org.y);
788 cairo_rotate(cr, priv->quote_angle);
790 /* Rendering quote */
791 adg_style_apply(adg_dim_style_get_quote_style(dim_style), cr);
792 cairo_show_glyphs(cr, priv->quote_glyphs, priv->quote_num_glyphs);
794 /* Rendering tolerances */
795 if (priv->tolerance_up != NULL || priv->tolerance_down != NULL) {
796 adg_style_apply(adg_dim_style_get_tolerance_style(dim_style), cr);
798 if (priv->tolerance_up != NULL)
799 cairo_show_glyphs(cr, priv->tolerance_up_glyphs,
800 priv->tolerance_up_num_glyphs);
802 if (priv->tolerance_down != NULL)
803 cairo_show_glyphs(cr, priv->tolerance_down_glyphs,
804 priv->tolerance_down_num_glyphs);
807 /* Rendering the note */
808 if (priv->note != NULL) {
809 adg_style_apply(adg_dim_style_get_note_style(dim_style), cr);
810 cairo_show_glyphs(cr, priv->note_glyphs, priv->note_num_glyphs);
813 cairo_restore(cr);