3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
23 #include "label-object.h"
25 #include <glib/gi18n.h>
34 /*========================================================*/
35 /* Private defines. */
36 /*========================================================*/
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)
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
46 #define HANDLE_OUTLINE_WIDTH_PIXELS 1.0
47 #define HANDLE_PIXELS 7
50 /*========================================================*/
52 /*========================================================*/
54 struct _glLabelObjectPrivate {
58 gboolean selected_flag;
63 cairo_matrix_t matrix;
67 gboolean shadow_state;
70 glColorNode *shadow_color_node;
71 gdouble shadow_opacity;
80 /*========================================================*/
81 /* Private globals. */
82 /*========================================================*/
84 static guint instance = 0;
86 static guint signals[LAST_SIGNAL] = {0};
89 /*========================================================*/
90 /* Private function prototypes. */
91 /*========================================================*/
93 static void gl_label_object_finalize (GObject *object);
95 static void set_size (glLabelObject *object,
101 /*****************************************************************************/
102 /* Boilerplate object stuff. */
103 /*****************************************************************************/
104 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT);
108 gl_label_object_class_init (glLabelObjectClass *class)
110 GObjectClass *object_class = G_OBJECT_CLASS (class);
112 gl_debug (DEBUG_LABEL, "START");
114 gl_label_object_parent_class = g_type_class_peek_parent (class);
116 object_class->finalize = gl_label_object_finalize;
118 class->set_size = set_size;
119 class->draw_handles = gl_label_object_draw_handles_box; /* Default style */
120 class->handle_at = gl_label_object_box_handle_at; /* Default style */
123 g_signal_new ("changed",
124 G_OBJECT_CLASS_TYPE (object_class),
126 G_STRUCT_OFFSET (glLabelObjectClass, changed),
128 gl_marshal_VOID__VOID,
132 gl_debug (DEBUG_LABEL, "END");
137 gl_label_object_init (glLabelObject *object)
139 gl_debug (DEBUG_LABEL, "START");
141 object->priv = g_new0 (glLabelObjectPrivate, 1);
143 object->priv->name = g_strdup_printf ("object%d", instance++);
145 cairo_matrix_init_identity (&object->priv->matrix);
147 object->priv->shadow_state = FALSE;
148 object->priv->shadow_x = DEFAULT_SHADOW_X_OFFSET;
149 object->priv->shadow_y = DEFAULT_SHADOW_Y_OFFSET;
150 object->priv->shadow_color_node = gl_color_node_new_default ();
151 object->priv->shadow_color_node->color = DEFAULT_SHADOW_COLOR;
152 object->priv->shadow_opacity = DEFAULT_SHADOW_OPACITY;
154 gl_debug (DEBUG_LABEL, "END");
159 gl_label_object_finalize (GObject *object)
161 glLabelObject *label_object = GL_LABEL_OBJECT (object);
163 gl_debug (DEBUG_LABEL, "START");
165 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
167 g_free (label_object->priv->name);
168 g_free (label_object->priv);
170 G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
172 gl_debug (DEBUG_LABEL, "END");
176 /*****************************************************************************/
177 /* New label object. */
178 /*****************************************************************************/
180 gl_label_object_new (glLabel *label)
182 glLabelObject *object;
184 gl_debug (DEBUG_LABEL, "START");
186 object = g_object_new (gl_label_object_get_type(), NULL);
188 gl_label_object_set_parent (object, label);
190 gl_debug (DEBUG_LABEL, "END");
192 return G_OBJECT (object);
196 /*****************************************************************************/
197 /* Duplicate object. */
198 /*****************************************************************************/
200 gl_label_object_dup (glLabelObject *src_object,
203 glLabelObject *dst_object;
205 cairo_matrix_t matrix;
206 gboolean shadow_state;
207 gdouble shadow_x, shadow_y;
208 glColorNode *shadow_color_node;
209 gdouble shadow_opacity;
211 gl_debug (DEBUG_LABEL, "START");
213 g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
215 dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
217 gl_label_object_set_parent (dst_object, label);
218 dst_object->priv->selected_flag = src_object->priv->selected_flag;
220 gl_label_object_get_position (src_object, &x, &y);
221 gl_label_object_get_raw_size (src_object, &w, &h);
222 gl_label_object_get_matrix (src_object, &matrix);
223 gl_label_object_get_shadow_offset (src_object, &shadow_x, &shadow_y);
224 shadow_color_node = gl_label_object_get_shadow_color (src_object);
225 shadow_opacity = gl_label_object_get_shadow_opacity (src_object);
226 shadow_state = gl_label_object_get_shadow_state (src_object);
228 gl_label_object_set_position (dst_object, x, y, FALSE);
229 gl_label_object_set_size (dst_object, w, h, FALSE);
230 gl_label_object_set_matrix (dst_object, &matrix);
231 gl_label_object_set_shadow_offset (dst_object, shadow_x, shadow_y, FALSE);
232 gl_label_object_set_shadow_color (dst_object, shadow_color_node, FALSE);
233 gl_label_object_set_shadow_opacity (dst_object, shadow_opacity, FALSE);
234 gl_label_object_set_shadow_state (dst_object, shadow_state, FALSE);
236 gl_color_node_free (&shadow_color_node);
238 if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL )
240 /* We have an object specific method, use it */
241 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
244 gl_debug (DEBUG_LABEL, "END");
250 /*****************************************************************************/
251 /* Emit "changed" signal (for derived objects). */
252 /*****************************************************************************/
254 gl_label_object_emit_changed (glLabelObject *object)
256 gl_debug (DEBUG_LABEL, "START");
258 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
260 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
262 gl_debug (DEBUG_LABEL, "END");
266 /*****************************************************************************/
267 /* Set parent label of object. */
268 /*****************************************************************************/
270 gl_label_object_set_parent (glLabelObject *object,
273 gl_debug (DEBUG_LABEL, "START");
275 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
276 g_return_if_fail (label && GL_IS_LABEL (label));
278 object->priv->parent = label;
282 /*****************************************************************************/
283 /* Get parent label of object. */
284 /*****************************************************************************/
286 gl_label_object_get_parent (glLabelObject *object)
288 gl_debug (DEBUG_LABEL, "START");
290 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
292 gl_debug (DEBUG_LABEL, "END");
294 return object->priv->parent;
298 /*****************************************************************************/
300 /*****************************************************************************/
302 gl_label_object_select (glLabelObject *object)
304 object->priv->selected_flag = TRUE;
308 /*****************************************************************************/
309 /* Unselect object. */
310 /*****************************************************************************/
312 gl_label_object_unselect (glLabelObject *object)
314 object->priv->selected_flag = FALSE;
318 /*****************************************************************************/
319 /* Is object selected? */
320 /*****************************************************************************/
322 gl_label_object_is_selected (glLabelObject *object)
324 return object->priv->selected_flag;
328 /*****************************************************************************/
329 /* Set name of object. */
330 /*****************************************************************************/
332 gl_label_object_set_name (glLabelObject *object,
335 gl_debug (DEBUG_LABEL, "START");
337 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
339 g_free(object->priv->name);
340 object->priv->name = name;
342 gl_label_object_emit_changed (object);
344 gl_debug (DEBUG_LABEL, "END");
348 /*****************************************************************************/
349 /* Get name of object. */
350 /*****************************************************************************/
352 gl_label_object_get_name (glLabelObject *object)
354 gl_debug (DEBUG_LABEL, "START");
356 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
358 gl_debug (DEBUG_LABEL, "END");
360 return g_strdup(object->priv->name);
364 /*****************************************************************************/
365 /* Set position of object. */
366 /*****************************************************************************/
368 gl_label_object_set_position (glLabelObject *object,
375 gl_debug (DEBUG_LABEL, "START");
377 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
379 if ( (x != object->priv->x) || (y != object->priv->y) )
383 gl_label_checkpoint (object->priv->parent, _("Move"));
386 dx = x - object->priv->x;
387 dy = y - object->priv->y;
393 gl_label_object_emit_changed (object);
395 gl_debug (DEBUG_LABEL, "END");
399 /*****************************************************************************/
400 /* Set position of object relative to old position. */
401 /*****************************************************************************/
403 gl_label_object_set_position_relative (glLabelObject *object,
408 gl_debug (DEBUG_LABEL, "START");
410 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
412 if ( (dx != 0.0) || (dy != 0.0) )
416 gl_label_checkpoint (object->priv->parent, _("Move"));
419 object->priv->x += dx;
420 object->priv->y += dy;
422 gl_debug (DEBUG_LABEL, " x = %f, y= %f",
427 gl_label_object_emit_changed (object);
429 gl_debug (DEBUG_LABEL, "END");
433 /*****************************************************************************/
434 /* Get position of object. */
435 /*****************************************************************************/
437 gl_label_object_get_position (glLabelObject *object,
441 gl_debug (DEBUG_LABEL, "START");
443 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
445 *x = object->priv->x;
446 *y = object->priv->y;
448 gl_debug (DEBUG_LABEL, "END");
452 /*---------------------------------------------------------------------------*/
453 /* PRIVATE. Default set size method. */
454 /*---------------------------------------------------------------------------*/
456 set_size (glLabelObject *object,
461 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
463 if ( (object->priv->w != w) || (object->priv->h != h) )
467 gl_label_checkpoint (object->priv->parent, _("Resize"));
473 gl_label_object_emit_changed (object);
478 /*****************************************************************************/
479 /* Set size of object. */
480 /*****************************************************************************/
482 gl_label_object_set_size (glLabelObject *object,
487 gl_debug (DEBUG_LABEL, "START");
489 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
491 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
493 /* We have an object specific method, use it */
494 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
496 object->priv->aspect_ratio = h / w;
499 gl_debug (DEBUG_LABEL, "END");
503 /*****************************************************************************/
504 /* Set size of object honoring current aspect ratio. */
505 /*****************************************************************************/
507 gl_label_object_set_size_honor_aspect (glLabelObject *object,
512 gl_debug (DEBUG_LABEL, "START");
514 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
516 if ( h > w*object->priv->aspect_ratio )
518 h = w * object->priv->aspect_ratio;
522 w = h / object->priv->aspect_ratio;
525 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
527 /* We have an object specific method, use it */
528 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
531 gl_debug (DEBUG_LABEL, "END");
535 /*****************************************************************************/
536 /* Get raw size method (don't let object content adjust size). */
537 /*****************************************************************************/
539 gl_label_object_get_raw_size (glLabelObject *object,
543 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
545 *w = object->priv->w;
546 *h = object->priv->h;
550 /*****************************************************************************/
551 /* Get size of object. */
552 /*****************************************************************************/
554 gl_label_object_get_size (glLabelObject *object,
558 gl_debug (DEBUG_LABEL, "START");
560 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
562 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
564 /* We have an object specific method, use it */
565 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
569 gl_label_object_get_raw_size (object, w, h);
572 gl_debug (DEBUG_LABEL, "END");
576 /*****************************************************************************/
577 /* Get extent of object. */
578 /*****************************************************************************/
580 gl_label_object_get_extent (glLabelObject *object,
581 glLabelRegion *region)
585 gdouble xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
586 cairo_matrix_t matrix;
588 gl_debug (DEBUG_LABEL, "START");
590 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
592 gl_label_object_get_size (object, &w, &h);
593 line_w = gl_label_object_get_line_width (object);
595 /* setup untransformed corners of bounding box, account for line width */
605 /* transform these points */
606 gl_label_object_get_matrix (object, &matrix);
607 cairo_matrix_transform_point (&matrix, &xa1, &ya1);
608 cairo_matrix_transform_point (&matrix, &xa2, &ya2);
609 cairo_matrix_transform_point (&matrix, &xa3, &ya3);
610 cairo_matrix_transform_point (&matrix, &xa4, &ya4);
612 /* now find the maximum extent of these points in x and y */
613 region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
614 region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
615 region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
616 region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
618 gl_debug (DEBUG_LABEL, "END");
622 /*****************************************************************************/
623 /* Can text properties be set for this object? */
624 /*****************************************************************************/
626 gl_label_object_can_text (glLabelObject *object)
628 gl_debug (DEBUG_LABEL, "");
630 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
632 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
643 /*****************************************************************************/
644 /* Set font family for all text contained in object. */
645 /*****************************************************************************/
647 gl_label_object_set_font_family (glLabelObject *object,
648 const gchar *font_family,
651 gl_debug (DEBUG_LABEL, "START");
653 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
655 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
657 /* We have an object specific method, use it */
658 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family, checkpoint);
661 gl_debug (DEBUG_LABEL, "END");
665 /****************************************************************************/
666 /* Set font size for all text contained in object. */
667 /****************************************************************************/
669 gl_label_object_set_font_size (glLabelObject *object,
673 gl_debug (DEBUG_LABEL, "START");
675 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
677 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
679 /* We have an object specific method, use it */
680 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size, checkpoint);
683 gl_debug (DEBUG_LABEL, "END");
687 /****************************************************************************/
688 /* Set font weight for all text contained in object. */
689 /****************************************************************************/
691 gl_label_object_set_font_weight (glLabelObject *object,
692 PangoWeight font_weight,
695 gl_debug (DEBUG_LABEL, "START");
697 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
699 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL )
701 /* We have an object specific method, use it */
702 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight, checkpoint);
705 gl_debug (DEBUG_LABEL, "END");
709 /****************************************************************************/
710 /* Set font italic flag for all text contained in object. */
711 /****************************************************************************/
713 gl_label_object_set_font_italic_flag (glLabelObject *object,
714 gboolean font_italic_flag,
717 gl_debug (DEBUG_LABEL, "START");
719 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
721 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
723 /* We have an object specific method, use it */
724 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag, checkpoint);
727 gl_debug (DEBUG_LABEL, "END");
731 /****************************************************************************/
732 /* Set text alignment for all text contained in object. */
733 /****************************************************************************/
735 gl_label_object_set_text_alignment (glLabelObject *object,
736 PangoAlignment text_alignment,
739 gl_debug (DEBUG_LABEL, "START");
741 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
743 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
745 /* We have an object specific method, use it */
746 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment, checkpoint);
749 gl_debug (DEBUG_LABEL, "END");
753 /****************************************************************************/
754 /* Set text line spacing for all text contained in object. */
755 /****************************************************************************/
757 gl_label_object_set_text_line_spacing (glLabelObject *object,
758 gdouble text_line_spacing,
761 gl_debug (DEBUG_LABEL, "START");
763 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
765 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
767 /* We have an object specific method, use it */
768 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing, checkpoint);
771 gl_debug (DEBUG_LABEL, "END");
775 /****************************************************************************/
776 /* Set text color for all text contained in object. */
777 /****************************************************************************/
779 gl_label_object_set_text_color (glLabelObject *object,
780 glColorNode *text_color_node,
783 gl_debug (DEBUG_LABEL, "START");
785 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
787 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
789 /* We have an object specific method, use it */
790 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node, checkpoint);
793 gl_debug (DEBUG_LABEL, "END");
797 /*****************************************************************************/
798 /* Get font family for all text contained in object. */
799 /*****************************************************************************/
801 gl_label_object_get_font_family (glLabelObject *object)
805 gl_debug (DEBUG_LABEL, "START");
807 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
809 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
811 /* We have an object specific method, use it */
812 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
815 gl_debug (DEBUG_LABEL, "END");
821 /****************************************************************************/
822 /* Get font size for all text contained in object. */
823 /****************************************************************************/
825 gl_label_object_get_font_size (glLabelObject *object)
829 gl_debug (DEBUG_LABEL, "START");
831 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
833 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
835 /* We have an object specific method, use it */
836 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
839 gl_debug (DEBUG_LABEL, "END");
845 /****************************************************************************/
846 /* Get font weight for all text contained in object. */
847 /****************************************************************************/
849 gl_label_object_get_font_weight (glLabelObject *object)
851 PangoWeight ret = PANGO_WEIGHT_NORMAL;
853 gl_debug (DEBUG_LABEL, "START");
855 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
857 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
859 /* We have an object specific method, use it */
860 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
863 gl_debug (DEBUG_LABEL, "END");
869 /****************************************************************************/
870 /* Get font italic flag for all text contained in object. */
871 /****************************************************************************/
873 gl_label_object_get_font_italic_flag (glLabelObject *object)
875 gboolean ret = FALSE;
877 gl_debug (DEBUG_LABEL, "START");
879 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
881 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
883 /* We have an object specific method, use it */
884 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
887 gl_debug (DEBUG_LABEL, "END");
893 /****************************************************************************/
894 /* Get text alignment for all text contained in object. */
895 /****************************************************************************/
897 gl_label_object_get_text_alignment (glLabelObject *object)
899 PangoAlignment ret = PANGO_ALIGN_LEFT;
901 gl_debug (DEBUG_LABEL, "START");
903 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
905 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
907 /* We have an object specific method, use it */
908 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
911 gl_debug (DEBUG_LABEL, "END");
917 /****************************************************************************/
918 /* Get text line spacing for all text contained in object. */
919 /****************************************************************************/
921 gl_label_object_get_text_line_spacing (glLabelObject *object)
925 gl_debug (DEBUG_LABEL, "START");
927 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
929 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
931 /* We have an object specific method, use it */
932 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
935 gl_debug (DEBUG_LABEL, "END");
941 /****************************************************************************/
942 /* Get text color for all text contained in object. */
943 /****************************************************************************/
945 gl_label_object_get_text_color (glLabelObject *object)
947 glColorNode *ret = NULL;
949 gl_debug (DEBUG_LABEL, "START");
951 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
953 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
955 /* We have an object specific method, use it */
956 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
959 gl_debug (DEBUG_LABEL, "END");
965 /*****************************************************************************/
966 /* Can fill properties be set for this object? */
967 /*****************************************************************************/
969 gl_label_object_can_fill (glLabelObject *object)
971 gl_debug (DEBUG_LABEL, "");
973 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
975 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
987 /****************************************************************************/
988 /* Set fill color for object. */
989 /****************************************************************************/
991 gl_label_object_set_fill_color (glLabelObject *object,
992 glColorNode *fill_color_node,
995 gl_debug (DEBUG_LABEL, "START");
997 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
999 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1001 /* We have an object specific method, use it */
1002 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node, checkpoint);
1005 gl_debug (DEBUG_LABEL, "END");
1009 /****************************************************************************/
1010 /* Get fill color for object. */
1011 /****************************************************************************/
1013 gl_label_object_get_fill_color (glLabelObject *object)
1015 glColorNode *ret = NULL;
1017 gl_debug (DEBUG_LABEL, "START");
1019 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1021 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
1023 /* We have an object specific method, use it */
1024 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1027 gl_debug (DEBUG_LABEL, "END");
1033 /*****************************************************************************/
1034 /* Can line color property be set for this object? */
1035 /*****************************************************************************/
1037 gl_label_object_can_line_color (glLabelObject *object)
1039 gl_debug (DEBUG_LABEL, "");
1041 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1043 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1055 /****************************************************************************/
1056 /* Set line color for object. */
1057 /****************************************************************************/
1059 gl_label_object_set_line_color (glLabelObject *object,
1060 glColorNode *line_color_node,
1061 gboolean checkpoint)
1063 gl_debug (DEBUG_LABEL, "START");
1065 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1067 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1069 /* We have an object specific method, use it */
1070 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node, checkpoint);
1073 gl_debug (DEBUG_LABEL, "END");
1077 /****************************************************************************/
1078 /* Get line color for object. */
1079 /****************************************************************************/
1081 gl_label_object_get_line_color (glLabelObject *object)
1083 glColorNode *ret = NULL;
1085 gl_debug (DEBUG_LABEL, "START");
1087 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1089 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
1091 /* We have an object specific method, use it */
1092 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1095 gl_debug (DEBUG_LABEL, "END");
1101 /*****************************************************************************/
1102 /* Can line width property be set for this object? */
1103 /*****************************************************************************/
1105 gl_label_object_can_line_width (glLabelObject *object)
1107 gl_debug (DEBUG_LABEL, "");
1109 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1111 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1123 /****************************************************************************/
1124 /* Set line width for object. */
1125 /****************************************************************************/
1127 gl_label_object_set_line_width (glLabelObject *object,
1129 gboolean checkpoint)
1131 gl_debug (DEBUG_LABEL, "START");
1133 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1135 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1137 /* We have an object specific method, use it */
1138 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width, checkpoint);
1141 gl_debug (DEBUG_LABEL, "END");
1145 /****************************************************************************/
1146 /* Get line width for object. */
1147 /****************************************************************************/
1149 gl_label_object_get_line_width (glLabelObject *object)
1153 gl_debug (DEBUG_LABEL, "START");
1155 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1157 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
1159 /* We have an object specific method, use it */
1160 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1163 gl_debug (DEBUG_LABEL, "END");
1169 /****************************************************************************/
1170 /* Set shadow state of object. */
1171 /****************************************************************************/
1173 gl_label_object_set_shadow_state (glLabelObject *object,
1175 gboolean checkpoint)
1177 gl_debug (DEBUG_LABEL, "START");
1179 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1181 if (object->priv->shadow_state != state)
1185 gl_label_checkpoint (object->priv->parent, _("Shadow state"));
1188 object->priv->shadow_state = state;
1190 gl_label_object_emit_changed (object);
1193 gl_debug (DEBUG_LABEL, "END");
1197 /****************************************************************************/
1198 /* Get shadow state of object. */
1199 /****************************************************************************/
1201 gl_label_object_get_shadow_state (glLabelObject *object)
1203 gl_debug (DEBUG_LABEL, "");
1205 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1207 return object->priv->shadow_state;
1211 /****************************************************************************/
1212 /* Set offset of object's shadow. */
1213 /****************************************************************************/
1215 gl_label_object_set_shadow_offset (glLabelObject *object,
1218 gboolean checkpoint)
1220 gl_debug (DEBUG_LABEL, "START");
1222 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1224 if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1228 gl_label_checkpoint (object->priv->parent, _("Shadow offset"));
1231 object->priv->shadow_x = x;
1232 object->priv->shadow_y = y;
1234 gl_label_object_emit_changed (object);
1237 gl_debug (DEBUG_LABEL, "END");
1241 /****************************************************************************/
1242 /* Get offset of object's shadow. */
1243 /****************************************************************************/
1245 gl_label_object_get_shadow_offset (glLabelObject *object,
1249 gl_debug (DEBUG_LABEL, "START");
1251 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1253 *x = object->priv->shadow_x;
1254 *y = object->priv->shadow_y;
1256 gl_debug (DEBUG_LABEL, "END");
1260 /****************************************************************************/
1261 /* Set color of object's shadow. */
1262 /****************************************************************************/
1264 gl_label_object_set_shadow_color (glLabelObject *object,
1265 glColorNode *color_node,
1266 gboolean checkpoint)
1268 gl_debug (DEBUG_LABEL, "START");
1270 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1272 if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1276 gl_label_checkpoint (object->priv->parent, _("Shadow color"));
1279 gl_color_node_free (&(object->priv->shadow_color_node));
1280 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1282 gl_label_object_emit_changed (object);
1285 gl_debug (DEBUG_LABEL, "END");
1289 /****************************************************************************/
1290 /* Get color of object's shadow. */
1291 /****************************************************************************/
1293 gl_label_object_get_shadow_color (glLabelObject *object)
1295 gl_debug (DEBUG_LABEL, "");
1297 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1299 return gl_color_node_dup (object->priv->shadow_color_node);
1303 /****************************************************************************/
1304 /* Set opacity of object's shadow. */
1305 /****************************************************************************/
1307 gl_label_object_set_shadow_opacity (glLabelObject *object,
1309 gboolean checkpoint)
1311 gl_debug (DEBUG_LABEL, "START");
1313 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1315 if (object->priv->shadow_opacity != alpha)
1319 gl_label_checkpoint (object->priv->parent, _("Shadow opacity"));
1322 object->priv->shadow_opacity = alpha;
1324 gl_label_object_emit_changed (object);
1327 gl_debug (DEBUG_LABEL, "END");
1331 /****************************************************************************/
1332 /* Get opacity of object's shadow. */
1333 /****************************************************************************/
1335 gl_label_object_get_shadow_opacity (glLabelObject *object)
1337 gl_debug (DEBUG_LABEL, "");
1339 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1341 return object->priv->shadow_opacity;
1345 /****************************************************************************/
1346 /* Flip object horizontally. */
1347 /****************************************************************************/
1349 gl_label_object_flip_horiz (glLabelObject *object)
1351 cairo_matrix_t flip_matrix;
1353 gl_debug (DEBUG_LABEL, "START");
1355 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1357 cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1358 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1360 gl_debug (DEBUG_LABEL, "END");
1364 /****************************************************************************/
1365 /* Flip object vertically. */
1366 /****************************************************************************/
1368 gl_label_object_flip_vert (glLabelObject *object)
1370 cairo_matrix_t flip_matrix;
1372 gl_debug (DEBUG_LABEL, "START");
1374 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1376 cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1377 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1379 gl_debug (DEBUG_LABEL, "END");
1383 /****************************************************************************/
1384 /* Rotate object. */
1385 /****************************************************************************/
1387 gl_label_object_rotate (glLabelObject *object,
1390 cairo_matrix_t rotate_matrix;
1392 gl_debug (DEBUG_LABEL, "START");
1394 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1396 cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1397 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1399 gl_debug (DEBUG_LABEL, "END");
1403 /****************************************************************************/
1404 /* Set raw affine */
1405 /****************************************************************************/
1407 gl_label_object_set_matrix (glLabelObject *object,
1408 cairo_matrix_t *matrix)
1410 gl_debug (DEBUG_LABEL, "");
1412 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1414 object->priv->matrix = *matrix;
1418 /****************************************************************************/
1419 /* Get raw affine */
1420 /****************************************************************************/
1422 gl_label_object_get_matrix (glLabelObject *object,
1423 cairo_matrix_t *matrix)
1425 gl_debug (DEBUG_LABEL, "");
1427 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1429 *matrix = object->priv->matrix;
1433 /*****************************************************************************/
1435 /*****************************************************************************/
1437 gl_label_object_draw (glLabelObject *object,
1439 gboolean screen_flag,
1440 glMergeRecord *record)
1444 cairo_matrix_t matrix;
1445 gboolean shadow_state;
1446 gdouble shadow_x, shadow_y;
1448 gl_debug (DEBUG_LABEL, "START");
1450 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1452 gl_label_object_get_position (object, &x0, &y0);
1453 gl_label_object_get_matrix (object, &matrix);
1456 cairo_translate (cr, x0, y0);
1458 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
1460 shadow_state = gl_label_object_get_shadow_state (object);
1464 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1467 cairo_translate (cr, shadow_x, shadow_y);
1468 cairo_transform (cr, &matrix);
1470 GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1479 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1482 cairo_transform (cr, &matrix);
1484 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1494 gl_debug (DEBUG_LABEL, "END");
1498 /*****************************************************************************/
1499 /* Is object located at coordinates. */
1500 /*****************************************************************************/
1502 gl_label_object_is_located_at (glLabelObject *object,
1507 gboolean ret_val = FALSE;
1509 cairo_matrix_t matrix;
1512 gl_debug (DEBUG_LABEL, "START");
1514 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1516 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1519 gl_label_object_get_position (object, &x0, &y0);
1520 gl_label_object_get_matrix (object, &matrix);
1524 cairo_translate (cr, x0, y0);
1525 cairo_transform (cr, &matrix);
1529 cairo_device_to_user (cr, &x, &y);
1531 ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
1536 gl_debug (DEBUG_LABEL, "END");
1542 /*****************************************************************************/
1543 /* Draw object handles */
1544 /*****************************************************************************/
1546 gl_label_object_draw_handles (glLabelObject *object,
1550 cairo_matrix_t matrix;
1552 gl_debug (DEBUG_LABEL, "START");
1554 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1556 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1559 gl_label_object_get_position (object, &x0, &y0);
1560 gl_label_object_get_matrix (object, &matrix);
1564 cairo_translate (cr, x0, y0);
1565 cairo_transform (cr, &matrix);
1567 GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
1572 gl_debug (DEBUG_LABEL, "END");
1576 /*--------------------------------------------------------------------------*/
1577 /* Draw individual handle */
1578 /*--------------------------------------------------------------------------*/
1580 draw_handle (cairo_t *cr,
1581 glLabelObject *object,
1585 gdouble scale_x, scale_y;
1588 gl_debug (DEBUG_VIEW, "START");
1592 cairo_translate (cr, x_handle, y_handle);
1596 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1597 cairo_scale (cr, scale_x, scale_y);
1599 cairo_rectangle (cr,
1600 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1601 HANDLE_PIXELS, HANDLE_PIXELS);
1603 cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
1604 cairo_fill_preserve (cr);
1606 cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
1607 cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
1612 gl_debug (DEBUG_VIEW, "END");
1616 /*--------------------------------------------------------------------------*/
1617 /* Create handle path */
1618 /*--------------------------------------------------------------------------*/
1620 create_handle_path (cairo_t *cr,
1621 glLabelObject *object,
1625 gdouble scale_x, scale_y;
1628 gl_debug (DEBUG_VIEW, "START");
1632 cairo_translate (cr, x_handle, y_handle);
1636 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1637 cairo_scale (cr, scale_x, scale_y);
1639 cairo_rectangle (cr,
1640 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1641 HANDLE_PIXELS, HANDLE_PIXELS);
1645 gl_debug (DEBUG_VIEW, "END");
1649 /*****************************************************************************/
1650 /* Draw box style handles. */
1651 /*****************************************************************************/
1653 gl_label_object_draw_handles_box (glLabelObject *object,
1658 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1661 draw_handle (cr, object, w/2, 0);
1664 draw_handle (cr, object, w, 0);
1667 draw_handle (cr, object, w, h/2);
1670 draw_handle (cr, object, w, h);
1673 draw_handle (cr, object, w/2, h);
1676 draw_handle (cr, object, 0, h);
1679 draw_handle (cr, object, 0, h/2);
1682 draw_handle (cr, object, 0, 0);
1686 /*****************************************************************************/
1687 /* Draw line style handles. */
1688 /*****************************************************************************/
1690 gl_label_object_draw_handles_line (glLabelObject *object,
1695 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1698 draw_handle (cr, object, w, h);
1701 draw_handle (cr, object, 0, 0);
1705 /*****************************************************************************/
1706 /* Get handle at given coordinates, if any. */
1707 /*****************************************************************************/
1709 gl_label_object_handle_at (glLabelObject *object,
1714 glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
1716 cairo_matrix_t matrix;
1719 gl_debug (DEBUG_LABEL, "START");
1721 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
1723 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1726 gl_label_object_get_position (object, &x0, &y0);
1727 gl_label_object_get_matrix (object, &matrix);
1731 cairo_translate (cr, x0, y0);
1732 cairo_transform (cr, &matrix);
1736 cairo_device_to_user (cr, &x, &y);
1738 handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
1743 gl_debug (DEBUG_LABEL, "END");
1749 /*****************************************************************************/
1750 /* Get handle at given coordinates for box style handles, if any. */
1751 /*****************************************************************************/
1753 gl_label_object_box_handle_at (glLabelObject *object,
1760 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1763 create_handle_path (cr, object, w, h);
1764 if (cairo_in_fill (cr, x, y))
1766 return GL_LABEL_OBJECT_HANDLE_SE;
1770 create_handle_path (cr, object, 0, h);
1771 if (cairo_in_fill (cr, x, y))
1773 return GL_LABEL_OBJECT_HANDLE_SW;
1777 create_handle_path (cr, object, w, 0);
1778 if (cairo_in_fill (cr, x, y))
1780 return GL_LABEL_OBJECT_HANDLE_NE;
1784 create_handle_path (cr, object, 0, 0);
1785 if (cairo_in_fill (cr, x, y))
1787 return GL_LABEL_OBJECT_HANDLE_NW;
1791 create_handle_path (cr, object, w, h/2);
1792 if (cairo_in_fill (cr, x, y))
1794 return GL_LABEL_OBJECT_HANDLE_E;
1798 create_handle_path (cr, object, w/2, h);
1799 if (cairo_in_fill (cr, x, y))
1801 return GL_LABEL_OBJECT_HANDLE_S;
1805 create_handle_path (cr, object, 0, h/2);
1806 if (cairo_in_fill (cr, x, y))
1808 return GL_LABEL_OBJECT_HANDLE_W;
1812 create_handle_path (cr, object, w/2, 0);
1813 if (cairo_in_fill (cr, x, y))
1815 return GL_LABEL_OBJECT_HANDLE_N;
1818 return GL_LABEL_OBJECT_HANDLE_NONE;
1822 /*****************************************************************************/
1823 /* Get handle at given coordinates for line style handles, if any. */
1824 /*****************************************************************************/
1826 gl_label_object_line_handle_at (glLabelObject *object,
1833 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1836 create_handle_path (cr, object, w, h);
1837 if (cairo_in_fill (cr, x, y))
1839 return GL_LABEL_OBJECT_HANDLE_P2;
1843 create_handle_path (cr, object, 0, h);
1844 if (cairo_in_fill (cr, x, y))
1846 return GL_LABEL_OBJECT_HANDLE_P1;
1849 return GL_LABEL_OBJECT_HANDLE_NONE;
1856 * Local Variables: -- emacs
1858 * c-basic-offset: 8 -- emacs
1859 * tab-width: 8 -- emacs
1860 * indent-tabs-mode: nil -- emacs