s/2008,2009/2008,2009,2010/
[adg.git] / adg / adg-line-style.c
blob179f73424ac62174e358e16a550f03e1a2ff0c3a
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010 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-line-style
23 * @short_description: Line style related stuff
25 * Contains parameters on how to draw lines such as width, cap mode, join mode
26 * and dash composition, if used.
27 **/
29 /**
30 * AdgLineStyle:
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
34 **/
37 #include "adg-internal.h"
38 #include "adg-line-style.h"
39 #include "adg-line-style-private.h"
40 #include "adg-dress-builtins.h"
42 #define PARENT_STYLE_CLASS ((AdgStyleClass *) adg_line_style_parent_class)
45 enum {
46 PROP_0,
47 PROP_COLOR_DRESS,
48 PROP_WIDTH,
49 PROP_CAP,
50 PROP_JOIN,
51 PROP_MITER_LIMIT,
52 PROP_ANTIALIAS,
53 PROP_DASH
57 static void get_property (GObject *object,
58 guint prop_id,
59 GValue *value,
60 GParamSpec *pspec);
61 static void set_property (GObject *object,
62 guint prop_id,
63 const GValue *value,
64 GParamSpec *pspec);
65 static void apply (AdgStyle *style,
66 AdgEntity *entity,
67 cairo_t *cr);
70 G_DEFINE_TYPE(AdgLineStyle, adg_line_style, ADG_TYPE_STYLE);
73 static void
74 adg_line_style_class_init(AdgLineStyleClass *klass)
76 GObjectClass *gobject_class;
77 AdgStyleClass *style_class;
78 GParamSpec *param;
80 gobject_class = (GObjectClass *) klass;
81 style_class = (AdgStyleClass *) klass;
83 g_type_class_add_private(klass, sizeof(AdgLineStylePrivate));
85 gobject_class->get_property = get_property;
86 gobject_class->set_property = set_property;
88 style_class->apply = apply;
90 param = adg_param_spec_dress("color-dress",
91 P_("Color Dress"),
92 P_("The color dress to bind to this line style"),
93 ADG_DRESS_COLOR,
94 G_PARAM_READWRITE);
95 g_object_class_install_property(gobject_class, PROP_COLOR_DRESS, param);
97 param = g_param_spec_double("width",
98 P_("Line Width"),
99 P_("The line thickness in device unit"),
100 0., G_MAXDOUBLE, 2., G_PARAM_READWRITE);
101 g_object_class_install_property(gobject_class, PROP_WIDTH, param);
103 param = g_param_spec_int("cap",
104 P_("Line Cap"),
105 P_("The line cap mode"),
106 G_MININT, G_MAXINT, CAIRO_LINE_CAP_ROUND,
107 G_PARAM_READWRITE);
108 g_object_class_install_property(gobject_class, PROP_CAP, param);
110 param = g_param_spec_int("join",
111 P_("Line Join"),
112 P_("The line join mode"),
113 G_MININT, G_MAXINT, CAIRO_LINE_JOIN_MITER,
114 G_PARAM_READWRITE);
115 g_object_class_install_property(gobject_class, PROP_JOIN, param);
117 param = g_param_spec_double("miter-limit",
118 P_("Miter Limit"),
119 P_("Whether the lines should be joined with a bevel instead of a miter"),
120 0., G_MAXDOUBLE, 10., G_PARAM_READWRITE);
121 g_object_class_install_property(gobject_class, PROP_MITER_LIMIT,
122 param);
124 param = g_param_spec_int("antialias",
125 P_("Antialiasing Mode"),
126 P_("Type of antialiasing to do when rendering lines"),
127 G_MININT, G_MAXINT, CAIRO_ANTIALIAS_DEFAULT,
128 G_PARAM_READWRITE);
129 g_object_class_install_property(gobject_class, PROP_ANTIALIAS, param);
131 /* TODO: PROP_DASH (PROP_DASHES, PROP_NUM_DASHES, PROP_DASH_OFFSET) */
134 static void
135 adg_line_style_init(AdgLineStyle *line_style)
137 AdgLineStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(line_style,
138 ADG_TYPE_LINE_STYLE,
139 AdgLineStylePrivate);
141 data->color_dress = ADG_DRESS_COLOR;
142 data->width = 2.;
143 data->cap = CAIRO_LINE_CAP_ROUND;
144 data->join = CAIRO_LINE_JOIN_MITER;
145 data->miter_limit = 10.;
146 data->antialias = CAIRO_ANTIALIAS_DEFAULT;
147 data->dashes = NULL;
148 data->num_dashes = 0;
149 data->dash_offset = 0.;
151 line_style->data = data;
154 static void
155 get_property(GObject *object, guint prop_id,
156 GValue *value, GParamSpec *pspec)
158 AdgLineStylePrivate *data = ((AdgLineStyle *) object)->data;
160 switch (prop_id) {
161 case PROP_COLOR_DRESS:
162 g_value_set_int(value, data->color_dress);
163 break;
164 case PROP_WIDTH:
165 g_value_set_double(value, data->width);
166 break;
167 case PROP_CAP:
168 g_value_set_int(value, data->cap);
169 break;
170 case PROP_JOIN:
171 g_value_set_int(value, data->join);
172 break;
173 case PROP_MITER_LIMIT:
174 g_value_set_double(value, data->miter_limit);
175 break;
176 case PROP_ANTIALIAS:
177 g_value_set_int(value, data->antialias);
178 break;
179 case PROP_DASH:
180 /* TODO */
181 break;
182 default:
183 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
184 break;
188 static void
189 set_property(GObject *object, guint prop_id,
190 const GValue *value, GParamSpec *pspec)
192 AdgLineStylePrivate *data = ((AdgLineStyle *) object)->data;
194 switch (prop_id) {
195 case PROP_COLOR_DRESS:
196 adg_dress_set(&data->color_dress, g_value_get_int(value));
197 break;
198 case PROP_WIDTH:
199 data->width = g_value_get_double(value);
200 break;
201 case PROP_CAP:
202 data->cap = g_value_get_int(value);
203 break;
204 case PROP_JOIN:
205 data->join = g_value_get_int(value);
206 break;
207 case PROP_MITER_LIMIT:
208 data->miter_limit = g_value_get_double(value);
209 break;
210 case PROP_ANTIALIAS:
211 data->antialias = g_value_get_int(value);
212 break;
213 case PROP_DASH:
214 /* TODO */
215 break;
216 default:
217 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
218 break;
224 * adg_line_style_new:
226 * Constructs a new line style initialized with default params.
228 * Returns: a new line style
230 AdgLineStyle *
231 adg_line_style_new(void)
233 return g_object_new(ADG_TYPE_LINE_STYLE, NULL);
237 * adg_line_style_set_color_dress:
238 * @line_style: an #AdgLineStyle
239 * @dress: the new color dress to use
241 * Sets a new color dress on @line_style. The new dress
242 * should be related to the original dress: you cannot
243 * set a dress used for line styles to a dress managing
244 * fonts.
246 * The validation of the new dress is done by calling
247 * adg_dress_are_related() with @dress and the previous
248 * dress as arguments: check out its documentation for
249 * details on what is a related dress.
251 void
252 adg_line_style_set_color_dress(AdgLineStyle *line_style, AdgDress dress)
254 AdgLineStylePrivate *data;
256 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
258 data = line_style->data;
260 if (adg_dress_set(&data->color_dress, dress))
261 g_object_notify((GObject *) line_style, "color-dress");
265 * adg_line_style_get_color_dress:
266 * @line_style: an #AdgLineStyle
268 * Gets the color dress used by @line_style.
270 * Returns: the current color dress
272 AdgDress
273 adg_line_style_get_color_dress(AdgLineStyle *line_style)
275 AdgLineStylePrivate *data;
277 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style), ADG_DRESS_UNDEFINED);
279 data = line_style->data;
281 return data->color_dress;
285 * adg_line_style_set_width:
286 * @line_style: an #AdgLineStyle object
287 * @width: the new width
289 * Sets a new line thickness value.
291 void
292 adg_line_style_set_width(AdgLineStyle *line_style, gdouble width)
294 AdgLineStylePrivate *data;
296 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
298 data = line_style->data;
299 data->width = width;
301 g_object_notify((GObject *) line_style, "width");
305 * adg_line_style_get_width:
306 * @line_style: an #AdgLineStyle object
308 * Gets the line thickness value (in global space).
310 * Returns: the requested width
312 gdouble
313 adg_line_style_get_width(AdgLineStyle *line_style)
315 AdgLineStylePrivate *data;
317 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style), 0.);
319 data = line_style->data;
321 return data->width;
325 * adg_line_style_set_cap:
326 * @line_style: an #AdgLineStyle object
327 * @cap: the new cap mode
329 * Sets a new line cap mode.
331 void
332 adg_line_style_set_cap(AdgLineStyle *line_style, cairo_line_cap_t cap)
334 AdgLineStylePrivate *data;
336 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
338 data = line_style->data;
339 data->cap = cap;
341 g_object_notify((GObject *) line_style, "cap");
345 * adg_line_style_get_cap:
346 * @line_style: an #AdgLineStyle object
348 * Gets the line cap mode.
350 * Returns: the requested line cap mode
352 cairo_line_cap_t
353 adg_line_style_get_cap(AdgLineStyle *line_style)
355 AdgLineStylePrivate *data;
357 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style),
358 CAIRO_LINE_CAP_BUTT);
360 data = line_style->data;
362 return data->cap;
366 * adg_line_style_set_join:
367 * @line_style: an #AdgLineStyle object
368 * @join: the new join mode
370 * Sets a new line join mode.
372 void
373 adg_line_style_set_join(AdgLineStyle *line_style, cairo_line_join_t join)
375 AdgLineStylePrivate *data;
377 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
379 data = line_style->data;
380 data->join = join;
382 g_object_notify((GObject *) line_style, "join");
386 * adg_line_style_get_join:
387 * @line_style: an #AdgLineStyle object
389 * Gets the line join mode.
391 * Returns: the requested line join mode
393 cairo_line_join_t
394 adg_line_style_get_join(AdgLineStyle *line_style)
396 AdgLineStylePrivate *data;
398 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style),
399 CAIRO_LINE_JOIN_MITER);
401 data = line_style->data;
403 return data->join;
407 * adg_line_style_set_miter_limit:
408 * @line_style: an #AdgLineStyle object
409 * @miter_limit: the new miter limit
411 * Sets a new miter limit value.
413 void
414 adg_line_style_set_miter_limit(AdgLineStyle *line_style,
415 gdouble miter_limit)
417 AdgLineStylePrivate *data;
419 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
421 data = line_style->data;
422 data->miter_limit = miter_limit;
424 g_object_notify((GObject *) line_style, "miter-limit");
428 * adg_line_style_get_miter_limit:
429 * @line_style: an #AdgLineStyle object
431 * Gets the line miter limit value. The miter limit is used to determine
432 * whether the lines should be joined with a bevel instead of a miter.
434 * Returns: the requested miter limit
436 gdouble
437 adg_line_style_get_miter_limit(AdgLineStyle *line_style)
439 AdgLineStylePrivate *data;
441 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style), 0.);
443 data = line_style->data;
445 return data->miter_limit;
449 * adg_line_style_set_antialias:
450 * @line_style: an #AdgLineStyle object
451 * @antialias: the new antialias mode
453 * Sets a new antialias mode.
455 void
456 adg_line_style_set_antialias(AdgLineStyle *line_style,
457 cairo_antialias_t antialias)
459 AdgLineStylePrivate *data;
461 g_return_if_fail(ADG_IS_LINE_STYLE(line_style));
463 data = line_style->data;
464 data->antialias = antialias;
466 g_object_notify((GObject *) line_style, "antialias");
470 * adg_line_style_get_antialias:
471 * @line_style: an #AdgLineStyle object
473 * Gets the antialias mode used.
475 * Returns: the requested antialias mode
477 cairo_antialias_t
478 adg_line_style_get_antialias(AdgLineStyle *line_style)
480 AdgLineStylePrivate *data;
482 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style),
483 CAIRO_ANTIALIAS_DEFAULT);
485 data = line_style->data;
487 return data->antialias;
491 static void
492 apply(AdgStyle *style, AdgEntity *entity, cairo_t *cr)
494 AdgLineStylePrivate *data = ((AdgLineStyle *) style)->data;
496 adg_entity_apply_dress(entity, data->color_dress, cr);
497 cairo_set_line_width(cr, data->width);
498 cairo_set_line_cap(cr, data->cap);
499 cairo_set_line_join(cr, data->join);
500 cairo_set_miter_limit(cr, data->miter_limit);
501 cairo_set_antialias(cr, data->antialias);
503 if (data->num_dashes > 0) {
504 g_return_if_fail(data->dashes != NULL);
506 cairo_set_dash(cr, data->dashes, data->num_dashes, data->dash_offset);