[AdgLogo] Redesigned logo to better fit a cell
[adg.git] / adg / adg-dim-style.c
blobabcf7e49ba95519da11f45877f93b1de7c2da7bd
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-dress-builtins.h"
41 #include "adg-font-style.h"
42 #include "adg-line-style.h"
43 #include "adg-intl.h"
44 #include "adg-util.h"
47 enum {
48 PROP_0,
49 PROP_MARKER1,
50 PROP_MARKER2,
51 PROP_COLOR_DRESS,
52 PROP_VALUE_DRESS,
53 PROP_MIN_DRESS,
54 PROP_MAX_DRESS,
55 PROP_LINE_DRESS,
56 PROP_FROM_OFFSET,
57 PROP_TO_OFFSET,
58 PROP_BEYOND,
59 PROP_BASELINE_SPACING,
60 PROP_LIMITS_SPACING,
61 PROP_QUOTE_SHIFT,
62 PROP_LIMITS_SHIFT,
63 PROP_NUMBER_FORMAT,
64 PROP_NUMBER_TAG
68 static void finalize (GObject *object);
69 static void get_property (GObject *object,
70 guint prop_id,
71 GValue *value,
72 GParamSpec *pspec);
73 static void set_property (GObject *object,
74 guint prop_id,
75 const GValue *value,
76 GParamSpec *pspec);
77 static void apply (AdgStyle *style,
78 AdgEntity *entity,
79 cairo_t *cr);
80 static void set_limits_shift (AdgDimStyle *dim_style,
81 const AdgPair *shift);
82 static void set_number_format (AdgDimStyle *dim_style,
83 const gchar *format);
84 static void set_number_tag (AdgDimStyle *dim_style,
85 const gchar *tag);
86 static AdgMarker * marker_new (const AdgMarkerData
87 *marker_data);
88 static void use_marker (AdgMarkerData *marker_data,
89 AdgMarker *marker);
90 static void free_marker (AdgMarkerData *marker_data);
93 G_DEFINE_TYPE(AdgDimStyle, adg_dim_style, ADG_TYPE_STYLE);
96 static void
97 adg_dim_style_class_init(AdgDimStyleClass *klass)
99 GObjectClass *gobject_class;
100 AdgStyleClass *style_class;
101 GParamSpec *param;
103 gobject_class = (GObjectClass *) klass;
104 style_class = (AdgStyleClass *) klass;
106 g_type_class_add_private(klass, sizeof(AdgDimStylePrivate));
108 gobject_class->finalize = finalize;
109 gobject_class->get_property = get_property;
110 gobject_class->set_property = set_property;
112 style_class->apply = apply;
114 param = g_param_spec_object("marker1",
115 P_("First Marker"),
116 P_("The template entity to use as first marker"),
117 ADG_TYPE_MARKER,
118 G_PARAM_WRITABLE);
119 g_object_class_install_property(gobject_class, PROP_MARKER1, param);
121 param = g_param_spec_object("marker2",
122 P_("Second Marker"),
123 P_("The template entity to use as second marker"),
124 ADG_TYPE_MARKER,
125 G_PARAM_WRITABLE);
126 g_object_class_install_property(gobject_class, PROP_MARKER2, param);
128 param = adg_param_spec_dress("color-dress",
129 P_("Color Dress"),
130 P_("Color dress for the whole dimension"),
131 ADG_DRESS_COLOR_DIMENSION,
132 G_PARAM_READWRITE);
133 g_object_class_install_property(gobject_class, PROP_COLOR_DRESS, param);
135 param = adg_param_spec_dress("value-dress",
136 P_("Value Dress"),
137 P_("Font dress for the nominal value of the dimension"),
138 ADG_DRESS_TEXT_VALUE,
139 G_PARAM_READWRITE);
140 g_object_class_install_property(gobject_class, PROP_VALUE_DRESS, param);
142 param = adg_param_spec_dress("min-dress",
143 P_("Minimum Limit Dress"),
144 P_("Font dress for the lower limit value"),
145 ADG_DRESS_TEXT_LIMIT,
146 G_PARAM_READWRITE);
147 g_object_class_install_property(gobject_class, PROP_MIN_DRESS, param);
149 param = adg_param_spec_dress("max-dress",
150 P_("Maximum Limit Dress"),
151 P_("Font dress for the upper limit value"),
152 ADG_DRESS_TEXT_LIMIT,
153 G_PARAM_READWRITE);
154 g_object_class_install_property(gobject_class, PROP_MAX_DRESS, param);
156 param = adg_param_spec_dress("line-dress",
157 P_("Line Dress"),
158 P_("Line dress for the baseline and the extension lines"),
159 ADG_DRESS_LINE_THINNER,
160 G_PARAM_READWRITE);
161 g_object_class_install_property(gobject_class, PROP_LINE_DRESS, param);
163 param = g_param_spec_double("from-offset",
164 P_("From Offset"),
165 P_("Offset (in global space) of the extension lines from the path to the quote"),
166 0, G_MAXDOUBLE, 5,
167 G_PARAM_READWRITE);
168 g_object_class_install_property(gobject_class, PROP_FROM_OFFSET, param);
170 param = g_param_spec_double("to-offset",
171 P_("To Offset"),
172 P_("How many extend (in global space) the extension lines after hitting the baseline"),
173 0, G_MAXDOUBLE, 5,
174 G_PARAM_READWRITE);
175 g_object_class_install_property(gobject_class, PROP_TO_OFFSET, param);
177 param = g_param_spec_double("beyond",
178 P_("Beyond Length"),
179 P_("How much the baseline should be extended (in global space) beyond the extension lines on dimensions with outside markers"),
180 0, G_MAXDOUBLE, 20,
181 G_PARAM_READWRITE);
182 g_object_class_install_property(gobject_class, PROP_BEYOND, param);
184 param = g_param_spec_double("baseline-spacing",
185 P_("Baseline Spacing"),
186 P_("Distance between two consecutive baselines while stacking dimensions"),
187 0, G_MAXDOUBLE, 30,
188 G_PARAM_READWRITE);
189 g_object_class_install_property(gobject_class, PROP_BASELINE_SPACING, param);
191 param = g_param_spec_double("limits-spacing",
192 P_("Limits Spacing"),
193 P_("Distance between limits/tolerances"),
194 0, G_MAXDOUBLE, 2,
195 G_PARAM_READWRITE);
196 g_object_class_install_property(gobject_class, PROP_LIMITS_SPACING, param);
198 param = g_param_spec_boxed("quote-shift",
199 P_("Quote Shift"),
200 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)"),
201 ADG_TYPE_PAIR, G_PARAM_READWRITE);
202 g_object_class_install_property(gobject_class, PROP_QUOTE_SHIFT, param);
204 param = g_param_spec_boxed("limits-shift",
205 P_("Limits Shift"),
206 P_("Used to specify a smooth displacement (in global space) for the limits/tolerances by taking as reference the perfect compact position"),
207 ADG_TYPE_PAIR, G_PARAM_READWRITE);
208 g_object_class_install_property(gobject_class, PROP_LIMITS_SHIFT,
209 param);
211 param = g_param_spec_string("number-format",
212 P_("Number Format"),
213 P_("The format (in printf style) of the numeric component of the basic value"),
214 "%-.7g", G_PARAM_READWRITE);
215 g_object_class_install_property(gobject_class, PROP_NUMBER_FORMAT,
216 param);
218 param = g_param_spec_string("number-tag",
219 P_("Number Tag"),
220 P_("The tag to substitute inside the basic value pattern"),
221 "<>", G_PARAM_READWRITE);
222 g_object_class_install_property(gobject_class, PROP_NUMBER_TAG, param);
225 static void
226 adg_dim_style_init(AdgDimStyle *dim_style)
228 AdgDimStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(dim_style,
229 ADG_TYPE_DIM_STYLE,
230 AdgDimStylePrivate);
232 data->marker1.type = 0;
233 data->marker1.n_parameters = 0;
234 data->marker1.parameters = NULL;
235 data->marker2.type = 0;
236 data->marker2.n_parameters = 0;
237 data->marker2.parameters = NULL;
238 data->color_dress = ADG_DRESS_COLOR_DIMENSION;
239 data->value_dress = ADG_DRESS_TEXT_VALUE;
240 data->min_dress = ADG_DRESS_TEXT_LIMIT;
241 data->max_dress = ADG_DRESS_TEXT_LIMIT;
242 data->line_dress = ADG_DRESS_LINE_THINNER;
243 data->marker_dress = ADG_DRESS_UNDEFINED;
244 data->from_offset = 6;
245 data->to_offset = 6;
246 data->beyond = 20;
247 data->baseline_spacing = 30;
248 data->limits_spacing = 1;
249 data->quote_shift.x = 0;
250 data->quote_shift.y = -4;
251 data->limits_shift.x = +2;
252 data->limits_shift.y = -2;
253 data->number_format = g_strdup("%-.7g");
254 data->number_tag = g_strdup("<>");
256 dim_style->data = data;
259 static void
260 finalize(GObject *object)
262 AdgDimStylePrivate *data = ((AdgDimStyle *) object)->data;
264 free_marker(&data->marker1);
265 free_marker(&data->marker2);
267 g_free(data->number_format);
268 data->number_format = NULL;
270 g_free(data->number_tag);
271 data->number_tag = NULL;
274 static void
275 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
277 AdgDimStylePrivate *data = ((AdgDimStyle *) object)->data;
279 switch (prop_id) {
280 case PROP_COLOR_DRESS:
281 g_value_set_int(value, data->color_dress);
282 break;
283 case PROP_VALUE_DRESS:
284 g_value_set_int(value, data->value_dress);
285 break;
286 case PROP_MIN_DRESS:
287 g_value_set_int(value, data->min_dress);
288 break;
289 case PROP_MAX_DRESS:
290 g_value_set_int(value, data->max_dress);
291 break;
292 case PROP_LINE_DRESS:
293 g_value_set_int(value, data->line_dress);
294 break;
295 case PROP_FROM_OFFSET:
296 g_value_set_double(value, data->from_offset);
297 break;
298 case PROP_TO_OFFSET:
299 g_value_set_double(value, data->to_offset);
300 break;
301 case PROP_BEYOND:
302 g_value_set_double(value, data->beyond);
303 break;
304 case PROP_BASELINE_SPACING:
305 g_value_set_double(value, data->baseline_spacing);
306 break;
307 case PROP_LIMITS_SPACING:
308 g_value_set_double(value, data->limits_spacing);
309 break;
310 case PROP_QUOTE_SHIFT:
311 g_value_set_boxed(value, &data->quote_shift);
312 break;
313 case PROP_LIMITS_SHIFT:
314 g_value_set_boxed(value, &data->limits_shift);
315 break;
316 case PROP_NUMBER_FORMAT:
317 g_value_set_string(value, data->number_format);
318 break;
319 case PROP_NUMBER_TAG:
320 g_value_set_string(value, data->number_tag);
321 break;
322 default:
323 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
324 break;
328 static void
329 set_property(GObject *object,
330 guint prop_id, const GValue *value, GParamSpec *pspec)
332 AdgDimStyle *dim_style;
333 AdgDimStylePrivate *data;
335 dim_style = (AdgDimStyle *) object;
336 data = dim_style->data;
338 switch (prop_id) {
339 case PROP_MARKER1:
340 use_marker(&data->marker1, g_value_get_object(value));
341 break;
342 case PROP_MARKER2:
343 use_marker(&data->marker2, g_value_get_object(value));
344 break;
345 case PROP_COLOR_DRESS:
346 adg_dress_set(&data->color_dress, g_value_get_int(value));
347 break;
348 case PROP_VALUE_DRESS:
349 adg_dress_set(&data->value_dress, g_value_get_int(value));
350 break;
351 case PROP_MIN_DRESS:
352 adg_dress_set(&data->min_dress, g_value_get_int(value));
353 break;
354 case PROP_MAX_DRESS:
355 adg_dress_set(&data->max_dress, g_value_get_int(value));
356 break;
357 case PROP_LINE_DRESS:
358 adg_dress_set(&data->line_dress, g_value_get_int(value));
359 break;
360 case PROP_FROM_OFFSET:
361 data->from_offset = g_value_get_double(value);
362 break;
363 case PROP_TO_OFFSET:
364 data->to_offset = g_value_get_double(value);
365 break;
366 case PROP_BEYOND:
367 data->beyond = g_value_get_double(value);
368 break;
369 case PROP_BASELINE_SPACING:
370 data->baseline_spacing = g_value_get_double(value);
371 break;
372 case PROP_LIMITS_SPACING:
373 data->limits_spacing = g_value_get_double(value);
374 break;
375 case PROP_QUOTE_SHIFT:
376 cpml_pair_copy(&data->quote_shift, g_value_get_boxed(value));
377 break;
378 case PROP_LIMITS_SHIFT:
379 set_limits_shift(dim_style, g_value_get_boxed(value));
380 break;
381 case PROP_NUMBER_FORMAT:
382 set_number_format(dim_style, g_value_get_string(value));
383 break;
384 case PROP_NUMBER_TAG:
385 set_number_tag(dim_style, g_value_get_string(value));
386 break;
387 default:
388 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
389 break;
395 * adg_dim_style_new:
397 * Constructs a new dimension style initialized with default params.
399 * Returns: a new dimension style
401 AdgStyle *
402 adg_dim_style_new(void)
404 return g_object_new(ADG_TYPE_DIM_STYLE, NULL);
408 * adg_dim_style_marker1_new:
409 * @dim_style: an #AdgDimStyle
411 * Creates a new #AdgMarker entity accordling to the template marker
412 * stored with the #AdgDimStyle:marker1 property of @dim_style.
414 * Returns: a newly created #AdgMarker derived entity or %NULL if
415 * @dim_style has the #AdgDimStyle:marker1 property unset
417 AdgMarker *
418 adg_dim_style_marker1_new(AdgDimStyle *dim_style)
420 AdgDimStylePrivate *data;
422 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
424 data = dim_style->data;
426 return marker_new(&data->marker1);
430 * adg_dim_style_marker2_new:
431 * @dim_style: an #AdgDimStyle
433 * Creates a new #AdgMarker entity accordling to the template marker
434 * stored with the #AdgDimStyle:marker2 property of @dim_style.
436 * Returns: a newly created #AdgMarker derived entity or %NULL if
437 * @dim_style has the #AdgDimStyle:marker2 property unset
439 AdgMarker *
440 adg_dim_style_marker2_new(AdgDimStyle *dim_style)
442 AdgDimStylePrivate *data;
444 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
446 data = dim_style->data;
448 return marker_new(&data->marker2);
452 * adg_dim_style_use_marker1:
453 * @dim_style: an #AdgStyle
454 * @marker: an #AdgMarker derived entity
456 * Uses @marker as entity template to generate a new marker entity
457 * when a call to adg_dim_style_marker1_new() is made.
459 * This method duplicates internally the property values of @marker,
460 * so any further change to @marker does not affect @dim_style anymore.
461 * This also means @marker could be destroyed because @dim_style only
462 * uses its property values and does not add any references to @marker.
464 void
465 adg_dim_style_use_marker1(AdgDimStyle *dim_style, AdgMarker *marker)
467 AdgDimStylePrivate *data;
469 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
470 g_return_if_fail(marker == NULL || ADG_IS_MARKER(marker));
472 data = dim_style->data;
474 use_marker(&data->marker1, marker);
475 g_object_notify((GObject *) dim_style, "marker1");
479 * adg_dim_style_use_marker2:
480 * @dim_style: an #AdgStyle
481 * @marker: an #AdgMarker derived entity
483 * Uses @marker as entity template to generate a new marker entity
484 * when a call to adg_dim_style_marker2_new() is made.
486 * This method duplicates internally the property values of @marker,
487 * so any further change to @marker does not affect @dim_style anymore.
488 * This also means @marker could be destroyed because @dim_style only
489 * uses its property values and does not add any references to @marker.
491 void
492 adg_dim_style_use_marker2(AdgDimStyle *dim_style, AdgMarker *marker)
494 AdgDimStylePrivate *data;
496 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
497 g_return_if_fail(marker == NULL || ADG_IS_MARKER(marker));
499 data = dim_style->data;
501 use_marker(&data->marker2, marker);
502 g_object_notify((GObject *) dim_style, "marker2");
506 * adg_dim_style_get_color_dress:
507 * @dim_style: an #AdgDimStyle object
509 * Gets the @dim_style color dress to be used. This dress should be
510 * intended as a fallback color as it could be overriden by more
511 * specific dresses, such as a color explicitely specified on the
512 * #AdgDimStyle:value-dress.
514 * Returns: the color dress
516 AdgDress
517 adg_dim_style_get_color_dress(AdgDimStyle *dim_style)
519 AdgDimStylePrivate *data;
521 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
523 data = dim_style->data;
525 return data->color_dress;
529 * adg_dim_style_set_color_dress:
530 * @dim_style: an #AdgDimStyle object
531 * @dress: the new color dress
533 * Sets a new color dress on @dim_style.
535 void
536 adg_dim_style_set_color_dress(AdgDimStyle *dim_style, AdgDress dress)
538 AdgDimStylePrivate *data;
540 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
542 data = dim_style->data;
544 if (adg_dress_set(&data->color_dress, dress))
545 g_object_notify((GObject *) dim_style, "color-dress");
549 * adg_dim_style_get_value_dress:
550 * @dim_style: an #AdgDimStyle object
552 * Gets the font dress to be used for the basic value of dimensions
553 * with @dim_style.
555 * Returns: the font dress
557 AdgDress
558 adg_dim_style_get_value_dress(AdgDimStyle *dim_style)
560 AdgDimStylePrivate *data;
562 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
564 data = dim_style->data;
566 return data->value_dress;
570 * adg_dim_style_set_value_dress:
571 * @dim_style: an #AdgDimStyle object
572 * @dress: the new basic value font style
574 * Sets a new dress on @dim_style for the basic value.
576 void
577 adg_dim_style_set_value_dress(AdgDimStyle *dim_style, AdgDress dress)
579 AdgDimStylePrivate *data;
581 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
583 data = dim_style->data;
585 if (adg_dress_set(&data->value_dress, dress))
586 g_object_notify((GObject *) dim_style, "value-dress");
590 * adg_dim_style_get_min_dress:
591 * @dim_style: an #AdgDimStyle object
593 * Gets the @dim_style dress to be used for the lower limit.
595 * Returns: the lower limit dress
597 AdgDress
598 adg_dim_style_get_min_dress(AdgDimStyle *dim_style)
600 AdgDimStylePrivate *data;
602 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
604 data = dim_style->data;
606 return data->min_dress;
610 * adg_dim_style_set_min_dress:
611 * @dim_style: an #AdgDimStyle object
612 * @dress: the new lower limit dress
614 * Sets a new dress on @dim_style for the lower limit value.
616 void
617 adg_dim_style_set_min_dress(AdgDimStyle *dim_style, AdgDress dress)
619 AdgDimStylePrivate *data;
621 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
623 data = dim_style->data;
625 if (adg_dress_set(&data->min_dress, dress))
626 g_object_notify((GObject *) dim_style, "min-dress");
630 * adg_dim_style_get_max_dress:
631 * @dim_style: an #AdgDimStyle object
633 * Gets the @dim_style dress to be used for the upper limit.
635 * Returns: the upper limit dress
637 AdgDress
638 adg_dim_style_get_max_dress(AdgDimStyle *dim_style)
640 AdgDimStylePrivate *data;
642 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
644 data = dim_style->data;
646 return data->max_dress;
650 * adg_dim_style_set_max_dress:
651 * @dim_style: an #AdgDimStyle object
652 * @dress: the new upper limit dress
654 * Sets a new dress on @dim_style for the upper limit value.
656 void
657 adg_dim_style_set_max_dress(AdgDimStyle *dim_style, AdgDress dress)
659 AdgDimStylePrivate *data;
661 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
663 data = dim_style->data;
665 if (adg_dress_set(&data->max_dress, dress))
666 g_object_notify((GObject *) dim_style, "max-dress");
670 * adg_dim_style_get_line_dress:
671 * @dim_style: an #AdgDimStyle object
673 * Gets the line dress to be used for rendering the base and
674 * the extension lines with @dim_style.
676 * Returns: the line dress
678 AdgDress
679 adg_dim_style_get_line_dress(AdgDimStyle *dim_style)
681 AdgDimStylePrivate *data;
683 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), ADG_DRESS_UNDEFINED);
685 data = dim_style->data;
687 return data->line_dress;
691 * adg_dim_style_set_line_dress:
692 * @dim_style: an #AdgDimStyle object
693 * @dress: the new line dress
695 * Sets a new line dress on @dim_style.
697 void
698 adg_dim_style_set_line_dress(AdgDimStyle *dim_style, AdgDress dress)
700 AdgDimStylePrivate *data;
702 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
704 data = dim_style->data;
706 if (adg_dress_set(&data->line_dress, dress))
707 g_object_notify((GObject *) dim_style, "line-dress");
711 * adg_dim_style_get_from_offset:
712 * @dim_style: an #AdgDimStyle object
714 * Gets the distance (in global space) the extension lines must keep from the
715 * sensed points.
717 * Returns: the requested distance
719 gdouble
720 adg_dim_style_get_from_offset(AdgDimStyle *dim_style)
722 AdgDimStylePrivate *data;
724 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
726 data = dim_style->data;
728 return data->from_offset;
732 * adg_dim_style_set_from_offset:
733 * @dim_style: an #AdgDimStyle object
734 * @offset: the new offset
736 * Sets a new "from-offset" value.
738 void
739 adg_dim_style_set_from_offset(AdgDimStyle *dim_style, gdouble offset)
741 AdgDimStylePrivate *data;
743 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
745 data = dim_style->data;
746 data->from_offset = offset;
748 g_object_notify((GObject *) dim_style, "from-offset");
752 * adg_dim_style_get_to_offset:
753 * @dim_style: an #AdgDimStyle object
755 * Gets how much (in global space) the extension lines must extend after
756 * crossing the baseline.
758 * Returns: the requested distance
760 gdouble
761 adg_dim_style_get_to_offset(AdgDimStyle *dim_style)
763 AdgDimStylePrivate *data;
765 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
767 data = dim_style->data;
769 return data->to_offset;
773 * adg_dim_style_set_to_offset:
774 * @dim_style: an #AdgDimStyle object
775 * @offset: the new offset
777 * Sets a new "to-offset" value.
779 void
780 adg_dim_style_set_to_offset(AdgDimStyle *dim_style, gdouble offset)
782 AdgDimStylePrivate *data;
784 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
786 data = dim_style->data;
787 data->to_offset = offset;
789 g_object_notify((GObject *) dim_style, "to-offset");
793 * adg_dim_style_get_beyond:
794 * @dim_style: an #AdgDimStyle object
796 * Gets how much (in global space) the baseline should extend beyond
797 * the extension lines on dimension with outside markers.
799 * Returns: the requested beyond length
801 gdouble
802 adg_dim_style_get_beyond(AdgDimStyle *dim_style)
804 AdgDimStylePrivate *data;
806 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
808 data = dim_style->data;
810 return data->beyond;
814 * adg_dim_style_set_beyond:
815 * @dim_style: an #AdgDimStyle object
816 * @length: the new length
818 * Sets a new "beyond" value.
820 void
821 adg_dim_style_set_beyond(AdgDimStyle *dim_style, gdouble length)
823 AdgDimStylePrivate *data;
825 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
827 data = dim_style->data;
828 data->beyond = length;
830 g_object_notify((GObject *) dim_style, "beyond");
834 * adg_dim_style_get_baseline_spacing:
835 * @dim_style: an #AdgDimStyle object
837 * Gets the distance between two consecutive baselines
838 * while stacking dimensions.
840 * Returns: the requested spacing
842 gdouble
843 adg_dim_style_get_baseline_spacing(AdgDimStyle *dim_style)
845 AdgDimStylePrivate *data;
847 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
849 data = dim_style->data;
851 return data->baseline_spacing;
855 * adg_dim_style_set_baseline_spacing:
856 * @dim_style: an #AdgDimStyle object
857 * @spacing: the new spacing
859 * Sets a new "baseline-spacing" value.
861 void
862 adg_dim_style_set_baseline_spacing(AdgDimStyle *dim_style, gdouble spacing)
864 AdgDimStylePrivate *data;
866 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
868 data = dim_style->data;
869 data->baseline_spacing = spacing;
871 g_object_notify((GObject *) dim_style, "baseline-spacing");
875 * adg_dim_style_get_limits_spacing:
876 * @dim_style: an #AdgDimStyle object
878 * Gets the distance (in global space) between the limits/tolerances.
880 * Returns: the requested spacing
882 gdouble
883 adg_dim_style_get_limits_spacing(AdgDimStyle *dim_style)
885 AdgDimStylePrivate *data;
887 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), 0);
889 data = dim_style->data;
891 return data->limits_spacing;
895 * adg_dim_style_set_limits_spacing:
896 * @dim_style: an #AdgDimStyle object
897 * @spacing: the new spacing
899 * Sets a new #AdgDimStyle:limits-spacing value.
901 void
902 adg_dim_style_set_limits_spacing(AdgDimStyle *dim_style, gdouble spacing)
904 AdgDimStylePrivate *data;
906 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
908 data = dim_style->data;
909 data->limits_spacing = spacing;
911 g_object_notify((GObject *) dim_style, "limits-spacing");
915 * adg_dim_style_get_quote_shift:
916 * @dim_style: an #AdgDimStyle object
918 * Gets the smooth displacement of the quote. The returned pointer refers
919 * to an internal allocated struct and must not be modified or freed.
921 * Returns: the requested shift
923 const AdgPair *
924 adg_dim_style_get_quote_shift(AdgDimStyle *dim_style)
926 AdgDimStylePrivate *data;
928 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
930 data = dim_style->data;
932 return &data->quote_shift;
936 * adg_dim_style_set_quote_shift:
937 * @dim_style: an #AdgDimStyle object
938 * @shift: the new displacement
940 * Sets a new #AdgDimStyle:quote-shift value.
942 void
943 adg_dim_style_set_quote_shift(AdgDimStyle *dim_style, const AdgPair *shift)
945 AdgDimStylePrivate *data;
947 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
948 g_return_if_fail(shift != NULL);
950 data = dim_style->data;
951 cpml_pair_copy(&data->quote_shift, shift);
953 g_object_notify((GObject *) dim_style, "quote-shift");
957 * adg_dim_style_get_limits_shift:
958 * @dim_style: an #AdgDimStyle object
960 * Gets the smooth displacement for the limits. The returned pointer
961 * refers to an internal allocated struct and must not be modified or freed.
963 * Returns: the requested shift
965 const AdgPair *
966 adg_dim_style_get_limits_shift(AdgDimStyle *dim_style)
968 AdgDimStylePrivate *data;
970 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
972 data = dim_style->data;
974 return &data->limits_shift;
978 * adg_dim_style_set_limits_shift:
979 * @dim_style: an #AdgDimStyle object
980 * @shift: the new displacement
982 * Sets a new #AdgDimStyle:limits-shift value.
984 void
985 adg_dim_style_set_limits_shift(AdgDimStyle *dim_style, const AdgPair *shift)
987 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
989 set_limits_shift(dim_style, shift);
990 g_object_notify((GObject *) dim_style, "limits-shift");
994 * adg_dim_style_get_number_format:
995 * @dim_style: an #AdgDimStyle object
997 * Gets the number format (in printf style) of this quoting style. The
998 * returned pointer refers to internally managed text that must not be
999 * modified or freed.
1001 * Returns: the requested format
1003 const gchar *
1004 adg_dim_style_get_number_format(AdgDimStyle *dim_style)
1006 AdgDimStylePrivate *data;
1008 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
1010 data = dim_style->data;
1012 return data->number_format;
1016 * adg_dim_style_set_number_format:
1017 * @dim_style: an #AdgDimStyle object
1018 * @format: the new format to adopt
1020 * Sets a new "number-format" value.
1022 void
1023 adg_dim_style_set_number_format(AdgDimStyle *dim_style, const gchar *format)
1025 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
1027 set_number_format(dim_style, format);
1028 g_object_notify((GObject *) dim_style, "number-format");
1032 * adg_dim_style_get_number_tag:
1033 * @dim_style: an #AdgDimStyle object
1035 * Gets the number tag to substitute while building the basic value. The
1036 * returned pointer refers to internally managed text that must not be
1037 * modified or freed.
1039 * Returns: the requested tag
1041 const gchar *
1042 adg_dim_style_get_number_tag(AdgDimStyle *dim_style)
1044 AdgDimStylePrivate *data;
1046 g_return_val_if_fail(ADG_IS_DIM_STYLE(dim_style), NULL);
1048 data = dim_style->data;
1050 return data->number_tag;
1054 * adg_dim_style_set_number_tag:
1055 * @dim_style: an #AdgDimStyle object
1056 * @tag: the new tag
1058 * Sets a new "number-tag" value.
1060 void
1061 adg_dim_style_set_number_tag(AdgDimStyle *dim_style, const gchar *tag)
1063 g_return_if_fail(ADG_IS_DIM_STYLE(dim_style));
1065 set_number_tag(dim_style, tag);
1066 g_object_notify((GObject *) dim_style, "number-tag");
1070 static void
1071 apply(AdgStyle *style, AdgEntity *entity, cairo_t *cr)
1073 AdgDimStylePrivate *data = ((AdgDimStyle *) style)->data;
1075 adg_entity_apply_dress(entity, data->color_dress, cr);
1078 static void
1079 set_limits_shift(AdgDimStyle *dim_style, const AdgPair *shift)
1081 AdgDimStylePrivate *data = dim_style->data;
1083 cpml_pair_copy(&data->limits_shift, shift);
1086 static void
1087 set_number_format(AdgDimStyle *dim_style, const gchar *format)
1089 AdgDimStylePrivate *data = dim_style->data;
1091 g_free(data->number_format);
1092 data->number_format = g_strdup(format);
1095 static void
1096 set_number_tag(AdgDimStyle *dim_style, const gchar *tag)
1098 AdgDimStylePrivate *data = dim_style->data;
1100 g_free(data->number_tag);
1101 data->number_tag = g_strdup(tag);
1104 static AdgMarker *
1105 marker_new(const AdgMarkerData *marker_data)
1107 if (marker_data->type == 0)
1108 return NULL;
1110 return g_object_newv(marker_data->type,
1111 marker_data->n_parameters,
1112 marker_data->parameters);
1115 static void
1116 use_marker(AdgMarkerData *marker_data, AdgMarker *marker)
1118 GObject *object;
1119 GParamSpec **specs;
1120 GParamSpec *spec;
1121 GParameter *parameter;
1122 guint n;
1124 /* Free the previous marker data, if any */
1125 free_marker(marker_data);
1127 if (marker == NULL)
1128 return;
1130 object = (GObject *) marker;
1131 specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(marker),
1132 &marker_data->n_parameters);
1134 marker_data->type = G_TYPE_FROM_INSTANCE(marker);
1135 marker_data->parameters = g_new0(GParameter, marker_data->n_parameters);
1137 for (n = 0; n < marker_data->n_parameters; ++n) {
1138 spec = specs[n];
1139 parameter = &marker_data->parameters[n];
1141 /* Using intern strings because GParameter:name is const.
1142 * GObject properties are internally managed using non-static
1143 * GQuark, so g_intern_string() is the way to go */
1144 parameter->name = g_intern_string(spec->name);
1146 g_value_init(&parameter->value, spec->value_type);
1147 g_object_get_property(object, spec->name, &parameter->value);
1150 g_free(specs);
1153 static void
1154 free_marker(AdgMarkerData *marker_data)
1156 guint n;
1158 for (n = 0; n < marker_data->n_parameters; ++n)
1159 g_value_unset(&marker_data->parameters[n].value);
1161 marker_data->type = 0;
1162 marker_data->n_parameters = 0;
1163 marker_data->parameters = NULL;