]> git.sur5r.net Git - glabels/blob - src/label-box.c
Imported Upstream version 2.2.8
[glabels] / src / label-box.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  label_box.c:  GLabels label box object
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24
25 #include "label-box.h"
26
27 #include <glib/gmem.h>
28 #include <glib/gstrfuncs.h>
29 #include <glib/gmessages.h>
30
31 #include "debug.h"
32
33 /*========================================================*/
34 /* Private types.                                         */
35 /*========================================================*/
36
37 struct _glLabelBoxPrivate {
38         gdouble          line_width;
39         glColorNode      *line_color_node;
40         glColorNode      *fill_color_node;
41 };
42
43 /*========================================================*/
44 /* Private globals.                                       */
45 /*========================================================*/
46
47 /*========================================================*/
48 /* Private function prototypes.                           */
49 /*========================================================*/
50
51 static void    gl_label_box_finalize      (GObject         *object);
52
53 static void    copy                       (glLabelObject   *dst_object,
54                                            glLabelObject   *src_object);
55
56 static void    set_fill_color             (glLabelObject   *object,
57                                            glColorNode     *fill_color_node);
58
59 static void    set_line_color             (glLabelObject   *object,
60                                            glColorNode     *line_color_node);
61
62 static void    set_line_width             (glLabelObject   *object,
63                                            gdouble          line_width);
64
65 static glColorNode*   get_fill_color      (glLabelObject   *object);
66
67 static glColorNode*   get_line_color      (glLabelObject   *object);
68
69 static gdouble get_line_width             (glLabelObject   *object);
70
71 static void    draw_object                (glLabelObject     *object,
72                                            cairo_t           *cr,
73                                            gboolean           screen_flag,
74                                            glMergeRecord     *record);
75
76 static void    draw_shadow                (glLabelObject     *object,
77                                            cairo_t           *cr,
78                                            gboolean           screen_flag,
79                                            glMergeRecord     *record);
80
81
82
83
84 \f
85 /*****************************************************************************/
86 /* Boilerplate object stuff.                                                 */
87 /*****************************************************************************/
88 G_DEFINE_TYPE (glLabelBox, gl_label_box, GL_TYPE_LABEL_OBJECT);
89
90 static void
91 gl_label_box_class_init (glLabelBoxClass *class)
92 {
93         GObjectClass       *object_class       = G_OBJECT_CLASS (class);
94         glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
95
96         gl_label_box_parent_class = g_type_class_peek_parent (class);
97
98         label_object_class->copy           = copy;
99         label_object_class->set_fill_color = set_fill_color;
100         label_object_class->set_line_color = set_line_color;
101         label_object_class->set_line_width = set_line_width;
102         label_object_class->get_fill_color = get_fill_color;
103         label_object_class->get_line_color = get_line_color;
104         label_object_class->get_line_width = get_line_width;
105         label_object_class->draw_object    = draw_object;
106         label_object_class->draw_shadow    = draw_shadow;
107
108         object_class->finalize = gl_label_box_finalize;
109 }
110
111 static void
112 gl_label_box_init (glLabelBox *lbox)
113 {
114         lbox->priv = g_new0 (glLabelBoxPrivate, 1);
115         lbox->priv->line_color_node = gl_color_node_new_default ();
116         lbox->priv->fill_color_node = gl_color_node_new_default ();
117 }
118
119 static void
120 gl_label_box_finalize (GObject *object)
121 {
122         glLabelBox *lbox = GL_LABEL_BOX (object);
123
124         g_return_if_fail (object && GL_IS_LABEL_BOX (object));
125
126         gl_color_node_free (&(lbox->priv->fill_color_node));
127         gl_color_node_free (&(lbox->priv->line_color_node));
128         g_free (lbox->priv);
129
130         G_OBJECT_CLASS (gl_label_box_parent_class)->finalize (object);
131 }
132
133 /*****************************************************************************/
134 /* NEW label "box" object.                                                   */
135 /*****************************************************************************/
136 GObject *
137 gl_label_box_new (glLabel *label)
138 {
139         glLabelBox *lbox;
140
141         lbox = g_object_new (gl_label_box_get_type(), NULL);
142
143         gl_label_object_set_parent (GL_LABEL_OBJECT(lbox), label);
144
145         return G_OBJECT (lbox);
146 }
147
148 /*****************************************************************************/
149 /* Copy object contents.                                                     */
150 /*****************************************************************************/
151 static void
152 copy (glLabelObject *dst_object,
153       glLabelObject *src_object)
154 {
155         glLabelBox  *lbox     = (glLabelBox *)src_object;
156         glLabelBox  *new_lbox = (glLabelBox *)dst_object;
157         gdouble      line_width;
158         glColorNode *line_color_node;
159         glColorNode *fill_color_node;
160
161         gl_debug (DEBUG_LABEL, "START");
162
163         g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
164         g_return_if_fail (new_lbox && GL_IS_LABEL_BOX (new_lbox));
165
166         line_width = get_line_width (src_object);
167         line_color_node = get_line_color (src_object);
168         fill_color_node = get_fill_color (src_object);
169
170         set_line_width (dst_object, line_width);
171         set_line_color (dst_object, line_color_node);
172         set_fill_color (dst_object, fill_color_node);
173         
174         gl_color_node_free (&line_color_node);
175         gl_color_node_free (&fill_color_node);
176
177         gl_debug (DEBUG_LABEL, "END");
178 }
179
180
181 /*---------------------------------------------------------------------------*/
182 /* PRIVATE.  Set fill color method.                                          */
183 /*---------------------------------------------------------------------------*/
184 static void
185 set_fill_color (glLabelObject *object,
186                 glColorNode   *fill_color_node)
187 {
188         glLabelBox *lbox = (glLabelBox *)object;
189         
190         gl_debug (DEBUG_LABEL, "START");
191
192         g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
193
194         if (!gl_color_node_equal (lbox->priv->fill_color_node, fill_color_node)) {
195
196                 gl_color_node_free (&(lbox->priv->fill_color_node));
197                 lbox->priv->fill_color_node = gl_color_node_dup (fill_color_node);
198
199                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
200         }
201         gl_debug (DEBUG_LABEL, "END");
202 }
203
204 /*---------------------------------------------------------------------------*/
205 /* PRIVATE.  Set line color method.                                          */
206 /*---------------------------------------------------------------------------*/
207 static void
208 set_line_color (glLabelObject *object,
209                 glColorNode   *line_color_node)
210 {
211         glLabelBox *lbox = (glLabelBox *)object;
212
213         g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
214
215         if ( !gl_color_node_equal (lbox->priv->line_color_node, line_color_node )) {
216                 gl_color_node_free (&(lbox->priv->line_color_node));
217                 lbox->priv->line_color_node = gl_color_node_dup (line_color_node);
218                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
219         }
220 }
221
222 /*---------------------------------------------------------------------------*/
223 /* PRIVATE.  Set line width method.                                          */
224 /*---------------------------------------------------------------------------*/
225 static void
226 set_line_width (glLabelObject *object,
227                 gdouble        line_width)
228 {
229         glLabelBox *lbox = (glLabelBox *)object;
230
231         g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
232
233         if ( lbox->priv->line_width != line_width ) {
234                 lbox->priv->line_width = line_width;
235                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
236         }
237 }
238
239
240 /*---------------------------------------------------------------------------*/
241 /* PRIVATE.  Get fill color method.                                          */
242 /*---------------------------------------------------------------------------*/
243 static gdouble
244 get_line_width (glLabelObject *object)
245 {
246         glLabelBox *lbox = (glLabelBox *)object;
247
248         g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0.0);
249
250         return lbox->priv->line_width;
251 }
252
253 /*---------------------------------------------------------------------------*/
254 /* PRIVATE.  Get line color method.                                          */
255 /*---------------------------------------------------------------------------*/
256 static glColorNode*
257 get_line_color (glLabelObject *object)
258 {
259         glLabelBox *lbox = (glLabelBox *)object;
260
261         g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0);
262
263         return gl_color_node_dup (lbox->priv->line_color_node);
264 }
265
266 /*---------------------------------------------------------------------------*/
267 /* PRIVATE.  Get line width method.                                          */
268 /*---------------------------------------------------------------------------*/
269 static glColorNode*
270 get_fill_color (glLabelObject *object)
271 {
272         glLabelBox *lbox = (glLabelBox *)object;
273
274         g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0);
275
276         return gl_color_node_dup (lbox->priv->fill_color_node);
277 }
278
279 /*****************************************************************************/
280 /* Draw object method.                                                       */
281 /*****************************************************************************/
282 static void
283 draw_object (glLabelObject *object,
284              cairo_t       *cr,
285              gboolean       screen_flag,
286              glMergeRecord *record)
287 {
288         gdouble        w, h;
289         gdouble        line_width;
290         glColorNode   *line_color_node;
291         glColorNode   *fill_color_node;
292         guint          line_color;
293         guint          fill_color;
294
295         gl_debug (DEBUG_LABEL, "START");
296
297         gl_label_object_get_size (object, &w, &h);
298
299         line_width = gl_label_object_get_line_width (object);
300         
301         line_color_node = gl_label_object_get_line_color (object);
302         fill_color_node = gl_label_object_get_fill_color (object);
303         line_color = gl_color_node_expand (line_color_node, record);
304         fill_color = gl_color_node_expand (fill_color_node, record);
305         if (line_color_node->field_flag && screen_flag)
306         {
307                 line_color = GL_COLOR_MERGE_DEFAULT;
308         }
309         if (fill_color_node->field_flag && screen_flag)
310         {
311                 fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
312         }
313
314
315         cairo_rectangle (cr, 0.0, 0.0, w, h);
316
317         /* Paint fill color */
318         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
319         cairo_fill_preserve (cr);
320
321         /* Draw outline */
322         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
323         cairo_set_line_width (cr, line_width);
324         cairo_stroke (cr);
325
326         gl_color_node_free (&line_color_node);
327         gl_color_node_free (&fill_color_node);
328
329         gl_debug (DEBUG_LABEL, "END");
330 }
331
332 /*****************************************************************************/
333 /* Draw shadow method.                                                       */
334 /*****************************************************************************/
335 static void
336 draw_shadow (glLabelObject *object,
337              cairo_t       *cr,
338              gboolean       screen_flag,
339              glMergeRecord *record)
340 {
341         gdouble        w, h;
342         gdouble        line_width;
343         glColorNode   *line_color_node;
344         glColorNode   *fill_color_node;
345         guint          line_color;
346         guint          fill_color;
347         glColorNode   *shadow_color_node;
348         guint          shadow_color;
349         gdouble        shadow_opacity;
350         guint          shadow_line_color;
351         guint          shadow_fill_color;
352
353         gl_debug (DEBUG_LABEL, "START");
354
355         gl_label_object_get_size (object, &w, &h);
356
357         line_width = gl_label_object_get_line_width (object);
358         
359         line_color_node = gl_label_object_get_line_color (object);
360         fill_color_node = gl_label_object_get_fill_color (object);
361         line_color = gl_color_node_expand (line_color_node, record);
362         fill_color = gl_color_node_expand (fill_color_node, record);
363         if (line_color_node->field_flag && screen_flag)
364         {
365                 line_color = GL_COLOR_MERGE_DEFAULT;
366         }
367         if (fill_color_node->field_flag && screen_flag)
368         {
369                 fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
370         }
371
372         shadow_color_node = gl_label_object_get_shadow_color (object);
373         shadow_color = gl_color_node_expand (shadow_color_node, record);
374         if (shadow_color_node->field_flag && screen_flag)
375         {
376                 shadow_color = GL_COLOR_SHADOW_MERGE_DEFAULT;
377         }
378         shadow_opacity = gl_label_object_get_shadow_opacity (object);
379         shadow_line_color = gl_color_shadow (shadow_color, shadow_opacity, line_color_node->color);
380         shadow_fill_color = gl_color_shadow (shadow_color, shadow_opacity, fill_color_node->color);
381         
382
383         cairo_rectangle (cr, 0.0, 0.0, w, h);
384
385
386         /* Draw fill shadow */
387         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_fill_color));
388         cairo_fill_preserve (cr);
389
390         /* Draw outline shadow */
391         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_line_color));
392         cairo_set_line_width (cr, line_width);
393         cairo_stroke (cr);
394
395
396         gl_color_node_free (&line_color_node);
397         gl_color_node_free (&fill_color_node);
398         gl_color_node_free (&shadow_color_node);
399
400         gl_debug (DEBUG_LABEL, "END");
401 }
402