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
,
60 G_DEFINE_TYPE (AdgLineStyle
, adg_line_style
, ADG_TYPE_STYLE
)
64 adg_line_style_class_init (AdgLineStyleClass
*klass
)
66 GObjectClass
*gobject_class
;
69 gobject_class
= (GObjectClass
*) klass
;
71 g_type_class_add_private (klass
, sizeof (AdgLineStylePrivate
));
73 gobject_class
->get_property
= get_property
;
74 gobject_class
->set_property
= set_property
;
76 param
= g_param_spec_double ("width",
78 P_("The line thickness in device unit"),
81 g_object_class_install_property (gobject_class
, PROP_WIDTH
, param
);
83 param
= g_param_spec_int ("cap",
85 P_("The line cap mode"),
86 G_MININT
, G_MAXINT
, CAIRO_LINE_CAP_ROUND
,
88 g_object_class_install_property (gobject_class
, PROP_CAP
, param
);
90 param
= g_param_spec_int ("join",
92 P_("The line join mode"),
93 G_MININT
, G_MAXINT
, CAIRO_LINE_JOIN_MITER
,
95 g_object_class_install_property (gobject_class
, PROP_JOIN
, param
);
97 param
= g_param_spec_double ("miter-limit",
99 P_("Whether the lines should be joined with a bevel instead of a miter"),
100 0., G_MAXDOUBLE
, 10.,
102 g_object_class_install_property (gobject_class
, PROP_MITER_LIMIT
, param
);
104 param
= g_param_spec_int ("antialias",
105 P_("Antialiasing Mode"),
106 P_("Type of antialiasing to do when rendering lines"),
107 G_MININT
, G_MAXINT
, CAIRO_ANTIALIAS_DEFAULT
,
109 g_object_class_install_property (gobject_class
, PROP_ANTIALIAS
, param
);
111 /* TODO: PROP_DASH (PROP_DASHES, PROP_NUM_DASHES, PROP_DASH_OFFSET) */
115 adg_line_style_init (AdgLineStyle
*line_style
)
117 AdgLineStylePrivate
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (line_style
,
119 AdgLineStylePrivate
);
122 priv
->cap
= CAIRO_LINE_CAP_ROUND
;
123 priv
->join
= CAIRO_LINE_JOIN_MITER
;
124 priv
->miter_limit
= 10.;
125 priv
->antialias
= CAIRO_ANTIALIAS_DEFAULT
;
127 priv
->num_dashes
= 0;
128 priv
->dash_offset
= 0.;
130 line_style
->priv
= priv
;
134 get_property (GObject
*object
,
139 AdgLineStyle
*line_style
= (AdgLineStyle
*) object
;
144 g_value_set_double (value
, line_style
->priv
->width
);
147 g_value_set_int (value
, line_style
->priv
->cap
);
150 g_value_set_int (value
, line_style
->priv
->join
);
152 case PROP_MITER_LIMIT
:
153 g_value_set_double (value
, line_style
->priv
->miter_limit
);
156 g_value_set_int (value
, line_style
->priv
->antialias
);
162 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
168 set_property (GObject
*object
,
173 AdgLineStyle
*line_style
= (AdgLineStyle
*) object
;
178 line_style
->priv
->width
= g_value_get_double (value
);
181 line_style
->priv
->cap
= g_value_get_int (value
);
184 line_style
->priv
->join
= g_value_get_int (value
);
186 case PROP_MITER_LIMIT
:
187 line_style
->priv
->miter_limit
= g_value_get_double (value
);
190 line_style
->priv
->antialias
= g_value_get_int (value
);
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
203 * adg_line_style_from_id:
204 * @id: a line style identifier
206 * Gets a predefined style from an #AdgLineStyleId identifier.
208 * Return value: the requested style or %NULL if not found
211 adg_line_style_from_id (AdgLineStyleId id
)
213 static AdgStyle
**builtins
= NULL
;
215 if G_UNLIKELY (builtins
== NULL
)
217 builtins
= g_new (AdgStyle
*, ADG_LINE_STYLE_LAST
);
219 builtins
[ADG_LINE_STYLE_DRAW
] = g_object_new (ADG_TYPE_LINE_STYLE
,
222 builtins
[ADG_LINE_STYLE_CENTER
] = g_object_new (ADG_TYPE_LINE_STYLE
,
226 builtins
[ADG_LINE_STYLE_HIDDEN
] = g_object_new (ADG_TYPE_LINE_STYLE
,
230 builtins
[ADG_LINE_STYLE_XATCH
] = g_object_new (ADG_TYPE_LINE_STYLE
,
234 builtins
[ADG_LINE_STYLE_DIM
] = g_object_new (ADG_TYPE_LINE_STYLE
,
240 g_return_val_if_fail (id
< ADG_LINE_STYLE_LAST
, NULL
);
245 * adg_line_style_apply:
246 * @line_style: an #AdgLineStyle style
247 * @cr: the cairo context
249 * Applies @line_style to @cr so the next lines will have this style.
252 adg_line_style_apply (const AdgLineStyle
*line_style
,
258 g_return_if_fail (line_style
!= NULL
);
259 g_return_if_fail (cr
!= NULL
);
261 device_width
= line_style
->priv
->width
;
262 cairo_device_to_user_distance (cr
, &device_width
, &dummy
);
263 cairo_set_line_width (cr
, device_width
);
265 cairo_set_line_cap (cr
, line_style
->priv
->cap
);
266 cairo_set_line_join (cr
, line_style
->priv
->join
);
267 cairo_set_miter_limit (cr
, line_style
->priv
->miter_limit
);
268 cairo_set_antialias (cr
, line_style
->priv
->antialias
);
270 if (line_style
->priv
->num_dashes
> 0)
272 g_return_if_fail (line_style
->priv
->dashes
!= NULL
);
274 cairo_set_dash (cr
, line_style
->priv
->dashes
, line_style
->priv
->num_dashes
,
275 line_style
->priv
->dash_offset
);
280 * adg_line_style_get_width:
281 * @line_style: an #AdgLineStyle object
283 * Gets the line thickness value (in paper units).
285 * Return value: the requested width
288 adg_line_style_get_width (AdgLineStyle
*line_style
)
290 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), 0.);
292 return line_style
->priv
->width
;
296 * adg_line_style_set_width:
297 * @line_style: an #AdgLineStyle object
298 * @width: the new width
300 * Sets a new line thickness value.
303 adg_line_style_set_width (AdgLineStyle
*line_style
,
306 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
308 line_style
->priv
->width
= width
;
309 g_object_notify ((GObject
*) line_style
, "width");
313 * adg_line_style_get_cap:
314 * @line_style: an #AdgLineStyle object
316 * Gets the line cap mode.
318 * Return value: the requested line cap mode
321 adg_line_style_get_cap (AdgLineStyle
*line_style
)
323 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_LINE_CAP_BUTT
);
325 return line_style
->priv
->cap
;
329 * adg_line_style_set_cap:
330 * @line_style: an #AdgLineStyle object
331 * @cap: the new cap mode
333 * Sets a new line cap mode.
336 adg_line_style_set_cap (AdgLineStyle
*line_style
,
337 cairo_line_cap_t cap
)
339 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
341 line_style
->priv
->cap
= cap
;
342 g_object_notify ((GObject
*) line_style
, "cap");
346 * adg_line_style_get_join:
347 * @line_style: an #AdgLineStyle object
349 * Gets the line join mode.
351 * Return value: the requested line join mode
354 adg_line_style_get_join (AdgLineStyle
*line_style
)
356 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_LINE_JOIN_MITER
);
358 return line_style
->priv
->join
;
362 * adg_line_style_set_join:
363 * @line_style: an #AdgLineStyle object
364 * @join: the new join mode
366 * Sets a new line join mode.
369 adg_line_style_set_join (AdgLineStyle
*line_style
,
370 cairo_line_join_t join
)
372 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
374 line_style
->priv
->join
= join
;
375 g_object_notify ((GObject
*) line_style
, "join");
379 * adg_line_style_get_miter_limit:
380 * @line_style: an #AdgLineStyle object
382 * Gets the line miter limit value. The miter limit is used to determine
383 * whether the lines should be joined with a bevel instead of a miter.
385 * Return value: the requested miter limit
388 adg_line_style_get_miter_limit (AdgLineStyle
*line_style
)
390 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), 0.);
392 return line_style
->priv
->miter_limit
;
396 * adg_line_style_set_miter_limit:
397 * @line_style: an #AdgLineStyle object
398 * @miter_limit: the new miter limit
400 * Sets a new miter limit value.
403 adg_line_style_set_miter_limit (AdgLineStyle
*line_style
,
406 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
408 line_style
->priv
->miter_limit
= miter_limit
;
409 g_object_notify ((GObject
*) line_style
, "miter-limit");
413 * adg_line_style_get_antialias:
414 * @line_style: an #AdgLineStyle object
416 * Gets the antialias mode used.
418 * Return value: the requested antialias mode
421 adg_line_style_get_antialias (AdgLineStyle
*line_style
)
423 g_return_val_if_fail (ADG_IS_LINE_STYLE (line_style
), CAIRO_ANTIALIAS_DEFAULT
);
425 return line_style
->priv
->antialias
;
429 * adg_line_style_set_antialias:
430 * @line_style: an #AdgLineStyle object
431 * @antialias: the new antialias mode
433 * Sets a new antialias mode.
436 adg_line_style_set_antialias (AdgLineStyle
*line_style
,
437 cairo_antialias_t antialias
)
439 g_return_if_fail (ADG_IS_LINE_STYLE (line_style
));
441 line_style
->priv
->antialias
= antialias
;
442 g_object_notify ((GObject
*) line_style
, "antialias");