1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2008, 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 Library 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 * Library 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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 * @title: AdgLineStyle
24 * @short_description: Line style related stuff
26 * Contains parameters on how to draw lines such as width, cap mode, join mode
27 * and dash composition, if used.
30 #include "adg-line-style.h"
31 #include "adg-line-style-private.h"
35 #define PARENT_CLASS ((AdgStyleClass *) adg_line_style_parent_class)
50 static void get_property (GObject
*object
,
54 static void set_property (GObject
*object
,
59 static void apply (AdgStyle
*style
,
63 G_DEFINE_TYPE (AdgLineStyle
, adg_line_style
, ADG_TYPE_STYLE
)
67 adg_line_style_class_init (AdgLineStyleClass
*klass
)
69 GObjectClass
*gobject_class
;
70 AdgStyleClass
*style_class
;
73 gobject_class
= (GObjectClass
*) klass
;
74 style_class
= (AdgStyleClass
*) klass
;
76 g_type_class_add_private (klass
, sizeof (AdgLineStylePrivate
));
78 gobject_class
->get_property
= get_property
;
79 gobject_class
->set_property
= set_property
;
81 style_class
->apply
= apply
;
83 param
= g_param_spec_double ("width",
85 P_("The line thickness in device unit"),
88 g_object_class_install_property (gobject_class
, PROP_WIDTH
, param
);
90 param
= g_param_spec_int ("cap",
92 P_("The line cap mode"),
93 G_MININT
, G_MAXINT
, CAIRO_LINE_CAP_ROUND
,
95 g_object_class_install_property (gobject_class
, PROP_CAP
, param
);
97 param
= g_param_spec_int ("join",
99 P_("The line join mode"),
100 G_MININT
, G_MAXINT
, CAIRO_LINE_JOIN_MITER
,
102 g_object_class_install_property (gobject_class
, PROP_JOIN
, param
);
104 param
= g_param_spec_double ("miter-limit",
106 P_("Whether the lines should be joined with a bevel instead of a miter"),
107 0., G_MAXDOUBLE
, 10.,
109 g_object_class_install_property (gobject_class
, PROP_MITER_LIMIT
, param
);
111 param
= g_param_spec_int ("antialias",
112 P_("Antialiasing Mode"),
113 P_("Type of antialiasing to do when rendering lines"),
114 G_MININT
, G_MAXINT
, CAIRO_ANTIALIAS_DEFAULT
,
116 g_object_class_install_property (gobject_class
, PROP_ANTIALIAS
, param
);
118 /* TODO: PROP_DASH (PROP_DASHES, PROP_NUM_DASHES, PROP_DASH_OFFSET) */
122 adg_line_style_init (AdgLineStyle
*line_style
)
124 AdgLineStylePrivate
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (line_style
,
126 AdgLineStylePrivate
);
129 priv
->cap
= CAIRO_LINE_CAP_ROUND
;
130 priv
->join
= CAIRO_LINE_JOIN_MITER
;
131 priv
->miter_limit
= 10.;
132 priv
->antialias
= CAIRO_ANTIALIAS_DEFAULT
;
134 priv
->num_dashes
= 0;
135 priv
->dash_offset
= 0.;
137 line_style
->priv
= priv
;
141 get_property (GObject
*object
,
146 AdgLineStyle
*line_style
= (AdgLineStyle
*) object
;
151 g_value_set_double (value
, line_style
->priv
->width
);
154 g_value_set_int (value
, line_style
->priv
->cap
);
157 g_value_set_int (value
, line_style
->priv
->join
);
159 case PROP_MITER_LIMIT
:
160 g_value_set_double (value
, line_style
->priv
->miter_limit
);
163 g_value_set_int (value
, line_style
->priv
->antialias
);
169 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
175 set_property (GObject
*object
,
180 AdgLineStyle
*line_style
= (AdgLineStyle
*) object
;
185 line_style
->priv
->width
= g_value_get_double (value
);
188 line_style
->priv
->cap
= g_value_get_int (value
);
191 line_style
->priv
->join
= g_value_get_int (value
);
193 case PROP_MITER_LIMIT
:
194 line_style
->priv
->miter_limit
= g_value_get_double (value
);
197 line_style
->priv
->antialias
= g_value_get_int (value
);
203 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
210 * adg_line_style_new:
212 * Constructs a new line style initialized with default params.
214 * Return value: a new line style
217 adg_line_style_new (void)
219 return g_object_new (ADG_TYPE_LINE_STYLE
, NULL
);
223 * adg_line_style_from_id:
224 * @id: a line style identifier
226 * Gets a predefined style from an #AdgLineStyleId identifier.
228 * Return value: the requested style or %NULL if not found
231 adg_line_style_from_id (AdgLineStyleId id
)
233 static AdgStyle
**builtins
= NULL
;
235 if G_UNLIKELY (builtins
== NULL
)
237 cairo_pattern_t
*pattern
;
239 builtins
= g_new (AdgStyle
*, ADG_LINE_STYLE_LAST
);
241 builtins
[ADG_LINE_STYLE_DRAW
] = g_object_new (ADG_TYPE_LINE_STYLE
,
245 pattern
= cairo_pattern_create_rgb (0., 1., 0.);
246 builtins
[ADG_LINE_STYLE_CENTER
] = g_object_new (ADG_TYPE_LINE_STYLE
,
250 cairo_pattern_destroy (pattern
);
252 pattern
= cairo_pattern_create_rgba (0., 0., 0., 0.5);
253 builtins
[ADG_LINE_STYLE_HIDDEN
] = g_object_new (ADG_TYPE_LINE_STYLE
,
257 cairo_pattern_destroy (pattern
);
259 pattern
= cairo_pattern_create_rgb (0., 0., 1.);
260 builtins
[ADG_LINE_STYLE_XATCH
] = g_object_new (ADG_TYPE_LINE_STYLE
,
264 cairo_pattern_destroy (pattern
);
266 builtins
[ADG_LINE_STYLE_DIM
] = g_object_new (ADG_TYPE_LINE_STYLE
,
271 g_return_val_if_fail (id
< ADG_LINE_STYLE_LAST
, NULL
);
276 * adg_line_style_get_width:
277 * @line_style: an #AdgLineStyle object
279 * Gets the line thickness value (in paper units).
281 * Return value: the requested width
284 adg_line_style_get_width (AdgLineStyle
*line_style
)
286 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), 0.);
288 return line_style
->priv
->width
;
292 * adg_line_style_set_width:
293 * @line_style: an #AdgLineStyle object
294 * @width: the new width
296 * Sets a new line thickness value.
299 adg_line_style_set_width (AdgLineStyle
*line_style
,
302 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
304 line_style
->priv
->width
= width
;
305 g_object_notify ((GObject
*) line_style
, "width");
309 * adg_line_style_get_cap:
310 * @line_style: an #AdgLineStyle object
312 * Gets the line cap mode.
314 * Return value: the requested line cap mode
317 adg_line_style_get_cap (AdgLineStyle
*line_style
)
319 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_LINE_CAP_BUTT
);
321 return line_style
->priv
->cap
;
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
,
333 cairo_line_cap_t cap
)
335 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
337 line_style
->priv
->cap
= cap
;
338 g_object_notify ((GObject
*) line_style
, "cap");
342 * adg_line_style_get_join:
343 * @line_style: an #AdgLineStyle object
345 * Gets the line join mode.
347 * Return value: the requested line join mode
350 adg_line_style_get_join (AdgLineStyle
*line_style
)
352 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_LINE_JOIN_MITER
);
354 return line_style
->priv
->join
;
358 * adg_line_style_set_join:
359 * @line_style: an #AdgLineStyle object
360 * @join: the new join mode
362 * Sets a new line join mode.
365 adg_line_style_set_join (AdgLineStyle
*line_style
,
366 cairo_line_join_t join
)
368 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
370 line_style
->priv
->join
= join
;
371 g_object_notify ((GObject
*) line_style
, "join");
375 * adg_line_style_get_miter_limit:
376 * @line_style: an #AdgLineStyle object
378 * Gets the line miter limit value. The miter limit is used to determine
379 * whether the lines should be joined with a bevel instead of a miter.
381 * Return value: the requested miter limit
384 adg_line_style_get_miter_limit (AdgLineStyle
*line_style
)
386 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), 0.);
388 return line_style
->priv
->miter_limit
;
392 * adg_line_style_set_miter_limit:
393 * @line_style: an #AdgLineStyle object
394 * @miter_limit: the new miter limit
396 * Sets a new miter limit value.
399 adg_line_style_set_miter_limit (AdgLineStyle
*line_style
,
402 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
404 line_style
->priv
->miter_limit
= miter_limit
;
405 g_object_notify ((GObject
*) line_style
, "miter-limit");
409 * adg_line_style_get_antialias:
410 * @line_style: an #AdgLineStyle object
412 * Gets the antialias mode used.
414 * Return value: the requested antialias mode
417 adg_line_style_get_antialias (AdgLineStyle
*line_style
)
419 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_ANTIALIAS_DEFAULT
);
421 return line_style
->priv
->antialias
;
425 * adg_line_style_set_antialias:
426 * @line_style: an #AdgLineStyle object
427 * @antialias: the new antialias mode
429 * Sets a new antialias mode.
432 adg_line_style_set_antialias (AdgLineStyle
*line_style
,
433 cairo_antialias_t antialias
)
435 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
437 line_style
->priv
->antialias
= antialias
;
438 g_object_notify ((GObject
*) line_style
, "antialias");
443 apply (AdgStyle
*style
,
446 AdgLineStyle
*line_style
;
447 gdouble device_width
;
450 line_style
= (AdgLineStyle
*) style
;
452 PARENT_CLASS
->apply (style
, cr
);
454 device_width
= line_style
->priv
->width
;
455 cairo_device_to_user_distance (cr
, &device_width
, &dummy
);
456 cairo_set_line_width (cr
, device_width
);
458 cairo_set_line_cap (cr
, line_style
->priv
->cap
);
459 cairo_set_line_join (cr
, line_style
->priv
->join
);
460 cairo_set_miter_limit (cr
, line_style
->priv
->miter_limit
);
461 cairo_set_antialias (cr
, line_style
->priv
->antialias
);
463 if (line_style
->priv
->num_dashes
> 0)
465 g_return_if_fail (line_style
->priv
->dashes
!= NULL
);
467 cairo_set_dash (cr
, line_style
->priv
->dashes
, line_style
->priv
->num_dashes
,
468 line_style
->priv
->dash_offset
);