[AdgStroke] Using adg_entity_apply_local_matrix()
[adg.git] / adg / adg-style.c
blob77c292c8d2e0cfafa86ca544b0ed04b46ebd5d8e
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-style
23 * @short_description: The base class of all styling objects
25 * This is the fundamental abstract class from which all customization object
26 * must be derived.
29 /**
30 * AdgStyle:
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
34 **/
37 #include "adg-style.h"
38 #include "adg-style-private.h"
39 #include "adg-line-style.h"
40 #include "adg-font-style.h"
41 #include "adg-arrow-style.h"
42 #include "adg-enums.h"
43 #include "adg-util.h"
44 #include "adg-intl.h"
46 #include <string.h>
49 enum {
50 PROP_0,
51 PROP_PATTERN
55 static void get_property (GObject *object,
56 guint prop_id,
57 GValue *value,
58 GParamSpec *pspec);
59 static void set_property (GObject *object,
60 guint prop_id,
61 const GValue *value,
62 GParamSpec *pspec);
63 static GPtrArray * get_pool (void);
64 static void apply (AdgStyle *style,
65 cairo_t *cr);
66 static void set_pattern (AdgStyle *style,
67 AdgPattern *pattern);
70 G_DEFINE_ABSTRACT_TYPE(AdgStyle, adg_style, G_TYPE_OBJECT)
73 static void
74 adg_style_class_init(AdgStyleClass *klass)
76 GObjectClass *gobject_class;
77 GParamSpec *param;
79 gobject_class = (GObjectClass *) klass;
81 g_type_class_add_private(klass, sizeof(AdgStylePrivate));
83 gobject_class->get_property = get_property;
84 gobject_class->set_property = set_property;
86 klass->get_pool = get_pool;
87 klass->apply = apply;
89 param = g_param_spec_boxed("pattern",
90 P_("Pattern"),
91 P_("The pattern associated to this style"),
92 ADG_TYPE_PATTERN, G_PARAM_READWRITE);
93 g_object_class_install_property(gobject_class, PROP_PATTERN, param);
96 static void
97 adg_style_init(AdgStyle *style)
99 AdgStylePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(style,
100 ADG_TYPE_STYLE,
101 AdgStylePrivate);
103 data->pattern = NULL;
105 style->data = data;
108 static void
109 get_property(GObject *object,
110 guint prop_id, GValue *value, GParamSpec *pspec)
112 AdgStylePrivate *data = ((AdgStyle *) object)->data;
114 switch (prop_id) {
115 case PROP_PATTERN:
116 g_value_set_boxed(value, data->pattern);
117 break;
118 default:
119 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
120 break;
124 static void
125 set_property(GObject *object,
126 guint prop_id, const GValue *value, GParamSpec *pspec)
128 AdgStyle *style = (AdgStyle *) object;
130 switch (prop_id) {
131 case PROP_PATTERN:
132 set_pattern(style, g_value_get_boxed(value));
133 break;
134 default:
135 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
136 break;
142 * adg_style_register_id:
143 * @style: an #AdgStyle derived instance
145 * Registers a new style in the internal register.
147 * Returns: the new id associated to this style or %0 on errors
149 AdgStyleId
150 adg_style_register_id(AdgStyle *style)
152 GPtrArray *pool;
154 g_return_val_if_fail(ADG_IS_STYLE(style), 0);
156 pool = ADG_STYLE_GET_CLASS(style)->get_pool();
157 g_return_val_if_fail(pool != NULL, 0);
159 g_ptr_array_add(pool, style);
161 return pool->len - 1;
165 * adg_style_from_id:
166 * @type: the style type id
167 * @id: the id to get
169 * Gets the preregistered style identified by @id of @style family.
171 * Returns: the requested style or %NULL on errors
173 AdgStyle *
174 adg_style_from_id(GType type, AdgStyleId id)
176 AdgStyleClass *klass;
177 GPtrArray *pool;
179 klass = g_type_class_ref(type);
180 g_return_val_if_fail(ADG_IS_STYLE_CLASS(klass), NULL);
181 pool = klass->get_pool();
183 /* If @type is valid, @klass will be referenced by the pool items */
184 g_type_class_unref(klass);
186 if (id > pool->len)
187 return NULL;
189 return (AdgStyle *) g_ptr_array_index(pool, id);
192 AdgStyle *
193 adg_style_get_default(AdgStyleClass *klass)
195 GPtrArray *pool;
197 g_return_val_if_fail(ADG_IS_STYLE_CLASS(klass), NULL);
199 pool = klass->get_pool();
200 return (AdgStyle *) g_ptr_array_index(pool, 0);
204 * adg_style_apply:
205 * @style: an #AdgStyle derived object
206 * @cr: the cairo context
208 * Applies @style to @cr so the next rendering will be done accordling to
209 * this style directives.
211 void
212 adg_style_apply(AdgStyle *style, cairo_t *cr)
214 g_return_if_fail(ADG_IS_STYLE(style));
215 g_return_if_fail(cr != NULL);
217 return ADG_STYLE_GET_CLASS(style)->apply(style, cr);
221 * adg_style_get_pattern:
222 * @style: an #AdgStyle object
224 * Gets the pattern binded to this style. The returned pattern refers to
225 * an internally managed struct that must not be modified or freed.
227 * Returns: the requested pattern or %NULL on no pattern or errors
229 const AdgPattern *
230 adg_style_get_pattern(AdgStyle *style)
232 AdgStylePrivate *data;
234 g_return_val_if_fail(ADG_IS_STYLE(style), NULL);
236 data = style->data;
238 return data->pattern;
242 * adg_style_set_pattern:
243 * @style: an #AdgStyle object
244 * @pattern: the new pattern
246 * Sets a new pattern for this style. This operation will release one
247 * reference on the old pattern (if any) and will add a new reference
248 * to @pattern.
250 * A %NULL pattern is allowed: it means the previous pattern is kept
251 * during the rendering process.
253 void
254 adg_style_set_pattern(AdgStyle *style, AdgPattern *pattern)
256 g_return_if_fail(ADG_IS_STYLE(style));
257 g_return_if_fail(pattern != NULL);
259 set_pattern(style, pattern);
260 g_object_notify((GObject *) style, "pattern");
264 static GPtrArray *
265 get_pool(void)
267 g_warning("Uninmplemented get_pool()");
268 return NULL;
271 static void
272 apply(AdgStyle *style, cairo_t *cr)
274 AdgStylePrivate *data = style->data;
276 if (data->pattern != NULL)
277 cairo_set_source(cr, data->pattern);
280 static void
281 set_pattern(AdgStyle *style, AdgPattern *pattern)
283 AdgStylePrivate *data = style->data;
285 if (data->pattern != NULL)
286 cairo_pattern_destroy(data->pattern);
288 if (pattern != NULL)
289 cairo_pattern_reference(pattern);
291 data->pattern = pattern;