1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
22 * 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.
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
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)
57 static void get_property (GObject
*object
,
61 static void set_property (GObject
*object
,
65 static void apply (AdgStyle
*style
,
70 G_DEFINE_TYPE(AdgLineStyle
, adg_line_style
, ADG_TYPE_STYLE
);
74 adg_line_style_class_init(AdgLineStyleClass
*klass
)
76 GObjectClass
*gobject_class
;
77 AdgStyleClass
*style_class
;
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",
92 P_("The color dress to bind to this line style"),
95 g_object_class_install_property(gobject_class
, PROP_COLOR_DRESS
, param
);
97 param
= g_param_spec_double("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",
105 P_("The line cap mode"),
106 G_MININT
, G_MAXINT
, CAIRO_LINE_CAP_ROUND
,
108 g_object_class_install_property(gobject_class
, PROP_CAP
, param
);
110 param
= g_param_spec_int("join",
112 P_("The line join mode"),
113 G_MININT
, G_MAXINT
, CAIRO_LINE_JOIN_MITER
,
115 g_object_class_install_property(gobject_class
, PROP_JOIN
, param
);
117 param
= g_param_spec_double("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
,
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
,
129 g_object_class_install_property(gobject_class
, PROP_ANTIALIAS
, param
);
131 /* TODO: PROP_DASH (PROP_DASHES, PROP_NUM_DASHES, PROP_DASH_OFFSET) */
135 adg_line_style_init(AdgLineStyle
*line_style
)
137 AdgLineStylePrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(line_style
,
139 AdgLineStylePrivate
);
141 data
->color_dress
= ADG_DRESS_COLOR
;
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
;
148 data
->num_dashes
= 0;
149 data
->dash_offset
= 0.;
151 line_style
->data
= data
;
155 get_property(GObject
*object
, guint prop_id
,
156 GValue
*value
, GParamSpec
*pspec
)
158 AdgLineStylePrivate
*data
= ((AdgLineStyle
*) object
)->data
;
161 case PROP_COLOR_DRESS
:
162 g_value_set_int(value
, data
->color_dress
);
165 g_value_set_double(value
, data
->width
);
168 g_value_set_int(value
, data
->cap
);
171 g_value_set_int(value
, data
->join
);
173 case PROP_MITER_LIMIT
:
174 g_value_set_double(value
, data
->miter_limit
);
177 g_value_set_int(value
, data
->antialias
);
183 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
189 set_property(GObject
*object
, guint prop_id
,
190 const GValue
*value
, GParamSpec
*pspec
)
192 AdgLineStylePrivate
*data
= ((AdgLineStyle
*) object
)->data
;
195 case PROP_COLOR_DRESS
:
196 adg_dress_set(&data
->color_dress
, g_value_get_int(value
));
199 data
->width
= g_value_get_double(value
);
202 data
->cap
= g_value_get_int(value
);
205 data
->join
= g_value_get_int(value
);
207 case PROP_MITER_LIMIT
:
208 data
->miter_limit
= g_value_get_double(value
);
211 data
->antialias
= g_value_get_int(value
);
217 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
224 * adg_line_style_new:
226 * Constructs a new line style initialized with default params.
228 * Returns: a new line style
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
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.
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
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.
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
;
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
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
;
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.
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
;
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
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
;
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.
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
;
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
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
;
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.
414 adg_line_style_set_miter_limit(AdgLineStyle
*line_style
,
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
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.
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
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
;
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
);