[AdgLDim] Avoid arrange() on the same data
[adg.git] / adg / adg-dim-style.c
blob006f2a4b223128b04d661125f3aaa76868ef52b8
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.
21 /**
22 * SECTION:adg-dim-style
23 * @short_description: Dimension style related stuff
25 * Contains parameters on how to build dimensions such as the different font
26 * styles (for value and limits), line style, offsets of the various
27 * dimension components etc...
30 /**
31 * AdgDimStyle:
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
35 **/
38 #include "adg-dim-style.h"
39 #include "adg-dim-style-private.h"
40 #include "adg-font-style.h"
41 #include "adg-line-style.h"
42 #include "adg-intl.h"
43 #include "adg-util.h"
46 enum {
47 PROP_0,
48 PROP_MARKER1,
49 PROP_MARKER2,
50 PROP_COLOR_DRESS,
51 PROP_VALUE_DRESS,
52 PROP_MIN_DRESS,
53 PROP_MAX_DRESS,
54 PROP_LINE_DRESS,
55 PROP_FROM_OFFSET,
56 PROP_TO_OFFSET,
57 PROP_BEYOND,
58 PROP_BASELINE_SPACING,
59 PROP_LIMITS_SPACING,
60 PROP_QUOTE_SHIFT,
61 PROP_LIMITS_SHIFT,
62 PROP_NUMBER_FORMAT,
63 PROP_NUMBER_TAG
67 static void finalize (GObject *object);
68 static void get_property (GObject *object,
69 guint prop_id,
70 GValue *value,
71 GParamSpec *pspec);
72 static void set_property (GObject *object,
73 guint prop_id,
74 const GValue *value,
75 GParamSpec *pspec);
76 static void apply (AdgStyle *style,
77 cairo_t *cr);
78 static void set_limits_shift (AdgDimStyle *dim_style,
79 const AdgPair *shift);
80 static void set_number_format (AdgDimStyle *dim_style,
81 const gchar *format);
82 static void set_number_tag (AdgDimStyle *dim_style,
83 const gchar *tag);
84 static AdgMarker * marker_new (const AdgMarkerData
85 *marker_data);
86 static void use_marker (AdgMarkerData *marker_data,
87 AdgMarker *marker);
88 static void free_marker (AdgMarkerData *marker_data);
91 G_DEFINE_TYPE(AdgDimStyle, adg_dim_style, ADG_TYPE_STYLE);
94 static void
95 adg_dim_style_class_init(AdgDimStyleClass *klass)
97 GObjectClass *gobject_class;
98 AdgStyleClass *style_class;
99 GParamSpec *param;
101 gobject_class = (GObjectClass *) klass;
102 style_class = (AdgStyleClass *) klass;
104 g_type_class_add_private(klass, sizeof(AdgDimStylePrivate));
106 gobject_class->finalize = finalize;
107 gobject_class->get_property = get_property;
108 gobject_class->set_property = set_property;
110 style_class->apply = apply;
112 param = g_param_spec_object("marker1",
113 P_("First Marker"),
114 P_("The template entity to use as first marker"),
115 ADG_TYPE_MARKER,
116 G_PARAM_WRITABLE);
117 g_object_class_install_property(gobject_class, PROP_MARKER1, param);
119 param = g_param_spec_object("marker2",
120 P_("Second Marker"),
121 P_("The template entity to use as second marker"),
122 ADG_TYPE_MARKER,
123 G_PARAM_WRITABLE);
124 g_object_class_install_property(gobject_class, PROP_MARKER2, param);
126 param = adg_param_spec_dress("color-dress",
127 P_("Color Dress"),
128 P_("Color dress for the whole dimension"),
129 ADG_DRESS_COLOR_DIMENSION,
130 G_PARAM_READWRITE);
131 g_object_class_install_property(gobject_class, PROP_COLOR_DRESS, param);
133 param = adg_param_spec_dress("value-dress",
134 P_("Value Dress"),
135 P_("Font dress for the nominal value of the dimension"),
136 ADG_DRESS_TEXT_VALUE,
137 G_PARAM_READWRITE);
138 g_object_class_install_property(gobject_class, PROP_VALUE_DRESS, param);
140 param = adg_param_spec_dress("min-dress",
141 P_("Minimum Limit Dress"),
142 P_("Font dress for the lower limit value"),
143 ADG_DRESS_TEXT_LIMIT,
144 G_PARAM_READWRITE);
145 g_object_class_install_property(gobject_class, PROP_MIN_DRESS, param);
147 param = adg_param_spec_dress("max-dress",
148 P_("Maximum Limit Dress"),
149 P_("Font dress for the upper limit value"),
150 ADG_DRESS_TEXT_LIMIT,
151 G_PARAM_READWRITE);
152 g_object_class_install_property(gobject_class, PROP_MAX_DRESS, param);
154 param = adg_param_spec_dress("line-dress",
155 P_("Line Dress"),
156 P_("Line dress for the baseline and the extension lines"),
157 ADG_DRESS_LINE_DIMENSION,
158 G_PARAM_READWRITE);
159 g_object_class_install_property(gobject_class, PROP_LINE_DRESS, param);
161 param = g_param_spec_double("from-offset",
162 P_("From Offset"),
163 P_("Offset (in global space) of the extension lines from the path to the quote"),
164 0, G_MAXDOUBLE, 5,
165 G_PARAM_READWRITE);
166 g_object_class_install_property(gobject_class, PROP_FROM_OFFSET, param);
168 param = g_param_spec_double("to-offset",
169 P_("To Offset"),
170 P_("How many extend (in global space) the extension lines after hitting the baseline"),
171 0, G_MAXDOUBLE, 5,
172 G_PARAM_READWRITE);
173 g_object_class_install_property(gobject_class, PROP_TO_OFFSET, param);
175 param = g_param_spec_double("beyond",
176 P_("Beyond Length"),
177 P_("How much the baseline should be extended (in global space) beyond the extension lines on dimensions with outside markers"),
178 0, G_MAXDOUBLE, 20,
179 G_PARAM_READWRITE);
180 g_object_class_install_property(gobject_class, PROP_BEYOND, param);
182 param = g_param_spec_double("baseline-spacing",
183 P_("Baseline Spacing"),
184 P_("Distance between two consecutive baselines while stacking dimensions"),
185 0, G_MAXDOUBLE, 30,
186 G_PARAM_READWRITE);
187 g_object_class_install_property(gobject_class, PROP_BASELINE_SPACING, param);
189 param = g_param_spec_double("limits-spacing",
190 P_("Limits Spacing"),
191 P_("Distance between limits/tolerances"),
192 0, G_MAXDOUBLE, 2,
193 G_PARAM_READWRITE);
194 g_object_class_install_property(gobject_class, PROP_LIMITS_SPACING, param);
196 param = g_param_spec_boxed("quote-shift",
197 P_("Quote Shift"),
198 P_("Used to specify a smooth displacement (in global space) of the quote by taking as reference the perfect compact position (the middle of the baseline on common linear dimension, for instance)"),
199 ADG_TYPE_PAIR, G_PARAM_READWRITE);
200 g_object_class_install_property(gobject_class, PROP_QUOTE_SHIFT, param);
202 param = g_param_spec_boxed("limits-shift",
203 P_("Limits Shift"),
204 P_("Used to specify a smooth displacement (in global space) for the limits/tolerances by taking as reference the perfect compact position"),
205 ADG_TYPE_PAIR, G_PARAM_READWRITE);
206 g_object_class_install_property(gobject_class, PROP_LIMITS_SHIFT,
207 param);
209 param = g_param_spec_string("number-format",
210 P_("Number Format"),
211 P_("The format (in printf style) of the numeric component of the basic value"),
212 "%-.7g", G_PARAM_READWRITE);
213 g_object_class_install_property(gobject_class, PROP_NUMBER_FORMAT,
214 param);
216 param = g_param_spec_string("number-tag",
217 P_("Number Tag"),
218 P_("The tag to substitute inside the basic value pattern"),
219 "<>", G_PARAM_READWRITE);
220 g_object_class_install_property(gobject_class, PROP_NUMBER_TAG, param);
223 static void
224 adg_dim_style_init(AdgDimStyle *dim_style)
226 AdgDimStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(dim_style,
227 ADG_TYPE_DIM_STYLE,
228 AdgDimStylePrivate);
230 data->marker1.type = 0;
231 data->marker1.n_parameters = 0;
232 data->marker1.parameters = NULL;
233 data->marker2.type = 0;
234 data->marker2.n_parameters = 0;
235 data->marker2.parameters = NULL;
236 data->color_dress = ADG_DRESS_COLOR_DIMENSION;
237 data->value_dress = ADG_DRESS_TEXT_VALUE;
238 data->min_dress = ADG_DRESS_TEXT_LIMIT;
239 data->max_dress = ADG_DRESS_TEXT_LIMIT;
240 data->line_dress = ADG_DRESS_LINE_DIMENSION;
241 data->marker_dress = ADG_DRESS_UNDEFINED;
242 data->from_offset = 6;
243 data->to_offset = 6;
244 data->beyond = 20;
245 data->baseline_spacing = 30;
246 data->limits_spacing = 1;
247 data->quote_shift.x = 0;
248 data->quote_shift.y = -4;
249 data->limits_shift.x = +2;
250 data->limits_shift.y = -2;
251 data->number_format = g_strdup("%-.7g");
252 data->number_tag = g_strdup("<>");
254 dim_style->data = data;
257 static void
258 finalize(GObject *object)
260 AdgDimStylePrivate *data = ((AdgDimStyle *) object)->data;
262 free_marker(&data->marker1);
263 free_marker(&data->marker2);
265 g_free(data->number_format);
266 data->number_format = NULL;
268 g_free(data->number_tag);
269 data->number_tag = NULL;
272 static void
273 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
275 AdgDimStylePrivate *data = ((AdgDimStyle *) object)->data;
277 switch (prop_id) {
278 case PROP_COLOR_DRESS:
279 g_value_set_int(value, data->color_dress);
280 break;
281 case PROP_VALUE_DRESS:
282 g_value_set_int(value, data->value_dress);
283 break;
284 case PROP_MIN_DRESS:
285 g_value_set_int(value, data->min_dress);
286 break;
287 case PROP_MAX_DRESS:
288 g_value_set_int(value, data->max_dress);
289 break;
290 case PROP_LINE_DRESS:
291 g_value_set_int(value, data->line_dress);
292 break;
293 case PROP_FROM_OFFSET:
294 g_value_set_double(value, data->from_offset);
295 break;
296 case PROP_TO_OFFSET:
297 g_value_set_double(value, data->to_offset);
298 break;
299 case PROP_BEYOND:
300 g_value_set_double(value, data->beyond);
301 break;
302 case PROP_BASELINE_SPACING:
303 g_value_set_double(value, data->baseline_spacing);
304 break;
305 case PROP_LIMITS_SPACING:
306 g_value_set_double(value, data->limits_spacing);
307 break;
308 case PROP_QUOTE_SHIFT:
309 g_value_set_boxed(value, &data->quote_shift);
310 break;
311 case PROP_LIMITS_SHIFT:
312 g_value_set_boxed(value, &data->limits_shift);
313 break;
314 case PROP_NUMBER_FORMAT:
315 g_value_set_string(value, data->number_format);
316 break;
317 case PROP_NUMBER_TAG:
318 g_value_set_string(value, data->number_tag);
319 break;
320 default:
321 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
322 break;
326 static void
327 set_property(GObject *object,
328 guint prop_id, const GValue *value, GParamSpec *pspec)
330 AdgDimStyle *dim_style;
331 AdgDimStylePrivate *data;
333 dim_style = (AdgDimStyle *) object;
334 data = dim_style->data;
336 switch (prop_id) {
337 case PROP_MARKER1:
338 use_marker(&data->marker1, g_value_get_object(value));
339 break;
340 case PROP_MARKER2:
341 use_marker(&data->marker2, g_value_get_object(value));
342 break;
343 case PROP_COLOR_DRESS:
344 adg_dress_set(&data->color_dress, g_value_get_int(value));
345 break;
346 case PROP_VALUE_DRESS:
347 adg_dress_set(&data->value_dress, g_value_get_int(value));
348 break;
349 case PROP_MIN_DRESS:
350 adg_dress_set(&data->min_dress, g_value_get_int(value));
351 break;
352 case PROP_MAX_DRESS:
353 adg_dress_set(&data->max_dress, g_value_get_int(value));
354 break;
355 case PROP_LINE_DRESS:
356 adg_dress_set(&data->line_dress, g_value_get_int(value));
357 break;
358 case PROP_FROM_OFFSET:
359 data->from_offset = g_value_get_double(value);
360 break;
361 case PROP_TO_OFFSET:
362 data->to_offset = g_value_get_double(value);
363 break;
364 case PROP_BEYOND:
365 data->beyond = g_value_get_double(value);
366 break;
367 case PROP_BASELINE_SPACING:
368 data->baseline_spacing = g_value_get_double(value);
369 break;
370 case PROP_LIMITS_SPACING:
371 data->limits_spacing = g_value_get_double(value);
372 break;
373 case PROP_QUOTE_SHIFT:
374 cpml_pair_copy(&data->quote_shift, g_value_get_boxed(value));
375 break;
376 case PROP_LIMITS_SHIFT:
377 set_limits_shift(dim_style, g_value_get_boxed(value));
378 break;
379 case PROP_NUMBER_FORMAT:
380 set_number_format(dim_style, g_value_get_string(value));
381 break;
382 case PROP_NUMBER_TAG:
383 set_number_tag(dim_style, g_value_get_string(value));
384 break;
385 default:
386 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
387 break;
393 * adg_dim_style_new:
395 * Constructs a new dimension style initialized with default params.
397 * Returns: a new dimension style
399 AdgStyle *
400 adg_dim_style_new(void)
402 return g_object_new(ADG_TYPE_DIM_STYLE, NULL);
406 * adg_dim_style_marker1_new:
407 * @dim_style: an #AdgDimStyle
409 * Creates a new #AdgMarker entity accordling to the template marker
410 * stored with the #AdgDimStyle:marker1 property of @dim_style.
412 * Returns: a newly created #AdgMarker derived entity or %NULL if
413 * @dim_style has the #AdgDimStyle:marker1 property unset
415 AdgMarker *
416 adg_dim_style_marker1_new(AdgDimStyle *dim_style)
418 AdgDimStylePrivate *data;
420 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
422 data = dim_style->data;
424 return marker_new(&data->marker1);
428 * adg_dim_style_marker2_new:
429 * @dim_style: an #AdgDimStyle
431 * Creates a new #AdgMarker entity accordling to the template marker
432 * stored with the #AdgDimStyle:marker2 property of @dim_style.
434 * Returns: a newly created #AdgMarker derived entity or %NULL if
435 * @dim_style has the #AdgDimStyle:marker2 property unset
437 AdgMarker *
438 adg_dim_style_marker2_new(AdgDimStyle *dim_style)
440 AdgDimStylePrivate *data;
442 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
444 data = dim_style->data;
446 return marker_new(&data->marker2);
450 * adg_dim_style_use_marker1:
451 * @dim_style: an #AdgStyle
452 * @marker: an #AdgMarker derived entity
454 * Uses @marker as entity template to generate a new marker entity
455 * when a call to adg_dim_style_marker1_new() is made.
457 * This method duplicates internally the property values of @marker,
458 * so any further change to @marker does not affect @dim_style anymore.
459 * This also means @marker could be destroyed because @dim_style only
460 * uses its property values and does not add any references to @marker.
462 void
463 adg_dim_style_use_marker1(AdgDimStyle *dim_style, AdgMarker *marker)
465 AdgDimStylePrivate *data;
467 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
468 g_return_if_fail(marker == NULL || ADG_IS_MARKER(marker));
470 data = dim_style->data;
472 use_marker(&data->marker1, marker);
473 g_object_notify((GObject *) dim_style, "marker1");
477 * adg_dim_style_use_marker2:
478 * @dim_style: an #AdgStyle
479 * @marker: an #AdgMarker derived entity
481 * Uses @marker as entity template to generate a new marker entity
482 * when a call to adg_dim_style_marker2_new() is made.
484 * This method duplicates internally the property values of @marker,
485 * so any further change to @marker does not affect @dim_style anymore.
486 * This also means @marker could be destroyed because @dim_style only
487 * uses its property values and does not add any references to @marker.
489 void
490 adg_dim_style_use_marker2(AdgDimStyle *dim_style, AdgMarker *marker)
492 AdgDimStylePrivate *data;
494 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
495 g_return_if_fail(marker == NULL || ADG_IS_MARKER(marker));
497 data = dim_style->data;
499 use_marker(&data->marker2, marker);
500 g_object_notify((GObject *) dim_style, "marker2");
504 * adg_dim_style_get_color_dress:
505 * @dim_style: an #AdgDimStyle object
507 * Gets the @dim_style color dress to be used.
509 * Returns: the color dress
511 AdgDress
512 adg_dim_style_get_color_dress(AdgDimStyle *dim_style)
514 AdgDimStylePrivate *data;
516 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
518 data = dim_style->data;
520 return data->color_dress;
524 * adg_dim_style_set_color_dress:
525 * @dim_style: an #AdgDimStyle object
526 * @dress: the new color dress
528 * Sets a new color dress on @dim_style.
530 void
531 adg_dim_style_set_color_dress(AdgDimStyle *dim_style, AdgDress dress)
533 AdgDimStylePrivate *data;
535 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
537 data = dim_style->data;
539 if (adg_dress_set(&data->color_dress, dress))
540 g_object_notify((GObject *) dim_style, "color-dress");
544 * adg_dim_style_get_value_dress:
545 * @dim_style: an #AdgDimStyle object
547 * Gets the @dim_style dress to be used for the basic value.
549 * Returns: the basic value dress
551 AdgDress
552 adg_dim_style_get_value_dress(AdgDimStyle *dim_style)
554 AdgDimStylePrivate *data;
556 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
558 data = dim_style->data;
560 return data->value_dress;
564 * adg_dim_style_set_value_dress:
565 * @dim_style: an #AdgDimStyle object
566 * @dress: the new basic value font style
568 * Sets a new dress on @dim_style for the basic value.
570 void
571 adg_dim_style_set_value_dress(AdgDimStyle *dim_style, AdgDress dress)
573 AdgDimStylePrivate *data;
575 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
577 data = dim_style->data;
579 if (adg_dress_set(&data->value_dress, dress))
580 g_object_notify((GObject *) dim_style, "value-dress");
584 * adg_dim_style_get_min_dress:
585 * @dim_style: an #AdgDimStyle object
587 * Gets the @dim_style dress to be used for the lower limit.
589 * Returns: the lower limit dress
591 AdgDress
592 adg_dim_style_get_min_dress(AdgDimStyle *dim_style)
594 AdgDimStylePrivate *data;
596 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
598 data = dim_style->data;
600 return data->min_dress;
604 * adg_dim_style_set_min_dress:
605 * @dim_style: an #AdgDimStyle object
606 * @dress: the new lower limit dress
608 * Sets a new dress on @dim_style for the lower limit value.
610 void
611 adg_dim_style_set_min_dress(AdgDimStyle *dim_style, AdgDress dress)
613 AdgDimStylePrivate *data;
615 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
617 data = dim_style->data;
619 if (adg_dress_set(&data->min_dress, dress))
620 g_object_notify((GObject *) dim_style, "min-dress");
624 * adg_dim_style_get_max_dress:
625 * @dim_style: an #AdgDimStyle object
627 * Gets the @dim_style dress to be used for the upper limit.
629 * Returns: the upper limit dress
631 AdgDress
632 adg_dim_style_get_max_dress(AdgDimStyle *dim_style)
634 AdgDimStylePrivate *data;
636 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
638 data = dim_style->data;
640 return data->max_dress;
644 * adg_dim_style_set_max_dress:
645 * @dim_style: an #AdgDimStyle object
646 * @dress: the new upper limit dress
648 * Sets a new dress on @dim_style for the upper limit value.
650 void
651 adg_dim_style_set_max_dress(AdgDimStyle *dim_style, AdgDress dress)
653 AdgDimStylePrivate *data;
655 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
657 data = dim_style->data;
659 if (adg_dress_set(&data->max_dress, dress))
660 g_object_notify((GObject *) dim_style, "max-dress");
664 * adg_dim_style_get_line_dress:
665 * @dim_style: an #AdgDimStyle object
667 * Gets the @dim_style dress to be used for rendering the baseline and
668 * the extension lines.
670 * Returns: the line dress
672 AdgDress
673 adg_dim_style_get_line_dress(AdgDimStyle *dim_style)
675 AdgDimStylePrivate *data;
677 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
679 data = dim_style->data;
681 return data->line_dress;
685 * adg_dim_style_set_line_dress:
686 * @dim_style: an #AdgDimStyle object
687 * @dress: the new line dress
689 * Sets a new line dress on @dim_style.
691 void
692 adg_dim_style_set_line_dress(AdgDimStyle *dim_style, AdgDress dress)
694 AdgDimStylePrivate *data;
696 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
698 data = dim_style->data;
700 if (adg_dress_set(&data->line_dress, dress))
701 g_object_notify((GObject *) dim_style, "line-dress");
705 * adg_dim_style_get_from_offset:
706 * @dim_style: an #AdgDimStyle object
708 * Gets the distance (in global space) the extension lines must keep from the
709 * sensed points.
711 * Returns: the requested distance
713 gdouble
714 adg_dim_style_get_from_offset(AdgDimStyle *dim_style)
716 AdgDimStylePrivate *data;
718 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
720 data = dim_style->data;
722 return data->from_offset;
726 * adg_dim_style_set_from_offset:
727 * @dim_style: an #AdgDimStyle object
728 * @offset: the new offset
730 * Sets a new "from-offset" value.
732 void
733 adg_dim_style_set_from_offset(AdgDimStyle *dim_style, gdouble offset)
735 AdgDimStylePrivate *data;
737 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
739 data = dim_style->data;
740 data->from_offset = offset;
742 g_object_notify((GObject *) dim_style, "from-offset");
746 * adg_dim_style_get_to_offset:
747 * @dim_style: an #AdgDimStyle object
749 * Gets how much (in global space) the extension lines must extend after
750 * crossing the baseline.
752 * Returns: the requested distance
754 gdouble
755 adg_dim_style_get_to_offset(AdgDimStyle *dim_style)
757 AdgDimStylePrivate *data;
759 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
761 data = dim_style->data;
763 return data->to_offset;
767 * adg_dim_style_set_to_offset:
768 * @dim_style: an #AdgDimStyle object
769 * @offset: the new offset
771 * Sets a new "to-offset" value.
773 void
774 adg_dim_style_set_to_offset(AdgDimStyle *dim_style, gdouble offset)
776 AdgDimStylePrivate *data;
778 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
780 data = dim_style->data;
781 data->to_offset = offset;
783 g_object_notify((GObject *) dim_style, "to-offset");
787 * adg_dim_style_get_beyond:
788 * @dim_style: an #AdgDimStyle object
790 * Gets how much (in global space) the baseline should extend beyond
791 * the extension lines on dimension with outside markers.
793 * Returns: the requested beyond length
795 gdouble
796 adg_dim_style_get_beyond(AdgDimStyle *dim_style)
798 AdgDimStylePrivate *data;
800 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
802 data = dim_style->data;
804 return data->beyond;
808 * adg_dim_style_set_beyond:
809 * @dim_style: an #AdgDimStyle object
810 * @length: the new length
812 * Sets a new "beyond" value.
814 void
815 adg_dim_style_set_beyond(AdgDimStyle *dim_style, gdouble length)
817 AdgDimStylePrivate *data;
819 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
821 data = dim_style->data;
822 data->beyond = length;
824 g_object_notify((GObject *) dim_style, "beyond");
828 * adg_dim_style_get_baseline_spacing:
829 * @dim_style: an #AdgDimStyle object
831 * Gets the distance between two consecutive baselines
832 * while stacking dimensions.
834 * Returns: the requested spacing
836 gdouble
837 adg_dim_style_get_baseline_spacing(AdgDimStyle *dim_style)
839 AdgDimStylePrivate *data;
841 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
843 data = dim_style->data;
845 return data->baseline_spacing;
849 * adg_dim_style_set_baseline_spacing:
850 * @dim_style: an #AdgDimStyle object
851 * @spacing: the new spacing
853 * Sets a new "baseline-spacing" value.
855 void
856 adg_dim_style_set_baseline_spacing(AdgDimStyle *dim_style, gdouble spacing)
858 AdgDimStylePrivate *data;
860 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
862 data = dim_style->data;
863 data->baseline_spacing = spacing;
865 g_object_notify((GObject *) dim_style, "baseline-spacing");
869 * adg_dim_style_get_limits_spacing:
870 * @dim_style: an #AdgDimStyle object
872 * Gets the distance (in global space) between the limits/tolerances.
874 * Returns: the requested spacing
876 gdouble
877 adg_dim_style_get_limits_spacing(AdgDimStyle *dim_style)
879 AdgDimStylePrivate *data;
881 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
883 data = dim_style->data;
885 return data->limits_spacing;
889 * adg_dim_style_set_limits_spacing:
890 * @dim_style: an #AdgDimStyle object
891 * @spacing: the new spacing
893 * Sets a new #AdgDimStyle:limits-spacing value.
895 void
896 adg_dim_style_set_limits_spacing(AdgDimStyle *dim_style, gdouble spacing)
898 AdgDimStylePrivate *data;
900 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
902 data = dim_style->data;
903 data->limits_spacing = spacing;
905 g_object_notify((GObject *) dim_style, "limits-spacing");
909 * adg_dim_style_get_quote_shift:
910 * @dim_style: an #AdgDimStyle object
912 * Gets the smooth displacement of the quote. The returned pointer refers
913 * to an internal allocated struct and must not be modified or freed.
915 * Returns: the requested shift
917 const AdgPair *
918 adg_dim_style_get_quote_shift(AdgDimStyle *dim_style)
920 AdgDimStylePrivate *data;
922 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
924 data = dim_style->data;
926 return &data->quote_shift;
930 * adg_dim_style_set_quote_shift:
931 * @dim_style: an #AdgDimStyle object
932 * @shift: the new displacement
934 * Sets a new "quote-shift" value.
936 void
937 adg_dim_style_set_quote_shift(AdgDimStyle *dim_style, const AdgPair *shift)
939 AdgDimStylePrivate *data;
941 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
943 data = dim_style->data;
944 cpml_pair_copy(&data->quote_shift, shift);
946 g_object_notify((GObject *) dim_style, "quote-shift");
950 * adg_dim_style_get_limits_shift:
951 * @dim_style: an #AdgDimStyle object
953 * Gets the smooth displacement for the limits. The returned pointer
954 * refers to an internal allocated struct and must not be modified or freed.
956 * Returns: the requested shift
958 const AdgPair *
959 adg_dim_style_get_limits_shift(AdgDimStyle *dim_style)
961 AdgDimStylePrivate *data;
963 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
965 data = dim_style->data;
967 return &data->limits_shift;
971 * adg_dim_style_set_limits_shift:
972 * @dim_style: an #AdgDimStyle object
973 * @shift: the new displacement
975 * Sets a new #AdgDimStyle:limits-shift value.
977 void
978 adg_dim_style_set_limits_shift(AdgDimStyle *dim_style, const AdgPair *shift)
980 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
982 set_limits_shift(dim_style, shift);
983 g_object_notify((GObject *) dim_style, "limits-shift");
987 * adg_dim_style_get_number_format:
988 * @dim_style: an #AdgDimStyle object
990 * Gets the number format (in printf style) of this quoting style. The
991 * returned pointer refers to internally managed text that must not be
992 * modified or freed.
994 * Returns: the requested format
996 const gchar *
997 adg_dim_style_get_number_format(AdgDimStyle *dim_style)
999 AdgDimStylePrivate *data;
1001 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
1003 data = dim_style->data;
1005 return data->number_format;
1009 * adg_dim_style_set_number_format:
1010 * @dim_style: an #AdgDimStyle object
1011 * @format: the new format to adopt
1013 * Sets a new "number-format" value.
1015 void
1016 adg_dim_style_set_number_format(AdgDimStyle *dim_style, const gchar *format)
1018 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
1020 set_number_format(dim_style, format);
1021 g_object_notify((GObject *) dim_style, "number-format");
1025 * adg_dim_style_get_number_tag:
1026 * @dim_style: an #AdgDimStyle object
1028 * Gets the number tag to substitute while building the basic value. The
1029 * returned pointer refers to internally managed text that must not be
1030 * modified or freed.
1032 * Returns: the requested tag
1034 const gchar *
1035 adg_dim_style_get_number_tag(AdgDimStyle *dim_style)
1037 AdgDimStylePrivate *data;
1039 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
1041 data = dim_style->data;
1043 return data->number_tag;
1047 * adg_dim_style_set_number_tag:
1048 * @dim_style: an #AdgDimStyle object
1049 * @tag: the new tag
1051 * Sets a new "number-tag" value.
1053 void
1054 adg_dim_style_set_number_tag(AdgDimStyle *dim_style, const gchar *tag)
1056 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
1058 set_number_tag(dim_style, tag);
1059 g_object_notify((GObject *) dim_style, "number-tag");
1063 static void
1064 apply(AdgStyle *style, cairo_t *cr)
1068 static void
1069 set_limits_shift(AdgDimStyle *dim_style, const AdgPair *shift)
1071 AdgDimStylePrivate *data = dim_style->data;
1073 cpml_pair_copy(&data->limits_shift, shift);
1076 static void
1077 set_number_format(AdgDimStyle *dim_style, const gchar *format)
1079 AdgDimStylePrivate *data = dim_style->data;
1081 g_free(data->number_format);
1082 data->number_format = g_strdup(format);
1085 static void
1086 set_number_tag(AdgDimStyle *dim_style, const gchar *tag)
1088 AdgDimStylePrivate *data = dim_style->data;
1090 g_free(data->number_tag);
1091 data->number_tag = g_strdup(tag);
1094 static AdgMarker *
1095 marker_new(const AdgMarkerData *marker_data)
1097 if (marker_data->type == 0)
1098 return NULL;
1100 return g_object_newv(marker_data->type,
1101 marker_data->n_parameters,
1102 marker_data->parameters);
1105 static void
1106 use_marker(AdgMarkerData *marker_data, AdgMarker *marker)
1108 GObject *object;
1109 GParamSpec **specs;
1110 GParamSpec *spec;
1111 GParameter *parameter;
1112 guint n;
1114 /* Free the previous marker data, if any */
1115 free_marker(marker_data);
1117 if (marker == NULL)
1118 return;
1120 object = (GObject *) marker;
1121 specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(marker),
1122 &marker_data->n_parameters);
1124 marker_data->type = G_TYPE_FROM_INSTANCE(marker);
1125 marker_data->parameters = g_new0(GParameter, marker_data->n_parameters);
1127 for (n = 0; n < marker_data->n_parameters; ++n) {
1128 spec = specs[n];
1129 parameter = &marker_data->parameters[n];
1131 /* Using intern strings because GParameter:name is const.
1132 * GObject properties are internally managed using non-static
1133 * GQuark, so g_intern_string() is the way to go */
1134 parameter->name = g_intern_string(spec->name);
1136 g_value_init(&parameter->value, spec->value_type);
1137 g_object_get_property(object, spec->name, &parameter->value);
1140 g_free(specs);
1143 static void
1144 free_marker(AdgMarkerData *marker_data)
1146 guint n;
1148 for (n = 0; n < marker_data->n_parameters; ++n)
1149 g_value_unset(&marker_data->parameters[n].value);
1151 marker_data->type = 0;
1152 marker_data->n_parameters = 0;
1153 marker_data->parameters = NULL;