]> git.sur5r.net Git - glabels/blob - glabels2/src/label-object.c
89cefc98a9e3568f1c0d51789f831373cb6c0896
[glabels] / glabels2 / src / label-object.c
1 /*
2  *  label-object.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "label-object.h"
24
25 #include <glib.h>
26 #include <math.h>
27
28 #include "marshal.h"
29
30 #include "debug.h"
31
32
33 /*========================================================*/
34 /* Private defines.                                       */
35 /*========================================================*/
36
37 #define DEFAULT_SHADOW_X_OFFSET (3.6)
38 #define DEFAULT_SHADOW_Y_OFFSET (3.6)
39 #define DEFAULT_SHADOW_OPACITY  (0.5)
40
41
42 /*========================================================*/
43 /* Private types.                                         */
44 /*========================================================*/
45
46 struct _glLabelObjectPrivate {
47         gchar             *name;
48         gdouble            x, y;
49         gdouble            w, h;
50         cairo_matrix_t     matrix;
51
52         gdouble            aspect_ratio;
53
54         gboolean           shadow_state;
55         gdouble            shadow_x;
56         gdouble            shadow_y;
57         glColorNode       *shadow_color_node;
58         gdouble            shadow_opacity;
59 };
60
61 enum {
62         CHANGED,
63         MOVED,
64         FLIP_ROTATE,
65         TOP,
66         BOTTOM,
67         REMOVED,
68         LAST_SIGNAL
69 };
70
71
72 /*========================================================*/
73 /* Private globals.                                       */
74 /*========================================================*/
75
76 static guint signals[LAST_SIGNAL] = {0};
77
78 static guint instance = 0;
79
80
81 /*========================================================*/
82 /* Private function prototypes.                           */
83 /*========================================================*/
84
85 static void gl_label_object_finalize      (GObject            *object);
86
87 static void merge_changed_cb              (glLabel            *label,
88                                            glLabelObject      *object);
89
90 static void set_size                      (glLabelObject      *object,
91                                            gdouble             w,
92                                            gdouble             h);
93
94
95 /*****************************************************************************/
96 /* Boilerplate object stuff.                                                 */
97 /*****************************************************************************/
98 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT);
99
100
101 static void
102 gl_label_object_class_init (glLabelObjectClass *class)
103 {
104         GObjectClass       *object_class = G_OBJECT_CLASS (class);
105
106         gl_debug (DEBUG_LABEL, "START");
107
108         gl_label_object_parent_class = g_type_class_peek_parent (class);
109
110         object_class->finalize = gl_label_object_finalize;
111
112         class->set_size = set_size;
113
114         signals[CHANGED] =
115                 g_signal_new ("changed",
116                               G_OBJECT_CLASS_TYPE (object_class),
117                               G_SIGNAL_RUN_LAST,
118                               G_STRUCT_OFFSET (glLabelObjectClass, changed),
119                               NULL, NULL,
120                               gl_marshal_VOID__VOID,
121                               G_TYPE_NONE,
122                               0);
123
124         signals[MOVED] =
125                 g_signal_new ("moved",
126                               G_OBJECT_CLASS_TYPE (object_class),
127                               G_SIGNAL_RUN_LAST,
128                               G_STRUCT_OFFSET (glLabelObjectClass, moved),
129                               NULL, NULL,
130                               gl_marshal_VOID__DOUBLE_DOUBLE,
131                               G_TYPE_NONE,
132                               2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
133         signals[FLIP_ROTATE] =
134                 g_signal_new ("flip_rotate",
135                               G_OBJECT_CLASS_TYPE (object_class),
136                               G_SIGNAL_RUN_LAST,
137                               G_STRUCT_OFFSET (glLabelObjectClass, flip_rotate),
138                               NULL, NULL,
139                               gl_marshal_VOID__VOID,
140                               G_TYPE_NONE,
141                               0);
142         signals[TOP] =
143                 g_signal_new ("top",
144                               G_OBJECT_CLASS_TYPE (object_class),
145                               G_SIGNAL_RUN_LAST,
146                               G_STRUCT_OFFSET (glLabelObjectClass, top),
147                               NULL, NULL,
148                               gl_marshal_VOID__VOID,
149                               G_TYPE_NONE,
150                               0);
151
152         signals[BOTTOM] =
153                 g_signal_new ("bottom",
154                               G_OBJECT_CLASS_TYPE (object_class),
155                               G_SIGNAL_RUN_LAST,
156                               G_STRUCT_OFFSET (glLabelObjectClass, bottom),
157                               NULL, NULL,
158                               gl_marshal_VOID__VOID,
159                               G_TYPE_NONE,
160                               0);
161         signals[REMOVED] =
162                 g_signal_new ("removed",
163                               G_OBJECT_CLASS_TYPE (object_class),
164                               G_SIGNAL_RUN_LAST,
165                               G_STRUCT_OFFSET (glLabelObjectClass, removed),
166                               NULL, NULL,
167                               gl_marshal_VOID__VOID,
168                               G_TYPE_NONE,
169                               0);
170
171         gl_debug (DEBUG_LABEL, "END");
172 }
173
174
175 static void
176 gl_label_object_init (glLabelObject *object)
177 {
178         gl_debug (DEBUG_LABEL, "START");
179
180         object->priv = g_new0 (glLabelObjectPrivate, 1);
181
182         object->priv->name = g_strdup_printf ("object%d", instance++);
183
184         cairo_matrix_init_identity (&object->priv->matrix);
185
186         object->priv->shadow_state = FALSE;
187         object->priv->shadow_x = DEFAULT_SHADOW_X_OFFSET;
188         object->priv->shadow_y = DEFAULT_SHADOW_Y_OFFSET;
189         object->priv->shadow_color_node = gl_color_node_new_default ();
190         object->priv->shadow_opacity = DEFAULT_SHADOW_OPACITY;
191
192         gl_debug (DEBUG_LABEL, "END");
193 }
194
195
196 static void
197 gl_label_object_finalize (GObject *object)
198 {
199         glLabelObject *label_object = GL_LABEL_OBJECT (object);
200
201         gl_debug (DEBUG_LABEL, "START");
202
203         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
204
205         g_free (label_object->priv->name);
206         g_free (label_object->priv);
207
208         G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
209
210         gl_debug (DEBUG_LABEL, "END");
211 }
212
213
214 /*****************************************************************************/
215 /* New label object.                                                         */
216 /*****************************************************************************/
217 GObject *
218 gl_label_object_new (glLabel *label)
219 {
220         glLabelObject *object;
221
222         gl_debug (DEBUG_LABEL, "START");
223
224         object = g_object_new (gl_label_object_get_type(), NULL);
225
226         gl_label_object_set_parent (object, label);
227
228         gl_debug (DEBUG_LABEL, "END");
229
230         return G_OBJECT (object);
231 }
232
233
234 /*****************************************************************************/
235 /* Duplicate object.                                                         */
236 /*****************************************************************************/
237 glLabelObject *
238 gl_label_object_dup (glLabelObject *src_object,
239                      glLabel       *label)
240 {
241         glLabelObject    *dst_object;
242         gdouble           x, y, w, h;
243         cairo_matrix_t    matrix;
244         gboolean          shadow_state;
245         gdouble           shadow_x, shadow_y;
246         glColorNode      *shadow_color_node;
247         gdouble           shadow_opacity;
248
249         gl_debug (DEBUG_LABEL, "START");
250
251         g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
252
253         dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
254
255         gl_label_object_set_parent (dst_object, label);
256
257         gl_label_object_get_position      (src_object, &x, &y);
258         gl_label_object_get_size          (src_object, &w, &h);
259         gl_label_object_get_matrix        (src_object, &matrix);
260         gl_label_object_get_shadow_offset (src_object, &shadow_x, &shadow_y);
261         shadow_color_node = gl_label_object_get_shadow_color   (src_object);
262         shadow_opacity    = gl_label_object_get_shadow_opacity (src_object);
263         shadow_state      = gl_label_object_get_shadow_state   (src_object);
264
265         gl_label_object_set_position (dst_object, x, y);
266         gl_label_object_set_size     (dst_object, w, h);
267         gl_label_object_set_matrix   (dst_object, &matrix);
268         gl_label_object_set_shadow_offset  (dst_object, shadow_x, shadow_y);
269         gl_label_object_set_shadow_color   (dst_object, shadow_color_node);
270         gl_label_object_set_shadow_opacity (dst_object, shadow_opacity);
271         gl_label_object_set_shadow_state   (dst_object, shadow_state);
272
273         gl_color_node_free (&shadow_color_node);
274
275         if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL ) {
276
277                 /* We have an object specific method, use it */
278                 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
279
280         }
281
282         gl_debug (DEBUG_LABEL, "END");
283
284         return dst_object;
285 }
286
287
288 /*****************************************************************************/
289 /* Emit "changed" signal (for derived objects).                              */
290 /*****************************************************************************/
291 void
292 gl_label_object_emit_changed (glLabelObject *object)
293 {
294         gl_debug (DEBUG_LABEL, "START");
295
296         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
297
298         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
299
300         gl_debug (DEBUG_LABEL, "END");
301 }
302
303
304 /*****************************************************************************/
305 /* Set parent label of object.                                               */
306 /*****************************************************************************/
307 void
308 gl_label_object_set_parent (glLabelObject *object,
309                             glLabel       *label)
310 {
311         glLabel *old_parent;
312
313         gl_debug (DEBUG_LABEL, "START");
314
315         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
316         g_return_if_fail (label && GL_IS_LABEL (label));
317
318         old_parent = object->parent;
319         if ( old_parent != NULL ) {
320                 g_signal_handlers_disconnect_by_func (old_parent,
321                                                       G_CALLBACK(merge_changed_cb),
322                                                       object);
323                 gl_label_remove_object( old_parent, object );
324         }
325         gl_label_add_object( label, object );
326
327         g_signal_connect (G_OBJECT(label), "merge_changed",
328                           G_CALLBACK(merge_changed_cb), object);
329
330         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
331
332         gl_debug (DEBUG_LABEL, "END");
333 }
334
335
336 /*****************************************************************************/
337 /* Get parent label of object.                                               */
338 /*****************************************************************************/
339 glLabel *
340 gl_label_object_get_parent (glLabelObject *object)
341 {
342         gl_debug (DEBUG_LABEL, "START");
343
344         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
345
346         gl_debug (DEBUG_LABEL, "END");
347
348         return object->parent;
349 }
350
351
352 /*****************************************************************************/
353 /* Set remove object from parent.                                            */
354 /*****************************************************************************/
355 void
356 gl_label_object_remove (glLabelObject *object)
357 {
358         glLabel *parent;
359
360         gl_debug (DEBUG_LABEL, "START");
361
362         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
363
364         parent = object->parent;
365         if ( parent != NULL ) {
366                 g_signal_handlers_disconnect_by_func (parent,
367                                                       G_CALLBACK(merge_changed_cb),
368                                                       object);
369                 gl_label_remove_object (parent, object);
370
371                 g_signal_emit (G_OBJECT(object), signals[REMOVED], 0);
372
373                 g_object_unref (G_OBJECT(object));
374         }
375
376
377         gl_debug (DEBUG_LABEL, "END");
378 }
379
380
381 /*****************************************************************************/
382 /* Set name of object.                                                       */
383 /*****************************************************************************/
384 void
385 gl_label_object_set_name (glLabelObject *object,
386                           gchar         *name)
387 {
388         gl_debug (DEBUG_LABEL, "START");
389
390         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
391
392         g_free(object->priv->name);
393         object->priv->name = name;
394
395         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
396
397         gl_debug (DEBUG_LABEL, "END");
398 }
399
400
401 /*****************************************************************************/
402 /* Get name of object.                                                       */
403 /*****************************************************************************/
404 gchar *
405 gl_label_object_get_name (glLabelObject *object)
406 {
407         gl_debug (DEBUG_LABEL, "START");
408
409         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
410
411         gl_debug (DEBUG_LABEL, "END");
412
413         return g_strdup(object->priv->name);
414 }
415
416
417 /*****************************************************************************/
418 /* Set position of object.                                                   */
419 /*****************************************************************************/
420 void
421 gl_label_object_set_position (glLabelObject *object,
422                               gdouble        x,
423                               gdouble        y)
424 {
425         gdouble dx, dy;
426
427         gl_debug (DEBUG_LABEL, "START");
428
429         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
430
431         if ( (x != object->priv->x) || (y != object->priv->y) ) {
432
433                 dx = x - object->priv->x;
434                 dy = y - object->priv->y;
435
436                 object->priv->x = x;
437                 object->priv->y = y;
438
439                 g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
440
441         }
442
443         gl_debug (DEBUG_LABEL, "END");
444 }
445
446
447 /*****************************************************************************/
448 /* Set position of object relative to old position.                          */
449 /*****************************************************************************/
450 void
451 gl_label_object_set_position_relative (glLabelObject *object,
452                                        gdouble        dx,
453                                        gdouble        dy)
454 {
455         gl_debug (DEBUG_LABEL, "START");
456
457         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
458
459         if ( (dx != 0.0) || (dy != 0.0) ) {
460
461                 object->priv->x += dx;
462                 object->priv->y += dy;
463
464                 gl_debug (DEBUG_LABEL, "       x = %f, y= %f",
465                           object->priv->x,
466                           object->priv->y);
467
468                 g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
469
470         }
471
472         gl_debug (DEBUG_LABEL, "END");
473 }
474
475
476 /*****************************************************************************/
477 /* Get position of object.                                                   */
478 /*****************************************************************************/
479 void
480 gl_label_object_get_position (glLabelObject *object,
481                               gdouble       *x,
482                               gdouble       *y)
483 {
484         gl_debug (DEBUG_LABEL, "START");
485
486         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
487
488         *x = object->priv->x;
489         *y = object->priv->y;
490
491         gl_debug (DEBUG_LABEL, "END");
492 }
493
494
495 /*---------------------------------------------------------------------------*/
496 /* PRIVATE.  Default set size method.                                        */
497 /*---------------------------------------------------------------------------*/
498 static void
499 set_size (glLabelObject *object,
500           gdouble        w,
501           gdouble        h)
502 {
503         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
504
505         if ( (object->priv->w != w) || (object->priv->h != h) ) {
506
507                 object->priv->w = w;
508                 object->priv->h = h;
509
510                 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
511         }
512 }
513
514
515 /*****************************************************************************/
516 /* Set size of object.                                                       */
517 /*****************************************************************************/
518 void
519 gl_label_object_set_size (glLabelObject *object,
520                           gdouble        w,
521                           gdouble        h)
522 {
523         gl_debug (DEBUG_LABEL, "START");
524
525         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
526
527         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
528
529                 /* We have an object specific method, use it */
530                 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
531
532                 object->priv->aspect_ratio = h / w;
533
534         }
535
536
537         gl_debug (DEBUG_LABEL, "END");
538 }
539
540
541 /*****************************************************************************/
542 /* Set size of object honoring current aspect ratio.                         */
543 /*****************************************************************************/
544 void
545 gl_label_object_set_size_honor_aspect (glLabelObject *object,
546                                        gdouble        w,
547                                        gdouble        h)
548 {
549         gl_debug (DEBUG_LABEL, "START");
550
551         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
552
553         if ( h > w*object->priv->aspect_ratio ) {
554
555                 h = w * object->priv->aspect_ratio;
556
557         } else {
558
559                 w = h / object->priv->aspect_ratio;
560
561         }
562
563         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
564
565                 /* We have an object specific method, use it */
566                 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
567
568         }
569
570         gl_debug (DEBUG_LABEL, "END");
571 }
572
573
574 /*****************************************************************************/
575 /* Get raw size method (don't let object content adjust size).               */
576 /*****************************************************************************/
577 void
578 gl_label_object_get_raw_size (glLabelObject *object,
579                               gdouble       *w,
580                               gdouble       *h)
581 {
582         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
583
584         *w = object->priv->w;
585         *h = object->priv->h;
586 }
587
588
589 /*****************************************************************************/
590 /* Get size of object.                                                       */
591 /*****************************************************************************/
592 void
593 gl_label_object_get_size (glLabelObject *object,
594                           gdouble       *w,
595                           gdouble       *h)
596 {
597         gl_debug (DEBUG_LABEL, "START");
598
599         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
600
601         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL ) {
602
603                 /* We have an object specific method, use it */
604                 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
605
606         } else {
607
608                 gl_label_object_get_raw_size (object, w, h);
609
610         }
611
612         gl_debug (DEBUG_LABEL, "END");
613 }
614
615
616 /*****************************************************************************/
617 /* Get extent of object.                                                     */
618 /*****************************************************************************/
619 void
620 gl_label_object_get_extent (glLabelObject *object,
621                             glLabelRegion *region)
622 {
623         gdouble        w, h;
624         gdouble        line_w;
625         gdouble        xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
626         cairo_matrix_t matrix;
627
628         gl_debug (DEBUG_LABEL, "START");
629
630         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
631
632         gl_label_object_get_size (object, &w, &h);
633         line_w = gl_label_object_get_line_width (object);
634
635         /* setup untransformed corners of bounding box, account for line width */
636         xa1 =   - line_w/2;
637         ya1 =   - line_w/2;
638         xa2 = w + line_w/2;
639         ya2 =   - line_w/2;
640         xa3 = w + line_w/2;
641         ya3 = h + line_w/2;
642         xa4 =   - line_w/2;
643         ya4 = h + line_w/2;
644
645         /* transform these points */
646         gl_label_object_get_matrix (object, &matrix);
647         cairo_matrix_transform_point (&matrix, &xa1, &ya1);
648         cairo_matrix_transform_point (&matrix, &xa2, &ya2);
649         cairo_matrix_transform_point (&matrix, &xa3, &ya3);
650         cairo_matrix_transform_point (&matrix, &xa4, &ya4);
651
652         /* now find the maximum extent of these points in x and y */
653         region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
654         region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
655         region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
656         region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
657
658         gl_debug (DEBUG_LABEL, "END");
659 }
660
661
662 /*****************************************************************************/
663 /* Can text properties be set for this object?                               */
664 /*****************************************************************************/
665 gboolean
666 gl_label_object_can_text (glLabelObject     *object)
667 {
668         gl_debug (DEBUG_LABEL, "");
669
670         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
671
672         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
673
674                 return TRUE;
675
676         } else {
677
678                 return FALSE;
679
680         }
681
682 }
683
684
685 /*****************************************************************************/
686 /* Set font family for all text contained in object.                         */
687 /*****************************************************************************/
688 void
689 gl_label_object_set_font_family (glLabelObject     *object,
690                                  const gchar       *font_family)
691 {
692         gl_debug (DEBUG_LABEL, "START");
693
694         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
695
696         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
697
698                 /* We have an object specific method, use it */
699                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family);
700
701         }
702
703         gl_debug (DEBUG_LABEL, "END");
704 }
705
706
707 /****************************************************************************/
708 /* Set font size for all text contained in object.                          */
709 /****************************************************************************/
710 void
711 gl_label_object_set_font_size (glLabelObject     *object,
712                                gdouble            font_size)
713 {
714         gl_debug (DEBUG_LABEL, "START");
715
716         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
717
718         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL ) {
719
720                 /* We have an object specific method, use it */
721                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size);
722
723         }
724
725         gl_debug (DEBUG_LABEL, "END");
726 }
727
728
729 /****************************************************************************/
730 /* Set font weight for all text contained in object.                        */
731 /****************************************************************************/
732 void
733 gl_label_object_set_font_weight (glLabelObject     *object,
734                                  PangoWeight        font_weight)
735 {
736         gl_debug (DEBUG_LABEL, "START");
737
738         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
739
740         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL ) {
741
742                 /* We have an object specific method, use it */
743                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight);
744
745         }
746
747         gl_debug (DEBUG_LABEL, "END");
748 }
749
750
751 /****************************************************************************/
752 /* Set font italic flag for all text contained in object.                   */
753 /****************************************************************************/
754 void
755 gl_label_object_set_font_italic_flag (glLabelObject     *object,
756                                       gboolean           font_italic_flag)
757 {
758         gl_debug (DEBUG_LABEL, "START");
759
760         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
761
762         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL ) {
763
764                 /* We have an object specific method, use it */
765                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object,
766                                                                          font_italic_flag);
767
768         }
769
770         gl_debug (DEBUG_LABEL, "END");
771 }
772
773
774 /****************************************************************************/
775 /* Set text alignment for all text contained in object.                     */
776 /****************************************************************************/
777 void
778 gl_label_object_set_text_alignment (glLabelObject     *object,
779                                     PangoAlignment     text_alignment)
780 {
781         gl_debug (DEBUG_LABEL, "START");
782
783         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
784
785         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL ) {
786
787                 /* We have an object specific method, use it */
788                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object,
789                                                                        text_alignment);
790
791         }
792
793         gl_debug (DEBUG_LABEL, "END");
794 }
795
796
797 /****************************************************************************/
798 /* Set text line spacing for all text contained in object.                  */
799 /****************************************************************************/
800 void
801 gl_label_object_set_text_line_spacing (glLabelObject     *object,
802                                        gdouble            text_line_spacing)
803 {
804         gl_debug (DEBUG_LABEL, "START");
805
806         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
807
808         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL ) {
809
810                 /* We have an object specific method, use it */
811                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing);
812
813         }
814
815         gl_debug (DEBUG_LABEL, "END");
816 }
817
818
819 /****************************************************************************/
820 /* Set text color for all text contained in object.                         */
821 /****************************************************************************/
822 void
823 gl_label_object_set_text_color (glLabelObject     *object,
824                                 glColorNode       *text_color_node)
825 {
826         gl_debug (DEBUG_LABEL, "START");
827
828         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
829
830         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL ) {
831
832                 /* We have an object specific method, use it */
833                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node);
834
835         }
836
837         gl_debug (DEBUG_LABEL, "END");
838 }
839
840
841 /*****************************************************************************/
842 /* Get font family for all text contained in object.                         */
843 /*****************************************************************************/
844 gchar *
845 gl_label_object_get_font_family (glLabelObject     *object)
846 {
847         gchar *ret = NULL;
848
849         gl_debug (DEBUG_LABEL, "START");
850
851         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
852
853         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL ) {
854
855                 /* We have an object specific method, use it */
856                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
857
858         }
859
860         gl_debug (DEBUG_LABEL, "END");
861
862         return ret;
863 }
864
865
866 /****************************************************************************/
867 /* Get font size for all text contained in object.                          */
868 /****************************************************************************/
869 gdouble
870 gl_label_object_get_font_size (glLabelObject     *object)
871 {
872         gdouble ret = 0.0;
873
874         gl_debug (DEBUG_LABEL, "START");
875
876         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
877
878         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL ) {
879
880                 /* We have an object specific method, use it */
881                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
882
883         }
884
885         gl_debug (DEBUG_LABEL, "END");
886
887         return ret;
888 }
889
890
891 /****************************************************************************/
892 /* Get font weight for all text contained in object.                        */
893 /****************************************************************************/
894 PangoWeight    
895 gl_label_object_get_font_weight (glLabelObject     *object)
896 {
897         PangoWeight     ret = PANGO_WEIGHT_NORMAL;
898
899         gl_debug (DEBUG_LABEL, "START");
900
901         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
902
903         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL ) {
904
905                 /* We have an object specific method, use it */
906                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
907
908         }
909
910         gl_debug (DEBUG_LABEL, "END");
911
912         return ret;
913 }
914
915
916 /****************************************************************************/
917 /* Get font italic flag for all text contained in object.                   */
918 /****************************************************************************/
919 gboolean
920 gl_label_object_get_font_italic_flag (glLabelObject     *object)
921 {
922         gboolean ret = FALSE;
923
924         gl_debug (DEBUG_LABEL, "START");
925
926         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
927
928         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL ) {
929
930                 /* We have an object specific method, use it */
931                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
932
933         }
934
935         gl_debug (DEBUG_LABEL, "END");
936
937         return ret;
938 }
939
940
941 /****************************************************************************/
942 /* Get text alignment for all text contained in object.                     */
943 /****************************************************************************/
944 PangoAlignment
945 gl_label_object_get_text_alignment (glLabelObject     *object)
946 {
947         PangoAlignment ret = PANGO_ALIGN_LEFT;
948
949         gl_debug (DEBUG_LABEL, "START");
950
951         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
952
953         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL ) {
954
955                 /* We have an object specific method, use it */
956                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
957
958         }
959
960         gl_debug (DEBUG_LABEL, "END");
961
962         return ret;
963 }
964
965
966 /****************************************************************************/
967 /* Get text line spacing for all text contained in object.                  */
968 /****************************************************************************/
969 gdouble
970 gl_label_object_get_text_line_spacing (glLabelObject     *object)
971 {
972         gdouble ret = 0.0;
973
974         gl_debug (DEBUG_LABEL, "START");
975
976         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
977
978         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL ) {
979
980                 /* We have an object specific method, use it */
981                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
982
983         }
984
985         gl_debug (DEBUG_LABEL, "END");
986
987         return ret;
988 }
989
990
991 /****************************************************************************/
992 /* Get text color for all text contained in object.                         */
993 /****************************************************************************/
994 glColorNode*
995 gl_label_object_get_text_color (glLabelObject     *object)
996 {
997         glColorNode *ret = NULL;
998
999         gl_debug (DEBUG_LABEL, "START");
1000
1001         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1002
1003         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL ) {
1004
1005                 /* We have an object specific method, use it */
1006                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
1007
1008         }
1009
1010         gl_debug (DEBUG_LABEL, "END");
1011
1012         return ret;
1013 }
1014
1015
1016 /*****************************************************************************/
1017 /* Can fill properties be set for this object?                               */
1018 /*****************************************************************************/
1019 gboolean
1020 gl_label_object_can_fill (glLabelObject     *object)
1021 {
1022         gl_debug (DEBUG_LABEL, "");
1023
1024         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1025
1026         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
1027
1028                 return TRUE;
1029
1030         } else {
1031
1032                 return FALSE;
1033
1034         }
1035
1036 }
1037
1038
1039 /****************************************************************************/
1040 /* Set fill color for object.                                               */
1041 /****************************************************************************/
1042 void
1043 gl_label_object_set_fill_color (glLabelObject     *object,
1044                                 glColorNode       *fill_color_node)
1045 {
1046         gl_debug (DEBUG_LABEL, "START");
1047
1048         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1049
1050         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
1051
1052                 /* We have an object specific method, use it */
1053                 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node);
1054
1055         }
1056
1057         gl_debug (DEBUG_LABEL, "END");
1058 }
1059
1060
1061 /****************************************************************************/
1062 /* Get fill color for object.                                               */
1063 /****************************************************************************/
1064 glColorNode*
1065 gl_label_object_get_fill_color (glLabelObject     *object)
1066 {
1067         glColorNode *ret = NULL;
1068
1069         gl_debug (DEBUG_LABEL, "START");
1070
1071         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1072
1073         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL ) {
1074
1075                 /* We have an object specific method, use it */
1076                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1077
1078         }
1079
1080         gl_debug (DEBUG_LABEL, "END");
1081
1082         return ret;
1083 }
1084
1085
1086 /*****************************************************************************/
1087 /* Can line color property be set for this object?                           */
1088 /*****************************************************************************/
1089 gboolean
1090 gl_label_object_can_line_color (glLabelObject     *object)
1091 {
1092         gl_debug (DEBUG_LABEL, "");
1093
1094         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1095
1096         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
1097
1098                 return TRUE;
1099
1100         } else {
1101
1102                 return FALSE;
1103
1104         }
1105
1106 }
1107
1108
1109 /****************************************************************************/
1110 /* Set line color for object.                                               */
1111 /****************************************************************************/
1112 void
1113 gl_label_object_set_line_color (glLabelObject     *object,
1114                                 glColorNode       *line_color_node)
1115 {
1116         gl_debug (DEBUG_LABEL, "START");
1117
1118         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1119
1120         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
1121
1122                 /* We have an object specific method, use it */
1123                 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node);
1124
1125         }
1126
1127         gl_debug (DEBUG_LABEL, "END");
1128 }
1129
1130
1131 /****************************************************************************/
1132 /* Get line color for object.                                               */
1133 /****************************************************************************/
1134 glColorNode*
1135 gl_label_object_get_line_color (glLabelObject     *object)
1136 {
1137         glColorNode *ret = NULL;
1138
1139         gl_debug (DEBUG_LABEL, "START");
1140
1141         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1142
1143         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL ) {
1144
1145                 /* We have an object specific method, use it */
1146                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1147
1148         }
1149
1150         gl_debug (DEBUG_LABEL, "END");
1151
1152         return ret;
1153 }
1154
1155
1156 /*****************************************************************************/
1157 /* Can line width property be set for this object?                           */
1158 /*****************************************************************************/
1159 gboolean
1160 gl_label_object_can_line_width (glLabelObject     *object)
1161 {
1162         gl_debug (DEBUG_LABEL, "");
1163
1164         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1165
1166         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
1167
1168                 return TRUE;
1169
1170         } else {
1171
1172                 return FALSE;
1173
1174         }
1175
1176 }
1177
1178
1179 /****************************************************************************/
1180 /* Set line width for object.                                               */
1181 /****************************************************************************/
1182 void
1183 gl_label_object_set_line_width (glLabelObject     *object,
1184                                 gdouble            line_width)
1185 {
1186         gl_debug (DEBUG_LABEL, "START");
1187
1188         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1189
1190         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
1191
1192                 /* We have an object specific method, use it */
1193                 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width);
1194
1195         }
1196
1197         gl_debug (DEBUG_LABEL, "END");
1198 }
1199
1200
1201 /****************************************************************************/
1202 /* Get line width for object.                                               */
1203 /****************************************************************************/
1204 gdouble
1205 gl_label_object_get_line_width (glLabelObject     *object)
1206 {
1207         gdouble ret = 0.0;
1208
1209         gl_debug (DEBUG_LABEL, "START");
1210
1211         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1212
1213         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL ) {
1214
1215                 /* We have an object specific method, use it */
1216                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1217
1218         }
1219
1220         gl_debug (DEBUG_LABEL, "END");
1221
1222         return ret;
1223 }
1224
1225
1226 /****************************************************************************/
1227 /* Set shadow state of object.                                              */
1228 /****************************************************************************/
1229 void
1230 gl_label_object_set_shadow_state (glLabelObject     *object,
1231                                   gboolean           state)
1232 {
1233         gl_debug (DEBUG_LABEL, "START");
1234
1235         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1236
1237         if (object->priv->shadow_state != state)
1238         {
1239                 object->priv->shadow_state = state;
1240                 gl_label_object_emit_changed (object);
1241         }
1242
1243         gl_debug (DEBUG_LABEL, "END");
1244 }
1245
1246
1247 /****************************************************************************/
1248 /* Get shadow state of object.                                              */
1249 /****************************************************************************/
1250 gboolean
1251 gl_label_object_get_shadow_state (glLabelObject     *object)
1252 {
1253         gl_debug (DEBUG_LABEL, "");
1254
1255         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1256
1257         return object->priv->shadow_state;
1258 }
1259
1260
1261 /****************************************************************************/
1262 /* Set offset of object's shadow.                                           */
1263 /****************************************************************************/
1264 void
1265 gl_label_object_set_shadow_offset (glLabelObject     *object,
1266                                    gdouble            x,
1267                                    gdouble            y)
1268 {
1269         gl_debug (DEBUG_LABEL, "START");
1270
1271         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1272
1273         if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1274         {
1275                 object->priv->shadow_x = x;
1276                 object->priv->shadow_y = y;
1277
1278                 gl_label_object_emit_changed (object);
1279         }
1280
1281         gl_debug (DEBUG_LABEL, "END");
1282 }
1283
1284
1285 /****************************************************************************/
1286 /* Get offset of object's shadow.                                           */
1287 /****************************************************************************/
1288 void
1289 gl_label_object_get_shadow_offset (glLabelObject     *object,
1290                                    gdouble           *x,
1291                                    gdouble           *y)
1292 {
1293         gl_debug (DEBUG_LABEL, "START");
1294
1295         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1296
1297         *x = object->priv->shadow_x;
1298         *y = object->priv->shadow_y;
1299
1300         gl_debug (DEBUG_LABEL, "END");
1301 }
1302
1303
1304 /****************************************************************************/
1305 /* Set color of object's shadow.                                            */
1306 /****************************************************************************/
1307 void
1308 gl_label_object_set_shadow_color (glLabelObject     *object,
1309                                   glColorNode       *color_node)
1310 {
1311         gl_debug (DEBUG_LABEL, "START");
1312
1313         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1314
1315         if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1316         {
1317                 gl_color_node_free (&(object->priv->shadow_color_node));
1318                 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1319                 gl_label_object_emit_changed (GL_LABEL_OBJECT(object));
1320         }
1321
1322         gl_debug (DEBUG_LABEL, "END");
1323 }
1324
1325
1326 /****************************************************************************/
1327 /* Get color of object's shadow.                                            */
1328 /****************************************************************************/
1329 glColorNode*
1330 gl_label_object_get_shadow_color (glLabelObject     *object)
1331 {
1332         gl_debug (DEBUG_LABEL, "");
1333
1334         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1335
1336         return gl_color_node_dup (object->priv->shadow_color_node);
1337 }
1338
1339
1340 /****************************************************************************/
1341 /* Set opacity of object's shadow.                                          */
1342 /****************************************************************************/
1343 void
1344 gl_label_object_set_shadow_opacity (glLabelObject     *object,
1345                                     gdouble            alpha)
1346 {
1347         gl_debug (DEBUG_LABEL, "START");
1348
1349         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1350
1351         if (object->priv->shadow_opacity != alpha)
1352         {
1353                 object->priv->shadow_opacity = alpha;
1354                 gl_label_object_emit_changed (object);
1355         }
1356
1357         gl_debug (DEBUG_LABEL, "END");
1358 }
1359
1360
1361 /****************************************************************************/
1362 /* Get opacity of object's shadow.                                          */
1363 /****************************************************************************/
1364 gdouble
1365 gl_label_object_get_shadow_opacity (glLabelObject     *object)
1366 {
1367         gl_debug (DEBUG_LABEL, "");
1368
1369         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1370
1371         return object->priv->shadow_opacity;
1372 }
1373
1374
1375 /****************************************************************************/
1376 /* Flip object horizontally.                                                */
1377 /****************************************************************************/
1378 void
1379 gl_label_object_flip_horiz (glLabelObject *object)
1380 {
1381         cairo_matrix_t flip_matrix;
1382
1383         gl_debug (DEBUG_LABEL, "START");
1384
1385         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1386
1387         cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1388         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1389
1390         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1391
1392         gl_debug (DEBUG_LABEL, "END");
1393 }
1394
1395
1396 /****************************************************************************/
1397 /* Flip object vertically.                                                  */
1398 /****************************************************************************/
1399 void
1400 gl_label_object_flip_vert (glLabelObject *object)
1401 {
1402         cairo_matrix_t flip_matrix;
1403
1404         gl_debug (DEBUG_LABEL, "START");
1405
1406         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1407
1408         cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1409         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1410
1411         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1412
1413         gl_debug (DEBUG_LABEL, "END");
1414 }
1415
1416
1417 /****************************************************************************/
1418 /* Rotate object.                                                           */
1419 /****************************************************************************/
1420 void
1421 gl_label_object_rotate (glLabelObject *object,
1422                         gdouble        theta_degs)
1423 {
1424         cairo_matrix_t rotate_matrix;
1425
1426         gl_debug (DEBUG_LABEL, "START");
1427
1428         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1429
1430         cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1431         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1432
1433         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1434
1435         gl_debug (DEBUG_LABEL, "END");
1436 }
1437
1438
1439 /****************************************************************************/
1440 /* Set raw affine                                                           */
1441 /****************************************************************************/
1442 void
1443 gl_label_object_set_matrix (glLabelObject  *object,
1444                             cairo_matrix_t *matrix)
1445 {
1446         gl_debug (DEBUG_LABEL, "");
1447
1448         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1449
1450         object->priv->matrix = *matrix;
1451 }
1452
1453
1454 /****************************************************************************/
1455 /* Get raw affine                                                           */
1456 /****************************************************************************/
1457 void
1458 gl_label_object_get_matrix (glLabelObject  *object,
1459                             cairo_matrix_t *matrix)
1460 {
1461         gl_debug (DEBUG_LABEL, "");
1462
1463         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1464
1465         *matrix = object->priv->matrix;
1466 }
1467
1468
1469 /****************************************************************************/
1470 /* Bring label object to front/top.                                         */
1471 /****************************************************************************/
1472 void
1473 gl_label_object_raise_to_top (glLabelObject *object)
1474 {
1475         glLabel *label;
1476
1477         gl_debug (DEBUG_LABEL, "START");
1478
1479         label = object->parent;
1480
1481         gl_label_raise_object_to_top (label, object);
1482
1483         g_signal_emit (G_OBJECT(object), signals[TOP], 0);
1484
1485         gl_debug (DEBUG_LABEL, "END");
1486 }
1487
1488
1489 /****************************************************************************/
1490 /* Send label object to rear/bottom.                                        */
1491 /****************************************************************************/
1492 void
1493 gl_label_object_lower_to_bottom (glLabelObject *object)
1494 {
1495         glLabel *label;
1496
1497         gl_debug (DEBUG_LABEL, "START");
1498
1499         label = object->parent;
1500
1501         gl_label_lower_object_to_bottom (label, object);
1502
1503         g_signal_emit (G_OBJECT(object), signals[BOTTOM], 0);
1504
1505         gl_debug (DEBUG_LABEL, "END");
1506 }
1507
1508
1509 /*--------------------------------------------------------------------------*/
1510 /* PRIVATE.  Label's merge data changed callback.                           */
1511 /*--------------------------------------------------------------------------*/
1512 static void
1513 merge_changed_cb (glLabel       *label,
1514                   glLabelObject *object)
1515 {
1516         gl_label_object_emit_changed (object);
1517 }
1518
1519
1520 /*****************************************************************************/
1521 /* Draw object                                                               */
1522 /*****************************************************************************/
1523 void
1524 gl_label_object_draw (glLabelObject *object,
1525                       cairo_t       *cr,
1526                       gboolean       screen_flag,
1527                       glMergeRecord *record)
1528
1529 {
1530         gdouble        x0, y0;
1531         cairo_matrix_t matrix;
1532         gboolean       shadow_state;
1533         gdouble        shadow_x, shadow_y;
1534
1535         gl_debug (DEBUG_LABEL, "START");
1536
1537         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1538
1539         gl_label_object_get_position (object, &x0, &y0);
1540         gl_label_object_get_matrix (object, &matrix);
1541
1542         cairo_save (cr);
1543         cairo_translate (cr, x0, y0);
1544
1545         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL ) {
1546
1547                 shadow_state = gl_label_object_get_shadow_state (object);
1548
1549                 if ( shadow_state )
1550                 {
1551                         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1552
1553                         cairo_save (cr);
1554                         cairo_translate (cr, shadow_x, shadow_y);
1555                         cairo_transform (cr, &matrix);
1556
1557                         GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1558                                                                         cr,
1559                                                                         screen_flag,
1560                                                                         record);
1561
1562                         cairo_restore (cr);
1563                 }
1564         }
1565
1566         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL ) {
1567
1568                 cairo_save (cr);
1569                 cairo_transform (cr, &matrix);
1570
1571                 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1572                                                                 cr,
1573                                                                 screen_flag,
1574                                                                 record);
1575
1576                 cairo_restore (cr);
1577         }
1578
1579         cairo_restore (cr);
1580
1581         gl_debug (DEBUG_LABEL, "END");
1582 }
1583
1584
1585
1586
1587 /*
1588  * Local Variables:       -- emacs
1589  * mode: C                -- emacs
1590  * c-basic-offset: 8      -- emacs
1591  * tab-width: 8           -- emacs
1592  * indent-tabs-mode: nil  -- emacs
1593  * End:                   -- emacs
1594  */