1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010,2011 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.
34 * All fields are private and should not be used directly.
35 * Use its public methods instead.
41 #include "adg-internal.h"
42 #include "adg-dress.h"
43 #include "adg-dress-builtins.h"
44 #include "adg-style.h"
46 #include "adg-line-style.h"
47 #include "adg-line-style-private.h"
50 G_DEFINE_TYPE(AdgLineStyle
, adg_line_style
, ADG_TYPE_STYLE
)
52 /* XXX: http://dev.entidi.com/p/adg/issues/51/ */
64 static void _adg_get_property (GObject
*object
,
68 static void _adg_set_property (GObject
*object
,
72 static void _adg_apply (AdgStyle
*style
,
78 adg_line_style_class_init(AdgLineStyleClass
*klass
)
80 GObjectClass
*gobject_class
;
81 AdgStyleClass
*style_class
;
84 gobject_class
= (GObjectClass
*) klass
;
85 style_class
= (AdgStyleClass
*) klass
;
87 g_type_class_add_private(klass
, sizeof(AdgLineStylePrivate
));
89 gobject_class
->get_property
= _adg_get_property
;
90 gobject_class
->set_property
= _adg_set_property
;
92 style_class
->apply
= _adg_apply
;
94 param
= adg_param_spec_dress("color-dress",
96 P_("The color dress to bind to this line style"),
99 g_object_class_install_property(gobject_class
, PROP_COLOR_DRESS
, param
);
101 param
= g_param_spec_double("width",
103 P_("The line thickness in device unit"),
104 0., G_MAXDOUBLE
, 2., G_PARAM_READWRITE
);
105 g_object_class_install_property(gobject_class
, PROP_WIDTH
, param
);
107 param
= g_param_spec_int("cap",
109 P_("The line cap mode"),
110 G_MININT
, G_MAXINT
, CAIRO_LINE_CAP_ROUND
,
112 g_object_class_install_property(gobject_class
, PROP_CAP
, param
);
114 param
= g_param_spec_int("join",
116 P_("The line join mode"),
117 G_MININT
, G_MAXINT
, CAIRO_LINE_JOIN_MITER
,
119 g_object_class_install_property(gobject_class
, PROP_JOIN
, param
);
121 param
= g_param_spec_double("miter-limit",
123 P_("Whether the lines should be joined with a bevel instead of a miter"),
124 0., G_MAXDOUBLE
, 10., G_PARAM_READWRITE
);
125 g_object_class_install_property(gobject_class
, PROP_MITER_LIMIT
,
128 param
= g_param_spec_int("antialias",
129 P_("Antialiasing Mode"),
130 P_("Type of antialiasing to do when rendering lines"),
131 G_MININT
, G_MAXINT
, CAIRO_ANTIALIAS_DEFAULT
,
133 g_object_class_install_property(gobject_class
, PROP_ANTIALIAS
, param
);
137 adg_line_style_init(AdgLineStyle
*line_style
)
139 AdgLineStylePrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(line_style
,
141 AdgLineStylePrivate
);
143 data
->color_dress
= ADG_DRESS_COLOR
;
145 data
->cap
= CAIRO_LINE_CAP_ROUND
;
146 data
->join
= CAIRO_LINE_JOIN_MITER
;
147 data
->miter_limit
= 10.;
148 data
->antialias
= CAIRO_ANTIALIAS_DEFAULT
;
150 data
->num_dashes
= 0;
151 data
->dash_offset
= 0.;
153 line_style
->data
= data
;
157 _adg_get_property(GObject
*object
, guint prop_id
,
158 GValue
*value
, GParamSpec
*pspec
)
160 AdgLineStylePrivate
*data
= ((AdgLineStyle
*) object
)->data
;
163 case PROP_COLOR_DRESS
:
164 g_value_set_int(value
, data
->color_dress
);
167 g_value_set_double(value
, data
->width
);
170 g_value_set_int(value
, data
->cap
);
173 g_value_set_int(value
, data
->join
);
175 case PROP_MITER_LIMIT
:
176 g_value_set_double(value
, data
->miter_limit
);
179 g_value_set_int(value
, data
->antialias
);
182 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
188 _adg_set_property(GObject
*object
, guint prop_id
,
189 const GValue
*value
, GParamSpec
*pspec
)
191 AdgLineStylePrivate
*data
= ((AdgLineStyle
*) object
)->data
;
194 case PROP_COLOR_DRESS
:
195 data
->color_dress
= g_value_get_int(value
);
198 data
->width
= g_value_get_double(value
);
201 data
->cap
= g_value_get_int(value
);
204 data
->join
= g_value_get_int(value
);
206 case PROP_MITER_LIMIT
:
207 data
->miter_limit
= g_value_get_double(value
);
210 data
->antialias
= g_value_get_int(value
);
213 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
220 * adg_line_style_new:
222 * Constructs a new line style initialized with default params.
224 * Returns: (transfer full): a new line style.
229 adg_line_style_new(void)
231 return g_object_new(ADG_TYPE_LINE_STYLE
, NULL
);
235 * adg_line_style_set_color_dress:
236 * @line_style: an #AdgLineStyle
237 * @dress: the new color dress to use
239 * Sets a new color dress on @line_style. The new dress
240 * should be related to the original dress: you cannot
241 * set a dress used for line styles to a dress managing
244 * The validation of the new dress is done by calling
245 * adg_dress_are_related() with @dress and the previous
246 * dress as arguments: check out its documentation for
247 * details on what is a related dress.
252 adg_line_style_set_color_dress(AdgLineStyle
*line_style
, AdgDress dress
)
254 g_return_if_fail(ADG_IS_LINE_STYLE(line_style
));
255 g_object_set(line_style
, "color-dress", dress
, NULL
);
259 * adg_line_style_get_color_dress:
260 * @line_style: an #AdgLineStyle
262 * Gets the color dress used by @line_style.
264 * Returns: (transfer none): the current color dress.
269 adg_line_style_get_color_dress(AdgLineStyle
*line_style
)
271 AdgLineStylePrivate
*data
;
273 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
), ADG_DRESS_UNDEFINED
);
275 data
= line_style
->data
;
277 return data
->color_dress
;
281 * adg_line_style_set_width:
282 * @line_style: an #AdgLineStyle object
283 * @width: the new width
285 * Sets a new line thickness value.
290 adg_line_style_set_width(AdgLineStyle
*line_style
, gdouble width
)
292 g_return_if_fail(ADG_IS_LINE_STYLE(line_style
));
293 g_object_set(line_style
, "width", width
, NULL
);
297 * adg_line_style_get_width:
298 * @line_style: an #AdgLineStyle object
300 * Gets the line thickness value (in global space).
302 * Returns: the requested width.
307 adg_line_style_get_width(AdgLineStyle
*line_style
)
309 AdgLineStylePrivate
*data
;
311 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
), 0.);
313 data
= line_style
->data
;
319 * adg_line_style_set_cap:
320 * @line_style: an #AdgLineStyle object
321 * @cap: (type gint): the new cap mode
323 * Sets a new line cap mode.
328 adg_line_style_set_cap(AdgLineStyle
*line_style
, cairo_line_cap_t cap
)
330 AdgLineStylePrivate
*data
;
332 g_return_if_fail(ADG_IS_LINE_STYLE(line_style
));
334 data
= line_style
->data
;
337 g_object_notify((GObject
*) line_style
, "cap");
341 * adg_line_style_get_cap:
342 * @line_style: an #AdgLineStyle object
344 * Gets the line cap mode.
346 * Returns: (type gint) (transfer none): the requested line cap mode.
351 adg_line_style_get_cap(AdgLineStyle
*line_style
)
353 AdgLineStylePrivate
*data
;
355 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
),
356 CAIRO_LINE_CAP_BUTT
);
358 data
= line_style
->data
;
364 * adg_line_style_set_join:
365 * @line_style: an #AdgLineStyle object
366 * @join: (type gint): the new join mode
368 * 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: (type gint) (transfer none): the requested line join mode.
396 adg_line_style_get_join(AdgLineStyle
*line_style
)
398 AdgLineStylePrivate
*data
;
400 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
),
401 CAIRO_LINE_JOIN_MITER
);
403 data
= line_style
->data
;
409 * adg_line_style_set_miter_limit:
410 * @line_style: an #AdgLineStyle object
411 * @miter_limit: the new miter limit
413 * Sets a new miter limit value.
418 adg_line_style_set_miter_limit(AdgLineStyle
*line_style
, gdouble miter_limit
)
420 g_return_if_fail(ADG_IS_LINE_STYLE(line_style
));
421 g_object_set(line_style
, "miter-limit", miter_limit
, NULL
);
425 * adg_line_style_get_miter_limit:
426 * @line_style: an #AdgLineStyle object
428 * Gets the line miter limit value. The miter limit is used to determine
429 * whether the lines should be joined with a bevel instead of a miter.
431 * Returns: the requested miter limit
436 adg_line_style_get_miter_limit(AdgLineStyle
*line_style
)
438 AdgLineStylePrivate
*data
;
440 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
), 0.);
442 data
= line_style
->data
;
444 return data
->miter_limit
;
448 * adg_line_style_set_antialias:
449 * @line_style: an #AdgLineStyle object
450 * @antialias: (type gint): the new antialias mode
452 * Sets a new antialias mode.
457 adg_line_style_set_antialias(AdgLineStyle
*line_style
,
458 cairo_antialias_t antialias
)
460 AdgLineStylePrivate
*data
;
462 g_return_if_fail(ADG_IS_LINE_STYLE(line_style
));
464 data
= line_style
->data
;
465 data
->antialias
= antialias
;
467 g_object_notify((GObject
*) line_style
, "antialias");
471 * adg_line_style_get_antialias:
472 * @line_style: an #AdgLineStyle object
474 * Gets the antialias mode used.
476 * Returns: (type gint) (transfer none): the requested antialias mode.
481 adg_line_style_get_antialias(AdgLineStyle
*line_style
)
483 AdgLineStylePrivate
*data
;
485 g_return_val_if_fail(ADG_IS_LINE_STYLE(line_style
),
486 CAIRO_ANTIALIAS_DEFAULT
);
488 data
= line_style
->data
;
490 return data
->antialias
;
495 _adg_apply(AdgStyle
*style
, AdgEntity
*entity
, cairo_t
*cr
)
497 AdgLineStylePrivate
*data
= ((AdgLineStyle
*) style
)->data
;
499 adg_entity_apply_dress(entity
, data
->color_dress
, cr
);
500 cairo_set_line_width(cr
, data
->width
);
501 cairo_set_line_cap(cr
, data
->cap
);
502 cairo_set_line_join(cr
, data
->join
);
503 cairo_set_miter_limit(cr
, data
->miter_limit
);
504 cairo_set_antialias(cr
, data
->antialias
);
506 if (data
->num_dashes
> 0) {
507 g_return_if_fail(data
->dashes
!= NULL
);
508 cairo_set_dash(cr
, data
->dashes
, data
->num_dashes
, data
->dash_offset
);