]> git.sur5r.net Git - glabels/blob - src/label-object.c
Imported Upstream version 3.2.0
[glabels] / 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/gi18n.h>
26 #include <glib.h>
27 #include <math.h>
28
29 #include "marshal.h"
30
31 #include "debug.h"
32
33
34 /*========================================================*/
35 /* Private defines.                                       */
36 /*========================================================*/
37
38 #define DEFAULT_SHADOW_X_OFFSET (3.6)
39 #define DEFAULT_SHADOW_Y_OFFSET (3.6)
40 #define DEFAULT_SHADOW_COLOR    GL_COLOR_BLACK
41 #define DEFAULT_SHADOW_OPACITY  (0.5)
42
43 #define HANDLE_FILL_RGBA_ARGS      0.0,   0.75,  0.0,   0.4
44 #define HANDLE_OUTLINE_RGBA_ARGS   0.0,   0.0,   0.0,   0.8
45
46 #define HANDLE_OUTLINE_WIDTH_PIXELS   1.0
47 #define HANDLE_PIXELS 7
48
49
50 /*========================================================*/
51 /* Private types.                                         */
52 /*========================================================*/
53
54 struct _glLabelObjectPrivate {
55
56         gchar             *name;
57
58         gboolean           selected_flag;
59         glLabel           *parent;
60
61         gdouble            x, y;
62         gdouble            w, h;
63         cairo_matrix_t     matrix;
64
65         gdouble            aspect_ratio;
66
67         gboolean           shadow_state;
68         gdouble            shadow_x;
69         gdouble            shadow_y;
70         glColorNode       *shadow_color_node;
71         gdouble            shadow_opacity;
72 };
73
74 enum {
75         CHANGED,
76         MOVED,
77         LAST_SIGNAL
78 };
79
80
81 /*========================================================*/
82 /* Private globals.                                       */
83 /*========================================================*/
84
85 static guint instance = 0;
86
87 static guint signals[LAST_SIGNAL] = {0};
88
89
90 /*========================================================*/
91 /* Private function prototypes.                           */
92 /*========================================================*/
93
94 static void     gl_label_object_finalize  (GObject            *object);
95
96 static void     set_size                  (glLabelObject      *object,
97                                            gdouble             w,
98                                            gdouble             h,
99                                            gboolean            checkpoint);
100
101
102 /*****************************************************************************/
103 /* Boilerplate object stuff.                                                 */
104 /*****************************************************************************/
105 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT)
106
107
108 static void
109 gl_label_object_class_init (glLabelObjectClass *class)
110 {
111         GObjectClass       *object_class = G_OBJECT_CLASS (class);
112
113         gl_debug (DEBUG_LABEL, "START");
114
115         gl_label_object_parent_class = g_type_class_peek_parent (class);
116
117         object_class->finalize = gl_label_object_finalize;
118
119         class->set_size     = set_size;
120         class->draw_handles = gl_label_object_draw_handles_box; /* Default style */
121         class->handle_at    = gl_label_object_box_handle_at;    /* Default style */
122
123         signals[CHANGED] =
124                 g_signal_new ("changed",
125                               G_OBJECT_CLASS_TYPE (object_class),
126                               G_SIGNAL_RUN_LAST,
127                               G_STRUCT_OFFSET (glLabelObjectClass, changed),
128                               NULL, NULL,
129                               gl_marshal_VOID__VOID,
130                               G_TYPE_NONE,
131                               0);
132
133         signals[MOVED] =
134                 g_signal_new ("moved",
135                               G_OBJECT_CLASS_TYPE (object_class),
136                               G_SIGNAL_RUN_LAST,
137                               G_STRUCT_OFFSET (glLabelObjectClass, moved),
138                               NULL, NULL,
139                               gl_marshal_VOID__VOID,
140                               G_TYPE_NONE,
141                               0);
142
143         gl_debug (DEBUG_LABEL, "END");
144 }
145
146
147 static void
148 gl_label_object_init (glLabelObject *object)
149 {
150         gl_debug (DEBUG_LABEL, "START");
151
152         object->priv = g_new0 (glLabelObjectPrivate, 1);
153
154         object->priv->name = g_strdup_printf ("object%d", instance++);
155
156         cairo_matrix_init_identity (&object->priv->matrix);
157
158         object->priv->shadow_state = FALSE;
159         object->priv->shadow_x = DEFAULT_SHADOW_X_OFFSET;
160         object->priv->shadow_y = DEFAULT_SHADOW_Y_OFFSET;
161         object->priv->shadow_color_node = gl_color_node_new_default ();
162         object->priv->shadow_color_node->color = DEFAULT_SHADOW_COLOR;
163         object->priv->shadow_opacity = DEFAULT_SHADOW_OPACITY;
164
165         gl_debug (DEBUG_LABEL, "END");
166 }
167
168
169 static void
170 gl_label_object_finalize (GObject *object)
171 {
172         glLabelObject *label_object = GL_LABEL_OBJECT (object);
173
174         gl_debug (DEBUG_LABEL, "START");
175
176         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
177
178         g_free (label_object->priv->name);
179         g_free (label_object->priv);
180
181         G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
182
183         gl_debug (DEBUG_LABEL, "END");
184 }
185
186
187 /*****************************************************************************/
188 /* New label object.                                                         */
189 /*****************************************************************************/
190 GObject *
191 gl_label_object_new (glLabel *label)
192 {
193         glLabelObject *object;
194
195         gl_debug (DEBUG_LABEL, "START");
196
197         object = g_object_new (gl_label_object_get_type(), NULL);
198
199         gl_label_object_set_parent (object, label);
200
201         gl_debug (DEBUG_LABEL, "END");
202
203         return G_OBJECT (object);
204 }
205
206
207 /*****************************************************************************/
208 /* Duplicate object.                                                         */
209 /*****************************************************************************/
210 glLabelObject *
211 gl_label_object_dup (glLabelObject *src_object,
212                      glLabel       *label)
213 {
214         glLabelObject    *dst_object;
215         gdouble           x, y, w, h;
216         cairo_matrix_t    matrix;
217         gboolean          shadow_state;
218         gdouble           shadow_x, shadow_y;
219         glColorNode      *shadow_color_node;
220         gdouble           shadow_opacity;
221
222         gl_debug (DEBUG_LABEL, "START");
223
224         g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
225
226         dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
227
228         gl_label_object_set_parent (dst_object, label);
229         dst_object->priv->selected_flag = src_object->priv->selected_flag;
230
231         gl_label_object_get_position      (src_object, &x, &y);
232         gl_label_object_get_raw_size      (src_object, &w, &h);
233         gl_label_object_get_matrix        (src_object, &matrix);
234         gl_label_object_get_shadow_offset (src_object, &shadow_x, &shadow_y);
235         shadow_color_node = gl_label_object_get_shadow_color   (src_object);
236         shadow_opacity    = gl_label_object_get_shadow_opacity (src_object);
237         shadow_state      = gl_label_object_get_shadow_state   (src_object);
238
239         gl_label_object_set_position (dst_object, x, y, FALSE);
240         gl_label_object_set_raw_size (dst_object, w, h, FALSE);
241         gl_label_object_set_matrix   (dst_object, &matrix);
242         gl_label_object_set_shadow_offset  (dst_object, shadow_x, shadow_y, FALSE);
243         gl_label_object_set_shadow_color   (dst_object, shadow_color_node, FALSE);
244         gl_label_object_set_shadow_opacity (dst_object, shadow_opacity, FALSE);
245         gl_label_object_set_shadow_state   (dst_object, shadow_state, FALSE);
246
247         gl_color_node_free (&shadow_color_node);
248
249         if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL )
250         {
251                 /* We have an object specific method, use it */
252                 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
253         }
254
255         gl_debug (DEBUG_LABEL, "END");
256
257         return dst_object;
258 }
259
260
261 /*****************************************************************************/
262 /* Emit "changed" signal (for derived objects).                              */
263 /*****************************************************************************/
264 void
265 gl_label_object_emit_changed (glLabelObject *object)
266 {
267         gl_debug (DEBUG_LABEL, "START");
268
269         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
270
271         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
272
273         gl_debug (DEBUG_LABEL, "END");
274 }
275
276
277 /*****************************************************************************/
278 /* Set parent label of object.                                               */
279 /*****************************************************************************/
280 void
281 gl_label_object_set_parent (glLabelObject *object,
282                             glLabel       *label)
283 {
284         gl_debug (DEBUG_LABEL, "START");
285
286         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
287         g_return_if_fail (label && GL_IS_LABEL (label));
288
289         object->priv->parent = label;
290 }
291
292
293 /*****************************************************************************/
294 /* Get parent label of object.                                               */
295 /*****************************************************************************/
296 glLabel *
297 gl_label_object_get_parent (glLabelObject *object)
298 {
299         gl_debug (DEBUG_LABEL, "START");
300
301         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
302
303         gl_debug (DEBUG_LABEL, "END");
304
305         return object->priv->parent;
306 }
307
308
309 /*****************************************************************************/
310 /* Select object.                                                            */
311 /*****************************************************************************/
312 void
313 gl_label_object_select (glLabelObject     *object)
314 {
315         object->priv->selected_flag = TRUE;
316 }
317
318
319 /*****************************************************************************/
320 /* Unselect object.                                                          */
321 /*****************************************************************************/
322 void
323 gl_label_object_unselect (glLabelObject     *object)
324 {
325         object->priv->selected_flag = FALSE;
326 }
327
328
329 /*****************************************************************************/
330 /* Is object selected?                                                       */
331 /*****************************************************************************/
332 gboolean
333 gl_label_object_is_selected (glLabelObject     *object)
334 {
335         return object->priv->selected_flag;
336 }
337
338
339 /*****************************************************************************/
340 /* Set name of object.                                                       */
341 /*****************************************************************************/
342 void    
343 gl_label_object_set_name (glLabelObject *object,
344                           gchar         *name)
345 {
346         gl_debug (DEBUG_LABEL, "START");
347
348         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
349
350         g_free(object->priv->name);
351         object->priv->name = name;
352
353         gl_label_object_emit_changed (object);
354
355         gl_debug (DEBUG_LABEL, "END");
356 }
357
358
359 /*****************************************************************************/
360 /* Get name of object.                                                       */
361 /*****************************************************************************/
362 gchar *
363 gl_label_object_get_name (glLabelObject *object)
364 {
365         gl_debug (DEBUG_LABEL, "START");
366
367         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
368
369         gl_debug (DEBUG_LABEL, "END");
370
371         return g_strdup(object->priv->name);
372 }
373
374
375 /*****************************************************************************/
376 /* Set position of object.                                                   */
377 /*****************************************************************************/
378 void    
379 gl_label_object_set_position (glLabelObject *object,
380                               gdouble        x,
381                               gdouble        y,
382                               gboolean       checkpoint)
383 {
384         gl_debug (DEBUG_LABEL, "START");
385
386         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
387
388         if ( (x != object->priv->x) || (y != object->priv->y) )
389         {
390                 if ( checkpoint )
391                 {
392                         gl_label_checkpoint (object->priv->parent, _("Move"));
393                 }
394
395                 object->priv->x = x;
396                 object->priv->y = y;
397
398                 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
399
400         }
401
402         gl_debug (DEBUG_LABEL, "END");
403 }
404
405
406 /*****************************************************************************/
407 /* Set position of object relative to old position.                          */
408 /*****************************************************************************/
409 void    
410 gl_label_object_set_position_relative (glLabelObject *object,
411                                        gdouble        dx,
412                                        gdouble        dy,
413                                        gboolean       checkpoint)
414 {
415         gl_debug (DEBUG_LABEL, "START");
416
417         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
418
419         if ( (dx != 0.0) || (dy != 0.0) )
420         {
421                 if ( checkpoint )
422                 {
423                         gl_label_checkpoint (object->priv->parent, _("Move"));
424                 }
425
426                 object->priv->x += dx;
427                 object->priv->y += dy;
428
429                 gl_debug (DEBUG_LABEL, "       x = %f, y= %f",
430                           object->priv->x,
431                           object->priv->y);
432
433                 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
434         }
435
436         gl_debug (DEBUG_LABEL, "END");
437 }
438
439
440 /*****************************************************************************/
441 /* Get position of object.                                                   */
442 /*****************************************************************************/
443 void
444 gl_label_object_get_position (glLabelObject *object,
445                               gdouble       *x,
446                               gdouble       *y)
447 {
448         gl_debug (DEBUG_LABEL, "START");
449
450         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
451
452         *x = object->priv->x;
453         *y = object->priv->y;
454
455         gl_debug (DEBUG_LABEL, "END");
456 }
457
458
459 /*---------------------------------------------------------------------------*/
460 /* PRIVATE.  Default set size method.                                        */
461 /*---------------------------------------------------------------------------*/
462 static void
463 set_size (glLabelObject *object,
464           gdouble        w,
465           gdouble        h,
466           gboolean       checkpoint)
467 {
468         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
469
470         if ( (object->priv->w != w) || (object->priv->h != h) )
471         {
472                 if ( checkpoint )
473                 {
474                         gl_label_checkpoint (object->priv->parent, _("Resize"));
475                 }
476
477                 object->priv->w = w;
478                 object->priv->h = h;
479
480                 gl_label_object_emit_changed (object);
481         }
482 }
483
484
485 /*****************************************************************************/
486 /* Set size of object.                                                       */
487 /*****************************************************************************/
488 void    
489 gl_label_object_set_size (glLabelObject *object,
490                           gdouble        w,
491                           gdouble        h,
492                           gboolean       checkpoint)
493 {
494         gl_debug (DEBUG_LABEL, "START");
495
496         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
497
498         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
499         {
500                 /* We have an object specific method, use it */
501                 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
502
503                 object->priv->aspect_ratio = h / w;
504         }
505
506         gl_debug (DEBUG_LABEL, "END");
507 }
508
509
510 /*****************************************************************************/
511 /* Set raw size of object.                                                   */
512 /*****************************************************************************/
513 void
514 gl_label_object_set_raw_size (glLabelObject *object,
515                               gdouble        w,
516                               gdouble        h,
517                               gboolean       checkpoint)
518 {
519         gl_debug (DEBUG_LABEL, "START");
520
521         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
522
523         set_size (object, w, h, checkpoint);
524         object->priv->aspect_ratio = h / w;
525
526         gl_debug (DEBUG_LABEL, "END");
527 }
528
529
530 /*****************************************************************************/
531 /* Set size of object honoring current aspect ratio.                         */
532 /*****************************************************************************/
533 void    
534 gl_label_object_set_size_honor_aspect (glLabelObject *object,
535                                        gdouble        w,
536                                        gdouble        h,
537                                        gboolean       checkpoint)
538 {
539         gl_debug (DEBUG_LABEL, "START");
540
541         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
542
543         if ( h > w*object->priv->aspect_ratio )
544         {
545                 h = w * object->priv->aspect_ratio;
546         }
547         else
548         {
549                 w = h / object->priv->aspect_ratio;
550         }
551
552         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
553         {
554                 /* We have an object specific method, use it */
555                 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
556         }
557
558         gl_debug (DEBUG_LABEL, "END");
559 }
560
561
562 /*****************************************************************************/
563 /* Get raw size method (don't let object content adjust size).               */
564 /*****************************************************************************/
565 void
566 gl_label_object_get_raw_size (glLabelObject *object,
567                               gdouble       *w,
568                               gdouble       *h)
569 {
570         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
571
572         *w = object->priv->w;
573         *h = object->priv->h;
574 }
575
576
577 /*****************************************************************************/
578 /* Get size of object.                                                       */
579 /*****************************************************************************/
580 void
581 gl_label_object_get_size (glLabelObject *object,
582                           gdouble       *w,
583                           gdouble       *h)
584 {
585         gl_debug (DEBUG_LABEL, "START");
586
587         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
588
589         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
590         {
591                 /* We have an object specific method, use it */
592                 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
593         }
594         else
595         {
596                 gl_label_object_get_raw_size (object, w, h);
597         }
598
599         gl_debug (DEBUG_LABEL, "END");
600 }
601
602
603 /*****************************************************************************/
604 /* Get extent of object.                                                     */
605 /*****************************************************************************/
606 void
607 gl_label_object_get_extent (glLabelObject *object,
608                             glLabelRegion *region)
609 {
610         gdouble        w, h;
611         gdouble        line_w;
612         gdouble        xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
613         cairo_matrix_t matrix;
614
615         gl_debug (DEBUG_LABEL, "START");
616
617         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
618
619         gl_label_object_get_size (object, &w, &h);
620         line_w = gl_label_object_get_line_width (object);
621
622         /* setup untransformed corners of bounding box, account for line width */
623         xa1 =   - line_w/2;
624         ya1 =   - line_w/2;
625         xa2 = w + line_w/2;
626         ya2 =   - line_w/2;
627         xa3 = w + line_w/2;
628         ya3 = h + line_w/2;
629         xa4 =   - line_w/2;
630         ya4 = h + line_w/2;
631
632         /* transform these points */
633         gl_label_object_get_matrix (object, &matrix);
634         cairo_matrix_transform_point (&matrix, &xa1, &ya1);
635         cairo_matrix_transform_point (&matrix, &xa2, &ya2);
636         cairo_matrix_transform_point (&matrix, &xa3, &ya3);
637         cairo_matrix_transform_point (&matrix, &xa4, &ya4);
638
639         /* now find the maximum extent of these points in x and y */
640         region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
641         region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
642         region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
643         region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
644
645         gl_debug (DEBUG_LABEL, "END");
646 }
647
648
649 /*****************************************************************************/
650 /* Can text properties be set for this object?                               */
651 /*****************************************************************************/
652 gboolean
653 gl_label_object_can_text (glLabelObject     *object)
654 {
655         gl_debug (DEBUG_LABEL, "");
656
657         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
658
659         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
660         {
661                 return TRUE;
662         }
663         else
664         {
665                 return FALSE;
666         }
667 }
668
669
670 /*****************************************************************************/
671 /* Set font family for all text contained in object.                         */
672 /*****************************************************************************/
673 void    
674 gl_label_object_set_font_family (glLabelObject     *object,
675                                  const gchar       *font_family,
676                                  gboolean           checkpoint)
677 {
678         gl_debug (DEBUG_LABEL, "START");
679
680         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
681
682         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
683         {
684                 /* We have an object specific method, use it */
685                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family, checkpoint);
686         }
687
688         gl_debug (DEBUG_LABEL, "END");
689 }
690
691
692 /****************************************************************************/
693 /* Set font size for all text contained in object.                          */
694 /****************************************************************************/
695 void    
696 gl_label_object_set_font_size (glLabelObject     *object,
697                                gdouble            font_size,
698                                gboolean           checkpoint)
699 {
700         gl_debug (DEBUG_LABEL, "START");
701
702         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
703
704         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
705         {
706                 /* We have an object specific method, use it */
707                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size, checkpoint);
708         }
709
710         gl_debug (DEBUG_LABEL, "END");
711 }
712
713
714 /****************************************************************************/
715 /* Set font weight for all text contained in object.                        */
716 /****************************************************************************/
717 void    
718 gl_label_object_set_font_weight (glLabelObject     *object,
719                                  PangoWeight        font_weight,
720                                  gboolean           checkpoint)
721 {
722         gl_debug (DEBUG_LABEL, "START");
723
724         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
725
726         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL )
727         {
728                 /* We have an object specific method, use it */
729                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight, checkpoint);
730         }
731
732         gl_debug (DEBUG_LABEL, "END");
733 }
734
735
736 /****************************************************************************/
737 /* Set font italic flag for all text contained in object.                   */
738 /****************************************************************************/
739 void    
740 gl_label_object_set_font_italic_flag (glLabelObject     *object,
741                                       gboolean           font_italic_flag,
742                                       gboolean           checkpoint)
743 {
744         gl_debug (DEBUG_LABEL, "START");
745
746         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
747
748         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
749         {
750                 /* We have an object specific method, use it */
751                 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag, checkpoint);
752         }
753
754         gl_debug (DEBUG_LABEL, "END");
755 }
756
757
758 /****************************************************************************/
759 /* Set text alignment for all text contained in object.                     */
760 /****************************************************************************/
761 void    
762 gl_label_object_set_text_alignment (glLabelObject     *object,
763                                     PangoAlignment     text_alignment,
764                                     gboolean           checkpoint)
765 {
766         gl_debug (DEBUG_LABEL, "START");
767
768         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
769
770         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
771         {
772                 /* We have an object specific method, use it */
773                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment, checkpoint);
774         }
775
776         gl_debug (DEBUG_LABEL, "END");
777 }
778
779
780 /****************************************************************************/
781 /* Set vertical text alignment for all text contained in object.            */
782 /****************************************************************************/
783 void
784 gl_label_object_set_text_valignment (glLabelObject     *object,
785                                      glValignment       text_valignment,
786                                      gboolean           checkpoint)
787 {
788         gl_debug (DEBUG_LABEL, "START");
789
790         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
791
792         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment != NULL )
793         {
794                 /* We have an object specific method, use it */
795                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment (object, text_valignment, checkpoint);
796         }
797
798         gl_debug (DEBUG_LABEL, "END");
799 }
800
801
802 /****************************************************************************/
803 /* Set text line spacing for all text contained in object.                  */
804 /****************************************************************************/
805 void    
806 gl_label_object_set_text_line_spacing (glLabelObject     *object,
807                                        gdouble            text_line_spacing,
808                                        gboolean           checkpoint)
809 {
810         gl_debug (DEBUG_LABEL, "START");
811
812         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
813
814         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
815         {
816                 /* We have an object specific method, use it */
817                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing, checkpoint);
818         }
819
820         gl_debug (DEBUG_LABEL, "END");
821 }
822
823
824 /****************************************************************************/
825 /* Set text color for all text contained in object.                         */
826 /****************************************************************************/
827 void    
828 gl_label_object_set_text_color (glLabelObject     *object,
829                                 glColorNode       *text_color_node,
830                                 gboolean           checkpoint)
831 {
832         gl_debug (DEBUG_LABEL, "START");
833
834         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
835
836         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
837         {
838                 /* We have an object specific method, use it */
839                 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node, checkpoint);
840         }
841
842         gl_debug (DEBUG_LABEL, "END");
843 }
844
845
846 /*****************************************************************************/
847 /* Get font family for all text contained in object.                         */
848 /*****************************************************************************/
849 gchar *
850 gl_label_object_get_font_family (glLabelObject     *object)
851 {
852         gchar *ret = NULL;
853
854         gl_debug (DEBUG_LABEL, "START");
855
856         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
857
858         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
859         {
860                 /* We have an object specific method, use it */
861                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
862         }
863
864         gl_debug (DEBUG_LABEL, "END");
865
866         return ret;
867 }
868
869
870 /****************************************************************************/
871 /* Get font size for all text contained in object.                          */
872 /****************************************************************************/
873 gdouble
874 gl_label_object_get_font_size (glLabelObject     *object)
875 {
876         gdouble ret = 0.0;
877
878         gl_debug (DEBUG_LABEL, "START");
879
880         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
881
882         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
883         {
884                 /* We have an object specific method, use it */
885                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
886         }
887
888         gl_debug (DEBUG_LABEL, "END");
889
890         return ret;
891 }
892
893
894 /****************************************************************************/
895 /* Get font weight for all text contained in object.                        */
896 /****************************************************************************/
897 PangoWeight    
898 gl_label_object_get_font_weight (glLabelObject     *object)
899 {
900         PangoWeight     ret = PANGO_WEIGHT_NORMAL;
901
902         gl_debug (DEBUG_LABEL, "START");
903
904         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
905
906         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
907         {
908                 /* We have an object specific method, use it */
909                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
910         }
911
912         gl_debug (DEBUG_LABEL, "END");
913
914         return ret;
915 }
916
917
918 /****************************************************************************/
919 /* Get font italic flag for all text contained in object.                   */
920 /****************************************************************************/
921 gboolean
922 gl_label_object_get_font_italic_flag (glLabelObject     *object)
923 {
924         gboolean ret = FALSE;
925
926         gl_debug (DEBUG_LABEL, "START");
927
928         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
929
930         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
931         {
932                 /* We have an object specific method, use it */
933                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
934         }
935
936         gl_debug (DEBUG_LABEL, "END");
937
938         return ret;
939 }
940
941
942 /****************************************************************************/
943 /* Get text alignment for all text contained in object.                     */
944 /****************************************************************************/
945 PangoAlignment
946 gl_label_object_get_text_alignment (glLabelObject     *object)
947 {
948         PangoAlignment ret = PANGO_ALIGN_LEFT;
949
950         gl_debug (DEBUG_LABEL, "START");
951
952         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
953
954         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
955         {
956                 /* We have an object specific method, use it */
957                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
958         }
959
960         gl_debug (DEBUG_LABEL, "END");
961
962         return ret;
963 }
964
965
966 /****************************************************************************/
967 /* Get text alignment for all text contained in object.                     */
968 /****************************************************************************/
969 glValignment
970 gl_label_object_get_text_valignment (glLabelObject     *object)
971 {
972         glValignment ret = GL_VALIGN_TOP;
973
974         gl_debug (DEBUG_LABEL, "START");
975
976         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), GL_VALIGN_TOP);
977
978         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment != NULL )
979         {
980                 /* We have an object specific method, use it */
981                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment (object);
982         }
983
984         gl_debug (DEBUG_LABEL, "END");
985
986         return ret;
987 }
988
989
990 /****************************************************************************/
991 /* Get text line spacing for all text contained in object.                  */
992 /****************************************************************************/
993 gdouble
994 gl_label_object_get_text_line_spacing (glLabelObject     *object)
995 {
996         gdouble ret = 0.0;
997
998         gl_debug (DEBUG_LABEL, "START");
999
1000         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1001
1002         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
1003         {
1004                 /* We have an object specific method, use it */
1005                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
1006         }
1007
1008         gl_debug (DEBUG_LABEL, "END");
1009
1010         return ret;
1011 }
1012
1013
1014 /****************************************************************************/
1015 /* Get text color for all text contained in object.                         */
1016 /****************************************************************************/
1017 glColorNode*
1018 gl_label_object_get_text_color (glLabelObject     *object)
1019 {
1020         glColorNode *ret = NULL;
1021
1022         gl_debug (DEBUG_LABEL, "START");
1023
1024         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1025
1026         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
1027         {
1028                 /* We have an object specific method, use it */
1029                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
1030         }
1031
1032         gl_debug (DEBUG_LABEL, "END");
1033
1034         return ret;
1035 }
1036
1037
1038 /*****************************************************************************/
1039 /* Can fill properties be set for this object?                               */
1040 /*****************************************************************************/
1041 gboolean
1042 gl_label_object_can_fill (glLabelObject     *object)
1043 {
1044         gl_debug (DEBUG_LABEL, "");
1045
1046         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1047
1048         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1049         {
1050                 return TRUE;
1051         }
1052         else
1053         {
1054                 return FALSE;
1055         }
1056
1057 }
1058
1059
1060 /****************************************************************************/
1061 /* Set fill color for object.                                               */
1062 /****************************************************************************/
1063 void    
1064 gl_label_object_set_fill_color (glLabelObject     *object,
1065                                 glColorNode       *fill_color_node,
1066                                 gboolean           checkpoint)
1067 {
1068         gl_debug (DEBUG_LABEL, "START");
1069
1070         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1071
1072         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1073         {
1074                 /* We have an object specific method, use it */
1075                 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node, checkpoint);
1076         }
1077
1078         gl_debug (DEBUG_LABEL, "END");
1079 }
1080
1081
1082 /****************************************************************************/
1083 /* Get fill color for object.                                               */
1084 /****************************************************************************/
1085 glColorNode*
1086 gl_label_object_get_fill_color (glLabelObject     *object)
1087 {
1088         glColorNode *ret = NULL;
1089
1090         gl_debug (DEBUG_LABEL, "START");
1091
1092         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1093
1094         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
1095         {
1096                 /* We have an object specific method, use it */
1097                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1098         }
1099
1100         gl_debug (DEBUG_LABEL, "END");
1101
1102         return ret;
1103 }
1104
1105
1106 /*****************************************************************************/
1107 /* Can line color property be set for this object?                           */
1108 /*****************************************************************************/
1109 gboolean
1110 gl_label_object_can_line_color (glLabelObject     *object)
1111 {
1112         gl_debug (DEBUG_LABEL, "");
1113
1114         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1115
1116         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1117         {
1118                 return TRUE;
1119         }
1120         else
1121         {
1122                 return FALSE;
1123         }
1124
1125 }
1126
1127
1128 /****************************************************************************/
1129 /* Set line color for object.                                               */
1130 /****************************************************************************/
1131 void    
1132 gl_label_object_set_line_color (glLabelObject     *object,
1133                                 glColorNode       *line_color_node,
1134                                 gboolean           checkpoint)
1135 {
1136         gl_debug (DEBUG_LABEL, "START");
1137
1138         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1139
1140         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1141         {
1142                 /* We have an object specific method, use it */
1143                 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node, checkpoint);
1144         }
1145
1146         gl_debug (DEBUG_LABEL, "END");
1147 }
1148
1149
1150 /****************************************************************************/
1151 /* Get line color for object.                                               */
1152 /****************************************************************************/
1153 glColorNode*
1154 gl_label_object_get_line_color (glLabelObject     *object)
1155 {
1156         glColorNode *ret = NULL;
1157
1158         gl_debug (DEBUG_LABEL, "START");
1159
1160         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1161
1162         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
1163         {
1164                 /* We have an object specific method, use it */
1165                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1166         }
1167
1168         gl_debug (DEBUG_LABEL, "END");
1169
1170         return ret;
1171 }
1172
1173
1174 /*****************************************************************************/
1175 /* Can line width property be set for this object?                           */
1176 /*****************************************************************************/
1177 gboolean
1178 gl_label_object_can_line_width (glLabelObject     *object)
1179 {
1180         gl_debug (DEBUG_LABEL, "");
1181
1182         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1183
1184         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1185         {
1186                 return TRUE;
1187         }
1188         else
1189         {
1190                 return FALSE;
1191         }
1192
1193 }
1194
1195
1196 /****************************************************************************/
1197 /* Set line width for object.                                               */
1198 /****************************************************************************/
1199 void    
1200 gl_label_object_set_line_width (glLabelObject     *object,
1201                                 gdouble            line_width,
1202                                 gboolean           checkpoint)
1203 {
1204         gl_debug (DEBUG_LABEL, "START");
1205
1206         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1207
1208         if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1209         {
1210                 /* We have an object specific method, use it */
1211                 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width, checkpoint);
1212         }
1213
1214         gl_debug (DEBUG_LABEL, "END");
1215 }
1216
1217
1218 /****************************************************************************/
1219 /* Get line width for object.                                               */
1220 /****************************************************************************/
1221 gdouble
1222 gl_label_object_get_line_width (glLabelObject     *object)
1223 {
1224         gdouble ret = 0.0;
1225
1226         gl_debug (DEBUG_LABEL, "START");
1227
1228         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1229
1230         if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
1231         {
1232                 /* We have an object specific method, use it */
1233                 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1234         }
1235
1236         gl_debug (DEBUG_LABEL, "END");
1237
1238         return ret;
1239 }
1240
1241
1242 /****************************************************************************/
1243 /* Set shadow state of object.                                              */
1244 /****************************************************************************/
1245 void    
1246 gl_label_object_set_shadow_state (glLabelObject     *object,
1247                                   gboolean           state,
1248                                   gboolean           checkpoint)
1249 {
1250         gl_debug (DEBUG_LABEL, "START");
1251
1252         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1253
1254         if (object->priv->shadow_state != state)
1255         {
1256                 if ( checkpoint )
1257                 {
1258                         gl_label_checkpoint (object->priv->parent, _("Shadow state"));
1259                 }
1260
1261                 object->priv->shadow_state = state;
1262
1263                 gl_label_object_emit_changed (object);
1264         }
1265
1266         gl_debug (DEBUG_LABEL, "END");
1267 }
1268
1269
1270 /****************************************************************************/
1271 /* Get shadow state of object.                                              */
1272 /****************************************************************************/
1273 gboolean
1274 gl_label_object_get_shadow_state (glLabelObject     *object)
1275 {
1276         gl_debug (DEBUG_LABEL, "");
1277
1278         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1279
1280         return object->priv->shadow_state;
1281 }
1282
1283
1284 /****************************************************************************/
1285 /* Set offset of object's shadow.                                           */
1286 /****************************************************************************/
1287 void    
1288 gl_label_object_set_shadow_offset (glLabelObject     *object,
1289                                    gdouble            x,
1290                                    gdouble            y,
1291                                    gboolean           checkpoint)
1292 {
1293         gl_debug (DEBUG_LABEL, "START");
1294
1295         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1296
1297         if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1298         {
1299                 if ( checkpoint )
1300                 {
1301                         gl_label_checkpoint (object->priv->parent, _("Shadow offset"));
1302                 }
1303
1304                 object->priv->shadow_x = x;
1305                 object->priv->shadow_y = y;
1306
1307                 gl_label_object_emit_changed (object);
1308         }
1309
1310         gl_debug (DEBUG_LABEL, "END");
1311 }
1312
1313
1314 /****************************************************************************/
1315 /* Get offset of object's shadow.                                           */
1316 /****************************************************************************/
1317 void
1318 gl_label_object_get_shadow_offset (glLabelObject     *object,
1319                                    gdouble           *x,
1320                                    gdouble           *y)
1321 {
1322         gl_debug (DEBUG_LABEL, "START");
1323
1324         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1325
1326         *x = object->priv->shadow_x;
1327         *y = object->priv->shadow_y;
1328
1329         gl_debug (DEBUG_LABEL, "END");
1330 }
1331
1332
1333 /****************************************************************************/
1334 /* Set color of object's shadow.                                            */
1335 /****************************************************************************/
1336 void    
1337 gl_label_object_set_shadow_color (glLabelObject     *object,
1338                                   glColorNode       *color_node,
1339                                   gboolean           checkpoint)
1340 {
1341         gl_debug (DEBUG_LABEL, "START");
1342
1343         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1344
1345         if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1346         {
1347                 if ( checkpoint )
1348                 {
1349                         gl_label_checkpoint (object->priv->parent, _("Shadow color"));
1350                 }
1351
1352                 gl_color_node_free (&(object->priv->shadow_color_node));
1353                 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1354
1355                 gl_label_object_emit_changed (object);
1356         }
1357
1358         gl_debug (DEBUG_LABEL, "END");
1359 }
1360
1361
1362 /****************************************************************************/
1363 /* Get color of object's shadow.                                            */
1364 /****************************************************************************/
1365 glColorNode*
1366 gl_label_object_get_shadow_color (glLabelObject     *object)
1367 {
1368         gl_debug (DEBUG_LABEL, "");
1369
1370         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1371
1372         return gl_color_node_dup (object->priv->shadow_color_node);
1373 }
1374
1375
1376 /****************************************************************************/
1377 /* Set opacity of object's shadow.                                          */
1378 /****************************************************************************/
1379 void    
1380 gl_label_object_set_shadow_opacity (glLabelObject     *object,
1381                                     gdouble            alpha,
1382                                     gboolean           checkpoint)
1383 {
1384         gl_debug (DEBUG_LABEL, "START");
1385
1386         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1387
1388         if (object->priv->shadow_opacity != alpha)
1389         {
1390                 if ( checkpoint )
1391                 {
1392                         gl_label_checkpoint (object->priv->parent, _("Shadow opacity"));
1393                 }
1394
1395                 object->priv->shadow_opacity = alpha;
1396
1397                 gl_label_object_emit_changed (object);
1398         }
1399
1400         gl_debug (DEBUG_LABEL, "END");
1401 }
1402
1403
1404 /****************************************************************************/
1405 /* Get opacity of object's shadow.                                          */
1406 /****************************************************************************/
1407 gdouble
1408 gl_label_object_get_shadow_opacity (glLabelObject     *object)
1409 {
1410         gl_debug (DEBUG_LABEL, "");
1411
1412         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1413
1414         return object->priv->shadow_opacity;
1415 }
1416
1417
1418 /****************************************************************************/
1419 /* Flip object horizontally.                                                */
1420 /****************************************************************************/
1421 void
1422 gl_label_object_flip_horiz (glLabelObject *object)
1423 {
1424         cairo_matrix_t flip_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_scale (&flip_matrix, -1.0, 1.0);
1431         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1432
1433         gl_debug (DEBUG_LABEL, "END");
1434 }
1435
1436
1437 /****************************************************************************/
1438 /* Flip object vertically.                                                  */
1439 /****************************************************************************/
1440 void
1441 gl_label_object_flip_vert (glLabelObject *object)
1442 {
1443         cairo_matrix_t flip_matrix;
1444
1445         gl_debug (DEBUG_LABEL, "START");
1446
1447         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1448
1449         cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1450         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1451
1452         gl_debug (DEBUG_LABEL, "END");
1453 }
1454
1455
1456 /****************************************************************************/
1457 /* Rotate object.                                                           */
1458 /****************************************************************************/
1459 void
1460 gl_label_object_rotate (glLabelObject *object,
1461                         gdouble        theta_degs)
1462 {
1463         cairo_matrix_t rotate_matrix;
1464
1465         gl_debug (DEBUG_LABEL, "START");
1466
1467         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1468
1469         cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1470         cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1471
1472         gl_debug (DEBUG_LABEL, "END");
1473 }
1474
1475
1476 /****************************************************************************/
1477 /* Set raw affine                                                           */
1478 /****************************************************************************/
1479 void
1480 gl_label_object_set_matrix (glLabelObject  *object,
1481                             cairo_matrix_t *matrix)
1482 {
1483         gl_debug (DEBUG_LABEL, "");
1484
1485         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1486
1487         object->priv->matrix = *matrix;
1488 }
1489
1490
1491 /****************************************************************************/
1492 /* Get raw affine                                                           */
1493 /****************************************************************************/
1494 void
1495 gl_label_object_get_matrix (glLabelObject  *object,
1496                             cairo_matrix_t *matrix)
1497 {
1498         gl_debug (DEBUG_LABEL, "");
1499
1500         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1501
1502         *matrix = object->priv->matrix;
1503 }
1504
1505
1506 /*****************************************************************************/
1507 /* Draw object                                                               */
1508 /*****************************************************************************/
1509 void
1510 gl_label_object_draw (glLabelObject *object,
1511                       cairo_t       *cr,
1512                       gboolean       screen_flag,
1513                       glMergeRecord *record)
1514
1515 {
1516         gdouble        x0, y0;
1517         cairo_matrix_t matrix;
1518         gboolean       shadow_state;
1519         gdouble        shadow_x, shadow_y;
1520
1521         gl_debug (DEBUG_LABEL, "START");
1522
1523         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1524
1525         gl_label_object_get_position (object, &x0, &y0);
1526         gl_label_object_get_matrix (object, &matrix);
1527
1528         cairo_save (cr);
1529         cairo_translate (cr, x0, y0);
1530
1531         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
1532         {
1533                 shadow_state = gl_label_object_get_shadow_state (object);
1534
1535                 if ( shadow_state )
1536                 {
1537                         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1538
1539                         cairo_save (cr);
1540                         cairo_translate (cr, shadow_x, shadow_y);
1541                         cairo_transform (cr, &matrix);
1542
1543                         GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1544                                                                         cr,
1545                                                                         screen_flag,
1546                                                                         record);
1547
1548                         cairo_restore (cr);
1549                 }
1550         }
1551
1552         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1553         {
1554                 cairo_save (cr);
1555                 cairo_transform (cr, &matrix);
1556
1557                 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1558                                                                 cr,
1559                                                                 screen_flag,
1560                                                                 record);
1561
1562                 cairo_restore (cr);
1563         }
1564
1565         cairo_restore (cr);
1566
1567         gl_debug (DEBUG_LABEL, "END");
1568 }
1569
1570
1571 /*****************************************************************************/
1572 /* Is object located at coordinates.                                         */
1573 /*****************************************************************************/
1574 gboolean
1575 gl_label_object_is_located_at (glLabelObject     *object,
1576                                cairo_t           *cr,
1577                                gdouble            x_pixels,
1578                                gdouble            y_pixels)
1579 {
1580         gboolean            ret_val = FALSE;
1581         gdouble             x0, y0;
1582         cairo_matrix_t      matrix;
1583         gdouble             x, y;
1584
1585         gl_debug (DEBUG_LABEL, "START");
1586
1587         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1588
1589         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1590         {
1591
1592                 gl_label_object_get_position (object, &x0, &y0);
1593                 gl_label_object_get_matrix (object, &matrix);
1594
1595                 cairo_save (cr);
1596
1597                 cairo_translate (cr, x0, y0);
1598                 cairo_transform (cr, &matrix);
1599
1600                 x = x_pixels;
1601                 y = y_pixels;
1602                 cairo_device_to_user (cr, &x, &y);
1603
1604                 ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
1605
1606                 cairo_restore (cr);
1607         }
1608
1609         gl_debug (DEBUG_LABEL, "END");
1610
1611         return ret_val;
1612 }
1613
1614
1615 /*****************************************************************************/
1616 /* Draw object handles                                                       */
1617 /*****************************************************************************/
1618 void
1619 gl_label_object_draw_handles (glLabelObject     *object,
1620                               cairo_t           *cr)
1621 {
1622         gdouble        x0, y0;
1623         cairo_matrix_t matrix;
1624
1625         gl_debug (DEBUG_LABEL, "START");
1626
1627         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1628
1629         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1630         {
1631
1632                 gl_label_object_get_position (object, &x0, &y0);
1633                 gl_label_object_get_matrix (object, &matrix);
1634
1635                 cairo_save (cr);
1636
1637                 cairo_translate (cr, x0, y0);
1638                 cairo_transform (cr, &matrix);
1639
1640                 GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
1641
1642                 cairo_restore (cr);
1643         }
1644
1645         gl_debug (DEBUG_LABEL, "END");
1646 }
1647
1648
1649 /*--------------------------------------------------------------------------*/
1650 /* Draw individual handle                                                   */
1651 /*--------------------------------------------------------------------------*/
1652 static void
1653 draw_handle (cairo_t                *cr,
1654              glLabelObject          *object,
1655              gdouble                 x_handle,
1656              gdouble                 y_handle)
1657 {
1658         gdouble scale_x, scale_y;
1659
1660
1661         gl_debug (DEBUG_VIEW, "START");
1662
1663         cairo_save (cr);
1664
1665         cairo_translate (cr, x_handle, y_handle);
1666
1667         scale_x = 1.0;
1668         scale_y = 1.0;
1669         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1670         cairo_scale (cr, scale_x, scale_y);
1671
1672         cairo_rectangle (cr,
1673                          -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1674                          HANDLE_PIXELS, HANDLE_PIXELS);
1675
1676         cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
1677         cairo_fill_preserve (cr);
1678                                
1679         cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
1680         cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
1681         cairo_stroke (cr);
1682
1683         cairo_restore (cr);
1684
1685         gl_debug (DEBUG_VIEW, "END");
1686 }
1687
1688
1689 /*--------------------------------------------------------------------------*/
1690 /* Create handle path                                                       */
1691 /*--------------------------------------------------------------------------*/
1692 static void
1693 create_handle_path (cairo_t                *cr,
1694                     glLabelObject          *object,
1695                     gdouble                 x_handle,
1696                     gdouble                 y_handle)
1697 {
1698         gdouble scale_x, scale_y;
1699
1700
1701         gl_debug (DEBUG_VIEW, "START");
1702
1703         cairo_save (cr);
1704
1705         cairo_translate (cr, x_handle, y_handle);
1706
1707         scale_x = 1.0;
1708         scale_y = 1.0;
1709         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1710         cairo_scale (cr, scale_x, scale_y);
1711
1712         cairo_rectangle (cr,
1713                          -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1714                          HANDLE_PIXELS, HANDLE_PIXELS);
1715
1716         cairo_restore (cr);
1717
1718         gl_debug (DEBUG_VIEW, "END");
1719 }
1720
1721
1722 /*****************************************************************************/
1723 /* Draw box style handles.                                                   */
1724 /*****************************************************************************/
1725 void
1726 gl_label_object_draw_handles_box (glLabelObject     *object,
1727                                   cairo_t           *cr)
1728 {
1729         gdouble w, h;
1730
1731         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1732
1733         /* North */
1734         draw_handle (cr, object, w/2, 0);
1735
1736         /* North East */
1737         draw_handle (cr, object, w, 0);
1738
1739         /* East */
1740         draw_handle (cr, object, w, h/2);
1741
1742         /* South East */
1743         draw_handle (cr, object, w, h);
1744
1745         /* South */
1746         draw_handle (cr, object, w/2, h);
1747
1748         /* South West */
1749         draw_handle (cr, object, 0, h);
1750
1751         /* West */
1752         draw_handle (cr, object, 0, h/2);
1753
1754         /* North West */
1755         draw_handle (cr, object, 0, 0);
1756 }
1757
1758
1759 /*****************************************************************************/
1760 /* Draw line style handles.                                                  */
1761 /*****************************************************************************/
1762 void
1763 gl_label_object_draw_handles_line (glLabelObject     *object,
1764                                    cairo_t           *cr)
1765 {
1766         gdouble w, h;
1767
1768         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1769
1770         /* P2 */
1771         draw_handle (cr, object, w, h);
1772
1773         /* P1 */
1774         draw_handle (cr, object, 0, 0);
1775 }
1776
1777
1778 /*****************************************************************************/
1779 /* Get handle at given coordinates, if any.                                  */
1780 /*****************************************************************************/
1781 glLabelObjectHandle
1782 gl_label_object_handle_at (glLabelObject     *object,
1783                            cairo_t           *cr,
1784                            gdouble            x_pixels,
1785                            gdouble            y_pixels)
1786 {
1787         glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
1788         gdouble             x0, y0;
1789         cairo_matrix_t      matrix;
1790         gdouble             x, y;
1791
1792         gl_debug (DEBUG_LABEL, "START");
1793
1794         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
1795
1796         if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1797         {
1798
1799                 gl_label_object_get_position (object, &x0, &y0);
1800                 gl_label_object_get_matrix (object, &matrix);
1801
1802                 cairo_save (cr);
1803
1804                 cairo_translate (cr, x0, y0);
1805                 cairo_transform (cr, &matrix);
1806
1807                 x = x_pixels;
1808                 y = y_pixels;
1809                 cairo_device_to_user (cr, &x, &y);
1810
1811                 handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
1812
1813                 cairo_restore (cr);
1814         }
1815
1816         gl_debug (DEBUG_LABEL, "END");
1817
1818         return handle;
1819 }
1820
1821
1822 /*****************************************************************************/
1823 /* Get handle at given coordinates for box style handles, if any.            */
1824 /*****************************************************************************/
1825 glLabelObjectHandle
1826 gl_label_object_box_handle_at (glLabelObject     *object,
1827                                cairo_t           *cr,
1828                                gdouble            x,
1829                                gdouble            y)
1830 {
1831         gdouble w, h;
1832
1833         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1834
1835         /* South East */
1836         create_handle_path (cr, object, w, h);
1837         if (cairo_in_fill (cr, x, y))
1838         {
1839                 return GL_LABEL_OBJECT_HANDLE_SE;
1840         }
1841         
1842         /* South West */
1843         create_handle_path (cr, object, 0, h);
1844         if (cairo_in_fill (cr, x, y))
1845         {
1846                 return GL_LABEL_OBJECT_HANDLE_SW;
1847         }
1848
1849         /* North East */
1850         create_handle_path (cr, object, w, 0);
1851         if (cairo_in_fill (cr, x, y))
1852         {
1853                 return GL_LABEL_OBJECT_HANDLE_NE;
1854         }
1855
1856         /* North West */
1857         create_handle_path (cr, object, 0, 0);
1858         if (cairo_in_fill (cr, x, y))
1859         {
1860                 return GL_LABEL_OBJECT_HANDLE_NW;
1861         }
1862
1863         /* East */
1864         create_handle_path (cr, object, w, h/2);
1865         if (cairo_in_fill (cr, x, y))
1866         {
1867                 return GL_LABEL_OBJECT_HANDLE_E;
1868         }
1869
1870         /* South */
1871         create_handle_path (cr, object, w/2, h);
1872         if (cairo_in_fill (cr, x, y))
1873         {
1874                 return GL_LABEL_OBJECT_HANDLE_S;
1875         }
1876
1877         /* West */
1878         create_handle_path (cr, object, 0, h/2);
1879         if (cairo_in_fill (cr, x, y))
1880         {
1881                 return GL_LABEL_OBJECT_HANDLE_W;
1882         }
1883
1884         /* North */
1885         create_handle_path (cr, object, w/2, 0);
1886         if (cairo_in_fill (cr, x, y))
1887         {
1888                 return GL_LABEL_OBJECT_HANDLE_N;
1889         }
1890
1891         return GL_LABEL_OBJECT_HANDLE_NONE;
1892 }
1893
1894
1895 /*****************************************************************************/
1896 /* Get handle at given coordinates for line style handles, if any.           */
1897 /*****************************************************************************/
1898 glLabelObjectHandle
1899 gl_label_object_line_handle_at (glLabelObject     *object,
1900                                 cairo_t           *cr,
1901                                 gdouble            x,
1902                                 gdouble            y)
1903 {
1904         gdouble w, h;
1905
1906         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1907
1908         /* P2 */
1909         create_handle_path (cr, object, w, h);
1910         if (cairo_in_fill (cr, x, y))
1911         {
1912                 return GL_LABEL_OBJECT_HANDLE_P2;
1913         }
1914         
1915         /* P1 */
1916         create_handle_path (cr, object, 0, h);
1917         if (cairo_in_fill (cr, x, y))
1918         {
1919                 return GL_LABEL_OBJECT_HANDLE_P1;
1920         }
1921
1922         return GL_LABEL_OBJECT_HANDLE_NONE;
1923 }
1924
1925
1926
1927
1928 /*
1929  * Local Variables:       -- emacs
1930  * mode: C                -- emacs
1931  * c-basic-offset: 8      -- emacs
1932  * tab-width: 8           -- emacs
1933  * indent-tabs-mode: nil  -- emacs
1934  * End:                   -- emacs
1935  */