[build] Bumped version to 0.5.3
[adg.git] / adg / adg-fill-style.c
bloba3d33153703cbb9ec269e6c13f0f0b4a55f9d4d1
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.
21 /**
22 * SECTION:adg-fill-style
23 * @short_description: Generic pattern fill
25 * A style defining a generic fill based on cairo_pattern_t.
26 **/
28 /**
29 * AdgFillStyle:
31 * All fields are private and should not be used directly.
32 * Use its public methods instead.
33 **/
36 #include "adg-fill-style.h"
37 #include "adg-fill-style-private.h"
38 #include "adg-intl.h"
40 #define PARENT_STYLE_CLASS ((AdgStyleClass *) adg_fill_style_parent_class)
43 enum {
44 PROP_0,
45 PROP_PATTERN
49 static void finalize (GObject *object);
50 static void get_property (GObject *object,
51 guint prop_id,
52 GValue *value,
53 GParamSpec *pspec);
54 static void set_property (GObject *object,
55 guint prop_id,
56 const GValue *value,
57 GParamSpec *pspec);
58 static void apply (AdgStyle *style,
59 AdgEntity *entity,
60 cairo_t *cr);
61 static gboolean set_pattern (AdgFillStyle *fill_style,
62 AdgPattern *pattern);
63 static void set_extents (AdgFillStyle *fill_style,
64 const CpmlExtents *extents);
67 G_DEFINE_ABSTRACT_TYPE(AdgFillStyle, adg_fill_style, ADG_TYPE_STYLE);
70 static void
71 adg_fill_style_class_init(AdgFillStyleClass *klass)
73 GObjectClass *gobject_class;
74 AdgStyleClass *style_class;
75 GParamSpec *param;
77 gobject_class = (GObjectClass *) klass;
78 style_class = (AdgStyleClass *) klass;
80 g_type_class_add_private(klass, sizeof(AdgFillStylePrivate));
82 gobject_class->finalize = finalize;
83 gobject_class->get_property = get_property;
84 gobject_class->set_property = set_property;
86 style_class->apply = apply;
88 klass->set_extents = set_extents;
90 param = g_param_spec_boxed("pattern",
91 P_("Pattern"),
92 P_("The cairo pattern set for this entity"),
93 ADG_TYPE_PATTERN,
94 G_PARAM_READWRITE);
95 g_object_class_install_property(gobject_class, PROP_PATTERN, param);
98 static void
99 adg_fill_style_init(AdgFillStyle *fill_style)
101 AdgFillStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(fill_style,
102 ADG_TYPE_FILL_STYLE,
103 AdgFillStylePrivate);
105 data->pattern = NULL;
107 fill_style->data = data;
110 static void
111 finalize(GObject *object)
113 AdgFillStylePrivate *data = ((AdgFillStyle *) object)->data;
115 if (data->pattern != NULL) {
116 cairo_pattern_destroy(data->pattern);
117 data->pattern = NULL;
121 static void
122 get_property(GObject *object,
123 guint prop_id, GValue *value, GParamSpec *pspec)
125 AdgFillStylePrivate *data = ((AdgFillStyle *) object)->data;
127 switch (prop_id) {
128 case PROP_PATTERN:
129 g_value_set_boxed(value, data->pattern);
130 break;
131 default:
132 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
133 break;
137 static void
138 set_property(GObject *object,
139 guint prop_id, const GValue *value, GParamSpec *pspec)
141 AdgFillStyle *fill_style = (AdgFillStyle *) object;
143 switch (prop_id) {
144 case PROP_PATTERN:
145 set_pattern(fill_style, g_value_get_boxed(value));
146 break;
147 default:
148 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
149 break;
155 * adg_fill_style_get_pattern:
156 * @fill_style: an #AdgFillStyle
158 * Gets the current pattern binded to @fill_style.
160 * Returns: the current pattern
162 AdgPattern *
163 adg_fill_style_get_pattern(AdgFillStyle *fill_style)
165 AdgFillStylePrivate *data;
167 g_return_val_if_fail(ADG_IS_FILL_STYLE(fill_style), NULL);
169 data = fill_style->data;
171 return data->pattern;
175 * adg_fill_style_set_pattern:
176 * @fill_style: an #AdgFillStyle
177 * @pattern: the new pattern
179 * <note><para>
180 * This function is only useful in new fill implementations.
181 * </para></note>
183 * Sets a new pattern on @fill_style. A new reference is added to
184 * @pattern with cairo_pattern_reference() and the old pattern
185 * (if any) is unreferenced with cairo_pattern_destroy().
187 void
188 adg_fill_style_set_pattern(AdgFillStyle *fill_style, AdgPattern *pattern)
190 g_return_if_fail(ADG_IS_FILL_STYLE(fill_style));
192 if (set_pattern(fill_style, pattern))
193 g_object_notify((GObject *) fill_style, "pattern");
197 * adg_fill_style_get_extents:
198 * @fill_style: an #AdgFillStyle
199 * @extents: where to store the extents
201 * Stores a copy of the extents of @fill_style in @extents.
202 * This struct specifies the maximum portion (in global space)
203 * this fill style should be applied: it will clamped by the
204 * entities as needed.
206 void
207 adg_fill_style_get_extents(AdgFillStyle *fill_style, CpmlExtents *extents)
209 AdgFillStylePrivate *data;
211 g_return_if_fail(ADG_IS_FILL_STYLE(fill_style));
212 g_return_if_fail(extents != NULL);
214 data = fill_style->data;
216 cpml_extents_copy(extents, &data->extents);
220 * adg_fill_style_set_extents:
221 * @fill_style: an #AdgFillStyle
222 * @extents: the new extents
224 * <note><para>
225 * This function is only useful in new fill style implementations.
226 * </para></note>
228 * Forcibly sets new extents on @fill_style. Any fill style class
229 * that want to make some kind of customization can override the
230 * set_extents() virtual method to intercept any extents change.
232 * Sets new extents on @fill_style. These extents are usually set
233 * by the arrange() method of the entity using this filling style.
234 * The default implementation simply sets the extents, so the
235 * last one has precedence. Any fill style implementation can
236 * override the set_extents() implementation to customize this
237 * behavior, for example to keep the greatest boundary box instead
238 * of the last one.
240 void
241 adg_fill_style_set_extents(AdgFillStyle *fill_style,
242 const CpmlExtents *extents)
244 g_return_if_fail(ADG_IS_FILL_STYLE(fill_style));
245 g_return_if_fail(extents != NULL);
247 ADG_FILL_STYLE_GET_CLASS(fill_style)->set_extents(fill_style, extents);
251 static void
252 apply(AdgStyle *style, AdgEntity *entity, cairo_t *cr)
254 AdgFillStylePrivate *data = ((AdgFillStyle *) style)->data;
256 if (data->pattern == NULL)
257 g_warning("%s: pattern undefined for type `%s'",
258 G_STRLOC, g_type_name(G_OBJECT_TYPE(style)));
259 else
260 cairo_set_source(cr, data->pattern);
263 static gboolean
264 set_pattern(AdgFillStyle *fill_style, AdgPattern *pattern)
266 AdgFillStylePrivate *data = fill_style->data;
268 if (pattern == data->pattern)
269 return FALSE;
271 if (data->pattern != NULL)
272 cairo_pattern_destroy(data->pattern);
274 data->pattern = pattern;
276 if (data->pattern != NULL)
277 cairo_pattern_reference(data->pattern);
279 return TRUE;
282 static void
283 set_extents(AdgFillStyle *fill_style, const CpmlExtents *extents)
285 AdgFillStylePrivate *data = fill_style->data;
287 cpml_extents_copy(&data->extents, extents);