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;
81 /*========================================================*/
82 /* Private globals. */
83 /*========================================================*/
85 static guint instance = 0;
87 static guint signals[LAST_SIGNAL] = {0};
90 /*========================================================*/
91 /* Private function prototypes. */
92 /*========================================================*/
94 static void gl_label_object_finalize (GObject *object);
96 static void set_size (glLabelObject *object,
102 /*****************************************************************************/
103 /* Boilerplate object stuff. */
104 /*****************************************************************************/
105 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT)
109 gl_label_object_class_init (glLabelObjectClass *class)
111 GObjectClass *object_class = G_OBJECT_CLASS (class);
113 gl_debug (DEBUG_LABEL, "START");
115 gl_label_object_parent_class = g_type_class_peek_parent (class);
117 object_class->finalize = gl_label_object_finalize;
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 */
124 g_signal_new ("changed",
125 G_OBJECT_CLASS_TYPE (object_class),
127 G_STRUCT_OFFSET (glLabelObjectClass, changed),
129 gl_marshal_VOID__VOID,
134 g_signal_new ("moved",
135 G_OBJECT_CLASS_TYPE (object_class),
137 G_STRUCT_OFFSET (glLabelObjectClass, moved),
139 gl_marshal_VOID__VOID,
143 gl_debug (DEBUG_LABEL, "END");
148 gl_label_object_init (glLabelObject *object)
150 gl_debug (DEBUG_LABEL, "START");
152 object->priv = g_new0 (glLabelObjectPrivate, 1);
154 object->priv->name = g_strdup_printf ("object%d", instance++);
156 cairo_matrix_init_identity (&object->priv->matrix);
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;
165 gl_debug (DEBUG_LABEL, "END");
170 gl_label_object_finalize (GObject *object)
172 glLabelObject *label_object = GL_LABEL_OBJECT (object);
174 gl_debug (DEBUG_LABEL, "START");
176 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
178 g_free (label_object->priv->name);
179 g_free (label_object->priv);
181 G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
183 gl_debug (DEBUG_LABEL, "END");
187 /*****************************************************************************/
188 /* New label object. */
189 /*****************************************************************************/
191 gl_label_object_new (glLabel *label)
193 glLabelObject *object;
195 gl_debug (DEBUG_LABEL, "START");
197 object = g_object_new (gl_label_object_get_type(), NULL);
199 gl_label_object_set_parent (object, label);
201 gl_debug (DEBUG_LABEL, "END");
203 return G_OBJECT (object);
207 /*****************************************************************************/
208 /* Duplicate object. */
209 /*****************************************************************************/
211 gl_label_object_dup (glLabelObject *src_object,
214 glLabelObject *dst_object;
216 cairo_matrix_t matrix;
217 gboolean shadow_state;
218 gdouble shadow_x, shadow_y;
219 glColorNode *shadow_color_node;
220 gdouble shadow_opacity;
222 gl_debug (DEBUG_LABEL, "START");
224 g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
226 dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
228 gl_label_object_set_parent (dst_object, label);
229 dst_object->priv->selected_flag = src_object->priv->selected_flag;
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);
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);
247 gl_color_node_free (&shadow_color_node);
249 if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL )
251 /* We have an object specific method, use it */
252 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
255 gl_debug (DEBUG_LABEL, "END");
261 /*****************************************************************************/
262 /* Emit "changed" signal (for derived objects). */
263 /*****************************************************************************/
265 gl_label_object_emit_changed (glLabelObject *object)
267 gl_debug (DEBUG_LABEL, "START");
269 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
271 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
273 gl_debug (DEBUG_LABEL, "END");
277 /*****************************************************************************/
278 /* Set parent label of object. */
279 /*****************************************************************************/
281 gl_label_object_set_parent (glLabelObject *object,
284 gl_debug (DEBUG_LABEL, "START");
286 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
287 g_return_if_fail (label && GL_IS_LABEL (label));
289 object->priv->parent = label;
293 /*****************************************************************************/
294 /* Get parent label of object. */
295 /*****************************************************************************/
297 gl_label_object_get_parent (glLabelObject *object)
299 gl_debug (DEBUG_LABEL, "START");
301 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
303 gl_debug (DEBUG_LABEL, "END");
305 return object->priv->parent;
309 /*****************************************************************************/
311 /*****************************************************************************/
313 gl_label_object_select (glLabelObject *object)
315 object->priv->selected_flag = TRUE;
319 /*****************************************************************************/
320 /* Unselect object. */
321 /*****************************************************************************/
323 gl_label_object_unselect (glLabelObject *object)
325 object->priv->selected_flag = FALSE;
329 /*****************************************************************************/
330 /* Is object selected? */
331 /*****************************************************************************/
333 gl_label_object_is_selected (glLabelObject *object)
335 return object->priv->selected_flag;
339 /*****************************************************************************/
340 /* Set name of object. */
341 /*****************************************************************************/
343 gl_label_object_set_name (glLabelObject *object,
346 gl_debug (DEBUG_LABEL, "START");
348 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
350 g_free(object->priv->name);
351 object->priv->name = name;
353 gl_label_object_emit_changed (object);
355 gl_debug (DEBUG_LABEL, "END");
359 /*****************************************************************************/
360 /* Get name of object. */
361 /*****************************************************************************/
363 gl_label_object_get_name (glLabelObject *object)
365 gl_debug (DEBUG_LABEL, "START");
367 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
369 gl_debug (DEBUG_LABEL, "END");
371 return g_strdup(object->priv->name);
375 /*****************************************************************************/
376 /* Set position of object. */
377 /*****************************************************************************/
379 gl_label_object_set_position (glLabelObject *object,
386 gl_debug (DEBUG_LABEL, "START");
388 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
390 if ( (x != object->priv->x) || (y != object->priv->y) )
394 gl_label_checkpoint (object->priv->parent, _("Move"));
397 dx = x - object->priv->x;
398 dy = y - object->priv->y;
403 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
407 gl_debug (DEBUG_LABEL, "END");
411 /*****************************************************************************/
412 /* Set position of object relative to old position. */
413 /*****************************************************************************/
415 gl_label_object_set_position_relative (glLabelObject *object,
420 gl_debug (DEBUG_LABEL, "START");
422 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
424 if ( (dx != 0.0) || (dy != 0.0) )
428 gl_label_checkpoint (object->priv->parent, _("Move"));
431 object->priv->x += dx;
432 object->priv->y += dy;
434 gl_debug (DEBUG_LABEL, " x = %f, y= %f",
438 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
441 gl_debug (DEBUG_LABEL, "END");
445 /*****************************************************************************/
446 /* Get position of object. */
447 /*****************************************************************************/
449 gl_label_object_get_position (glLabelObject *object,
453 gl_debug (DEBUG_LABEL, "START");
455 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
457 *x = object->priv->x;
458 *y = object->priv->y;
460 gl_debug (DEBUG_LABEL, "END");
464 /*---------------------------------------------------------------------------*/
465 /* PRIVATE. Default set size method. */
466 /*---------------------------------------------------------------------------*/
468 set_size (glLabelObject *object,
473 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
475 if ( (object->priv->w != w) || (object->priv->h != h) )
479 gl_label_checkpoint (object->priv->parent, _("Resize"));
485 gl_label_object_emit_changed (object);
490 /*****************************************************************************/
491 /* Set size of object. */
492 /*****************************************************************************/
494 gl_label_object_set_size (glLabelObject *object,
499 gl_debug (DEBUG_LABEL, "START");
501 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
503 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
505 /* We have an object specific method, use it */
506 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
508 object->priv->aspect_ratio = h / w;
511 gl_debug (DEBUG_LABEL, "END");
515 /*****************************************************************************/
516 /* Set raw size of object. */
517 /*****************************************************************************/
519 gl_label_object_set_raw_size (glLabelObject *object,
524 gl_debug (DEBUG_LABEL, "START");
526 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
528 set_size (object, w, h, checkpoint);
529 object->priv->aspect_ratio = h / w;
531 gl_debug (DEBUG_LABEL, "END");
535 /*****************************************************************************/
536 /* Set size of object honoring current aspect ratio. */
537 /*****************************************************************************/
539 gl_label_object_set_size_honor_aspect (glLabelObject *object,
544 gl_debug (DEBUG_LABEL, "START");
546 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
548 if ( h > w*object->priv->aspect_ratio )
550 h = w * object->priv->aspect_ratio;
554 w = h / object->priv->aspect_ratio;
557 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
559 /* We have an object specific method, use it */
560 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
563 gl_debug (DEBUG_LABEL, "END");
567 /*****************************************************************************/
568 /* Get raw size method (don't let object content adjust size). */
569 /*****************************************************************************/
571 gl_label_object_get_raw_size (glLabelObject *object,
575 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
577 *w = object->priv->w;
578 *h = object->priv->h;
582 /*****************************************************************************/
583 /* Get size of object. */
584 /*****************************************************************************/
586 gl_label_object_get_size (glLabelObject *object,
590 gl_debug (DEBUG_LABEL, "START");
592 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
594 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
596 /* We have an object specific method, use it */
597 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
601 gl_label_object_get_raw_size (object, w, h);
604 gl_debug (DEBUG_LABEL, "END");
608 /*****************************************************************************/
609 /* Get extent of object. */
610 /*****************************************************************************/
612 gl_label_object_get_extent (glLabelObject *object,
613 glLabelRegion *region)
617 gdouble xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
618 cairo_matrix_t matrix;
620 gl_debug (DEBUG_LABEL, "START");
622 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
624 gl_label_object_get_size (object, &w, &h);
625 line_w = gl_label_object_get_line_width (object);
627 /* setup untransformed corners of bounding box, account for line width */
637 /* transform these points */
638 gl_label_object_get_matrix (object, &matrix);
639 cairo_matrix_transform_point (&matrix, &xa1, &ya1);
640 cairo_matrix_transform_point (&matrix, &xa2, &ya2);
641 cairo_matrix_transform_point (&matrix, &xa3, &ya3);
642 cairo_matrix_transform_point (&matrix, &xa4, &ya4);
644 /* now find the maximum extent of these points in x and y */
645 region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
646 region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
647 region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
648 region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
650 gl_debug (DEBUG_LABEL, "END");
654 /*****************************************************************************/
655 /* Can text properties be set for this object? */
656 /*****************************************************************************/
658 gl_label_object_can_text (glLabelObject *object)
660 gl_debug (DEBUG_LABEL, "");
662 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
664 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
675 /*****************************************************************************/
676 /* Set font family for all text contained in object. */
677 /*****************************************************************************/
679 gl_label_object_set_font_family (glLabelObject *object,
680 const gchar *font_family,
683 gl_debug (DEBUG_LABEL, "START");
685 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
687 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
689 /* We have an object specific method, use it */
690 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family, checkpoint);
693 gl_debug (DEBUG_LABEL, "END");
697 /****************************************************************************/
698 /* Set font size for all text contained in object. */
699 /****************************************************************************/
701 gl_label_object_set_font_size (glLabelObject *object,
705 gl_debug (DEBUG_LABEL, "START");
707 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
709 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
711 /* We have an object specific method, use it */
712 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size, checkpoint);
715 gl_debug (DEBUG_LABEL, "END");
719 /****************************************************************************/
720 /* Set font weight for all text contained in object. */
721 /****************************************************************************/
723 gl_label_object_set_font_weight (glLabelObject *object,
724 PangoWeight font_weight,
727 gl_debug (DEBUG_LABEL, "START");
729 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
731 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL )
733 /* We have an object specific method, use it */
734 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight, checkpoint);
737 gl_debug (DEBUG_LABEL, "END");
741 /****************************************************************************/
742 /* Set font italic flag for all text contained in object. */
743 /****************************************************************************/
745 gl_label_object_set_font_italic_flag (glLabelObject *object,
746 gboolean font_italic_flag,
749 gl_debug (DEBUG_LABEL, "START");
751 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
753 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
755 /* We have an object specific method, use it */
756 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag, checkpoint);
759 gl_debug (DEBUG_LABEL, "END");
763 /****************************************************************************/
764 /* Set text alignment for all text contained in object. */
765 /****************************************************************************/
767 gl_label_object_set_text_alignment (glLabelObject *object,
768 PangoAlignment text_alignment,
771 gl_debug (DEBUG_LABEL, "START");
773 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
775 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
777 /* We have an object specific method, use it */
778 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment, checkpoint);
781 gl_debug (DEBUG_LABEL, "END");
785 /****************************************************************************/
786 /* Set vertical text alignment for all text contained in object. */
787 /****************************************************************************/
789 gl_label_object_set_text_valignment (glLabelObject *object,
790 glValignment text_valignment,
793 gl_debug (DEBUG_LABEL, "START");
795 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
797 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment != NULL )
799 /* We have an object specific method, use it */
800 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment (object, text_valignment, checkpoint);
803 gl_debug (DEBUG_LABEL, "END");
807 /****************************************************************************/
808 /* Set text line spacing for all text contained in object. */
809 /****************************************************************************/
811 gl_label_object_set_text_line_spacing (glLabelObject *object,
812 gdouble text_line_spacing,
815 gl_debug (DEBUG_LABEL, "START");
817 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
819 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
821 /* We have an object specific method, use it */
822 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing, checkpoint);
825 gl_debug (DEBUG_LABEL, "END");
829 /****************************************************************************/
830 /* Set text color for all text contained in object. */
831 /****************************************************************************/
833 gl_label_object_set_text_color (glLabelObject *object,
834 glColorNode *text_color_node,
837 gl_debug (DEBUG_LABEL, "START");
839 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
841 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
843 /* We have an object specific method, use it */
844 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node, checkpoint);
847 gl_debug (DEBUG_LABEL, "END");
851 /*****************************************************************************/
852 /* Get font family for all text contained in object. */
853 /*****************************************************************************/
855 gl_label_object_get_font_family (glLabelObject *object)
859 gl_debug (DEBUG_LABEL, "START");
861 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
863 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
865 /* We have an object specific method, use it */
866 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
869 gl_debug (DEBUG_LABEL, "END");
875 /****************************************************************************/
876 /* Get font size for all text contained in object. */
877 /****************************************************************************/
879 gl_label_object_get_font_size (glLabelObject *object)
883 gl_debug (DEBUG_LABEL, "START");
885 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
887 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
889 /* We have an object specific method, use it */
890 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
893 gl_debug (DEBUG_LABEL, "END");
899 /****************************************************************************/
900 /* Get font weight for all text contained in object. */
901 /****************************************************************************/
903 gl_label_object_get_font_weight (glLabelObject *object)
905 PangoWeight ret = PANGO_WEIGHT_NORMAL;
907 gl_debug (DEBUG_LABEL, "START");
909 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
911 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
913 /* We have an object specific method, use it */
914 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
917 gl_debug (DEBUG_LABEL, "END");
923 /****************************************************************************/
924 /* Get font italic flag for all text contained in object. */
925 /****************************************************************************/
927 gl_label_object_get_font_italic_flag (glLabelObject *object)
929 gboolean ret = FALSE;
931 gl_debug (DEBUG_LABEL, "START");
933 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
935 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
937 /* We have an object specific method, use it */
938 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
941 gl_debug (DEBUG_LABEL, "END");
947 /****************************************************************************/
948 /* Get text alignment for all text contained in object. */
949 /****************************************************************************/
951 gl_label_object_get_text_alignment (glLabelObject *object)
953 PangoAlignment ret = PANGO_ALIGN_LEFT;
955 gl_debug (DEBUG_LABEL, "START");
957 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
959 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
961 /* We have an object specific method, use it */
962 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
965 gl_debug (DEBUG_LABEL, "END");
971 /****************************************************************************/
972 /* Get text alignment for all text contained in object. */
973 /****************************************************************************/
975 gl_label_object_get_text_valignment (glLabelObject *object)
977 glValignment ret = GL_VALIGN_TOP;
979 gl_debug (DEBUG_LABEL, "START");
981 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), GL_VALIGN_TOP);
983 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment != NULL )
985 /* We have an object specific method, use it */
986 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment (object);
989 gl_debug (DEBUG_LABEL, "END");
995 /****************************************************************************/
996 /* Get text line spacing for all text contained in object. */
997 /****************************************************************************/
999 gl_label_object_get_text_line_spacing (glLabelObject *object)
1003 gl_debug (DEBUG_LABEL, "START");
1005 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1007 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
1009 /* We have an object specific method, use it */
1010 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
1013 gl_debug (DEBUG_LABEL, "END");
1019 /****************************************************************************/
1020 /* Get text color for all text contained in object. */
1021 /****************************************************************************/
1023 gl_label_object_get_text_color (glLabelObject *object)
1025 glColorNode *ret = NULL;
1027 gl_debug (DEBUG_LABEL, "START");
1029 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1031 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
1033 /* We have an object specific method, use it */
1034 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
1037 gl_debug (DEBUG_LABEL, "END");
1043 /*****************************************************************************/
1044 /* Can fill properties be set for this object? */
1045 /*****************************************************************************/
1047 gl_label_object_can_fill (glLabelObject *object)
1049 gl_debug (DEBUG_LABEL, "");
1051 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1053 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1065 /****************************************************************************/
1066 /* Set fill color for object. */
1067 /****************************************************************************/
1069 gl_label_object_set_fill_color (glLabelObject *object,
1070 glColorNode *fill_color_node,
1071 gboolean checkpoint)
1073 gl_debug (DEBUG_LABEL, "START");
1075 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1077 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1079 /* We have an object specific method, use it */
1080 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node, checkpoint);
1083 gl_debug (DEBUG_LABEL, "END");
1087 /****************************************************************************/
1088 /* Get fill color for object. */
1089 /****************************************************************************/
1091 gl_label_object_get_fill_color (glLabelObject *object)
1093 glColorNode *ret = NULL;
1095 gl_debug (DEBUG_LABEL, "START");
1097 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1099 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
1101 /* We have an object specific method, use it */
1102 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1105 gl_debug (DEBUG_LABEL, "END");
1111 /*****************************************************************************/
1112 /* Can line color property be set for this object? */
1113 /*****************************************************************************/
1115 gl_label_object_can_line_color (glLabelObject *object)
1117 gl_debug (DEBUG_LABEL, "");
1119 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1121 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1133 /****************************************************************************/
1134 /* Set line color for object. */
1135 /****************************************************************************/
1137 gl_label_object_set_line_color (glLabelObject *object,
1138 glColorNode *line_color_node,
1139 gboolean checkpoint)
1141 gl_debug (DEBUG_LABEL, "START");
1143 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1145 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1147 /* We have an object specific method, use it */
1148 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node, checkpoint);
1151 gl_debug (DEBUG_LABEL, "END");
1155 /****************************************************************************/
1156 /* Get line color for object. */
1157 /****************************************************************************/
1159 gl_label_object_get_line_color (glLabelObject *object)
1161 glColorNode *ret = NULL;
1163 gl_debug (DEBUG_LABEL, "START");
1165 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1167 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
1169 /* We have an object specific method, use it */
1170 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1173 gl_debug (DEBUG_LABEL, "END");
1179 /*****************************************************************************/
1180 /* Can line width property be set for this object? */
1181 /*****************************************************************************/
1183 gl_label_object_can_line_width (glLabelObject *object)
1185 gl_debug (DEBUG_LABEL, "");
1187 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1189 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1201 /****************************************************************************/
1202 /* Set line width for object. */
1203 /****************************************************************************/
1205 gl_label_object_set_line_width (glLabelObject *object,
1207 gboolean checkpoint)
1209 gl_debug (DEBUG_LABEL, "START");
1211 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1213 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1215 /* We have an object specific method, use it */
1216 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width, checkpoint);
1219 gl_debug (DEBUG_LABEL, "END");
1223 /****************************************************************************/
1224 /* Get line width for object. */
1225 /****************************************************************************/
1227 gl_label_object_get_line_width (glLabelObject *object)
1231 gl_debug (DEBUG_LABEL, "START");
1233 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1235 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
1237 /* We have an object specific method, use it */
1238 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1241 gl_debug (DEBUG_LABEL, "END");
1247 /****************************************************************************/
1248 /* Set shadow state of object. */
1249 /****************************************************************************/
1251 gl_label_object_set_shadow_state (glLabelObject *object,
1253 gboolean checkpoint)
1255 gl_debug (DEBUG_LABEL, "START");
1257 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1259 if (object->priv->shadow_state != state)
1263 gl_label_checkpoint (object->priv->parent, _("Shadow state"));
1266 object->priv->shadow_state = state;
1268 gl_label_object_emit_changed (object);
1271 gl_debug (DEBUG_LABEL, "END");
1275 /****************************************************************************/
1276 /* Get shadow state of object. */
1277 /****************************************************************************/
1279 gl_label_object_get_shadow_state (glLabelObject *object)
1281 gl_debug (DEBUG_LABEL, "");
1283 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1285 return object->priv->shadow_state;
1289 /****************************************************************************/
1290 /* Set offset of object's shadow. */
1291 /****************************************************************************/
1293 gl_label_object_set_shadow_offset (glLabelObject *object,
1296 gboolean checkpoint)
1298 gl_debug (DEBUG_LABEL, "START");
1300 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1302 if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1306 gl_label_checkpoint (object->priv->parent, _("Shadow offset"));
1309 object->priv->shadow_x = x;
1310 object->priv->shadow_y = y;
1312 gl_label_object_emit_changed (object);
1315 gl_debug (DEBUG_LABEL, "END");
1319 /****************************************************************************/
1320 /* Get offset of object's shadow. */
1321 /****************************************************************************/
1323 gl_label_object_get_shadow_offset (glLabelObject *object,
1327 gl_debug (DEBUG_LABEL, "START");
1329 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1331 *x = object->priv->shadow_x;
1332 *y = object->priv->shadow_y;
1334 gl_debug (DEBUG_LABEL, "END");
1338 /****************************************************************************/
1339 /* Set color of object's shadow. */
1340 /****************************************************************************/
1342 gl_label_object_set_shadow_color (glLabelObject *object,
1343 glColorNode *color_node,
1344 gboolean checkpoint)
1346 gl_debug (DEBUG_LABEL, "START");
1348 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1350 if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1354 gl_label_checkpoint (object->priv->parent, _("Shadow color"));
1357 gl_color_node_free (&(object->priv->shadow_color_node));
1358 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1360 gl_label_object_emit_changed (object);
1363 gl_debug (DEBUG_LABEL, "END");
1367 /****************************************************************************/
1368 /* Get color of object's shadow. */
1369 /****************************************************************************/
1371 gl_label_object_get_shadow_color (glLabelObject *object)
1373 gl_debug (DEBUG_LABEL, "");
1375 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1377 return gl_color_node_dup (object->priv->shadow_color_node);
1381 /****************************************************************************/
1382 /* Set opacity of object's shadow. */
1383 /****************************************************************************/
1385 gl_label_object_set_shadow_opacity (glLabelObject *object,
1387 gboolean checkpoint)
1389 gl_debug (DEBUG_LABEL, "START");
1391 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1393 if (object->priv->shadow_opacity != alpha)
1397 gl_label_checkpoint (object->priv->parent, _("Shadow opacity"));
1400 object->priv->shadow_opacity = alpha;
1402 gl_label_object_emit_changed (object);
1405 gl_debug (DEBUG_LABEL, "END");
1409 /****************************************************************************/
1410 /* Get opacity of object's shadow. */
1411 /****************************************************************************/
1413 gl_label_object_get_shadow_opacity (glLabelObject *object)
1415 gl_debug (DEBUG_LABEL, "");
1417 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1419 return object->priv->shadow_opacity;
1423 /****************************************************************************/
1424 /* Flip object horizontally. */
1425 /****************************************************************************/
1427 gl_label_object_flip_horiz (glLabelObject *object)
1429 cairo_matrix_t flip_matrix;
1431 gl_debug (DEBUG_LABEL, "START");
1433 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1435 cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1436 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1438 gl_debug (DEBUG_LABEL, "END");
1442 /****************************************************************************/
1443 /* Flip object vertically. */
1444 /****************************************************************************/
1446 gl_label_object_flip_vert (glLabelObject *object)
1448 cairo_matrix_t flip_matrix;
1450 gl_debug (DEBUG_LABEL, "START");
1452 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1454 cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1455 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1457 gl_debug (DEBUG_LABEL, "END");
1461 /****************************************************************************/
1462 /* Rotate object. */
1463 /****************************************************************************/
1465 gl_label_object_rotate (glLabelObject *object,
1468 cairo_matrix_t rotate_matrix;
1470 gl_debug (DEBUG_LABEL, "START");
1472 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1474 cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1475 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1477 gl_debug (DEBUG_LABEL, "END");
1481 /****************************************************************************/
1482 /* Set raw affine */
1483 /****************************************************************************/
1485 gl_label_object_set_matrix (glLabelObject *object,
1486 cairo_matrix_t *matrix)
1488 gl_debug (DEBUG_LABEL, "");
1490 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1492 object->priv->matrix = *matrix;
1496 /****************************************************************************/
1497 /* Get raw affine */
1498 /****************************************************************************/
1500 gl_label_object_get_matrix (glLabelObject *object,
1501 cairo_matrix_t *matrix)
1503 gl_debug (DEBUG_LABEL, "");
1505 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1507 *matrix = object->priv->matrix;
1511 /*****************************************************************************/
1513 /*****************************************************************************/
1515 gl_label_object_draw (glLabelObject *object,
1517 gboolean screen_flag,
1518 glMergeRecord *record)
1522 cairo_matrix_t matrix;
1523 gboolean shadow_state;
1524 gdouble shadow_x, shadow_y;
1526 gl_debug (DEBUG_LABEL, "START");
1528 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1530 gl_label_object_get_position (object, &x0, &y0);
1531 gl_label_object_get_matrix (object, &matrix);
1534 cairo_translate (cr, x0, y0);
1536 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
1538 shadow_state = gl_label_object_get_shadow_state (object);
1542 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1545 cairo_translate (cr, shadow_x, shadow_y);
1546 cairo_transform (cr, &matrix);
1548 GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1557 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1560 cairo_transform (cr, &matrix);
1562 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1572 gl_debug (DEBUG_LABEL, "END");
1576 /*****************************************************************************/
1577 /* Is object located at coordinates. */
1578 /*****************************************************************************/
1580 gl_label_object_is_located_at (glLabelObject *object,
1585 gboolean ret_val = FALSE;
1587 cairo_matrix_t matrix;
1590 gl_debug (DEBUG_LABEL, "START");
1592 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1594 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1597 gl_label_object_get_position (object, &x0, &y0);
1598 gl_label_object_get_matrix (object, &matrix);
1602 cairo_translate (cr, x0, y0);
1603 cairo_transform (cr, &matrix);
1607 cairo_device_to_user (cr, &x, &y);
1609 ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
1614 gl_debug (DEBUG_LABEL, "END");
1620 /*****************************************************************************/
1621 /* Draw object handles */
1622 /*****************************************************************************/
1624 gl_label_object_draw_handles (glLabelObject *object,
1628 cairo_matrix_t matrix;
1630 gl_debug (DEBUG_LABEL, "START");
1632 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1634 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1637 gl_label_object_get_position (object, &x0, &y0);
1638 gl_label_object_get_matrix (object, &matrix);
1642 cairo_translate (cr, x0, y0);
1643 cairo_transform (cr, &matrix);
1645 GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
1650 gl_debug (DEBUG_LABEL, "END");
1654 /*--------------------------------------------------------------------------*/
1655 /* Draw individual handle */
1656 /*--------------------------------------------------------------------------*/
1658 draw_handle (cairo_t *cr,
1659 glLabelObject *object,
1663 gdouble scale_x, scale_y;
1666 gl_debug (DEBUG_VIEW, "START");
1670 cairo_translate (cr, x_handle, y_handle);
1674 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1675 cairo_scale (cr, scale_x, scale_y);
1677 cairo_rectangle (cr,
1678 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1679 HANDLE_PIXELS, HANDLE_PIXELS);
1681 cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
1682 cairo_fill_preserve (cr);
1684 cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
1685 cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
1690 gl_debug (DEBUG_VIEW, "END");
1694 /*--------------------------------------------------------------------------*/
1695 /* Create handle path */
1696 /*--------------------------------------------------------------------------*/
1698 create_handle_path (cairo_t *cr,
1699 glLabelObject *object,
1703 gdouble scale_x, scale_y;
1706 gl_debug (DEBUG_VIEW, "START");
1710 cairo_translate (cr, x_handle, y_handle);
1714 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1715 cairo_scale (cr, scale_x, scale_y);
1717 cairo_rectangle (cr,
1718 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1719 HANDLE_PIXELS, HANDLE_PIXELS);
1723 gl_debug (DEBUG_VIEW, "END");
1727 /*****************************************************************************/
1728 /* Draw box style handles. */
1729 /*****************************************************************************/
1731 gl_label_object_draw_handles_box (glLabelObject *object,
1736 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1739 draw_handle (cr, object, w/2, 0);
1742 draw_handle (cr, object, w, 0);
1745 draw_handle (cr, object, w, h/2);
1748 draw_handle (cr, object, w, h);
1751 draw_handle (cr, object, w/2, h);
1754 draw_handle (cr, object, 0, h);
1757 draw_handle (cr, object, 0, h/2);
1760 draw_handle (cr, object, 0, 0);
1764 /*****************************************************************************/
1765 /* Draw line style handles. */
1766 /*****************************************************************************/
1768 gl_label_object_draw_handles_line (glLabelObject *object,
1773 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1776 draw_handle (cr, object, w, h);
1779 draw_handle (cr, object, 0, 0);
1783 /*****************************************************************************/
1784 /* Get handle at given coordinates, if any. */
1785 /*****************************************************************************/
1787 gl_label_object_handle_at (glLabelObject *object,
1792 glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
1794 cairo_matrix_t matrix;
1797 gl_debug (DEBUG_LABEL, "START");
1799 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
1801 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1804 gl_label_object_get_position (object, &x0, &y0);
1805 gl_label_object_get_matrix (object, &matrix);
1809 cairo_translate (cr, x0, y0);
1810 cairo_transform (cr, &matrix);
1814 cairo_device_to_user (cr, &x, &y);
1816 handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
1821 gl_debug (DEBUG_LABEL, "END");
1827 /*****************************************************************************/
1828 /* Get handle at given coordinates for box style handles, if any. */
1829 /*****************************************************************************/
1831 gl_label_object_box_handle_at (glLabelObject *object,
1838 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1841 create_handle_path (cr, object, w, h);
1842 if (cairo_in_fill (cr, x, y))
1844 return GL_LABEL_OBJECT_HANDLE_SE;
1848 create_handle_path (cr, object, 0, h);
1849 if (cairo_in_fill (cr, x, y))
1851 return GL_LABEL_OBJECT_HANDLE_SW;
1855 create_handle_path (cr, object, w, 0);
1856 if (cairo_in_fill (cr, x, y))
1858 return GL_LABEL_OBJECT_HANDLE_NE;
1862 create_handle_path (cr, object, 0, 0);
1863 if (cairo_in_fill (cr, x, y))
1865 return GL_LABEL_OBJECT_HANDLE_NW;
1869 create_handle_path (cr, object, w, h/2);
1870 if (cairo_in_fill (cr, x, y))
1872 return GL_LABEL_OBJECT_HANDLE_E;
1876 create_handle_path (cr, object, w/2, h);
1877 if (cairo_in_fill (cr, x, y))
1879 return GL_LABEL_OBJECT_HANDLE_S;
1883 create_handle_path (cr, object, 0, h/2);
1884 if (cairo_in_fill (cr, x, y))
1886 return GL_LABEL_OBJECT_HANDLE_W;
1890 create_handle_path (cr, object, w/2, 0);
1891 if (cairo_in_fill (cr, x, y))
1893 return GL_LABEL_OBJECT_HANDLE_N;
1896 return GL_LABEL_OBJECT_HANDLE_NONE;
1900 /*****************************************************************************/
1901 /* Get handle at given coordinates for line style handles, if any. */
1902 /*****************************************************************************/
1904 gl_label_object_line_handle_at (glLabelObject *object,
1911 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1914 create_handle_path (cr, object, w, h);
1915 if (cairo_in_fill (cr, x, y))
1917 return GL_LABEL_OBJECT_HANDLE_P2;
1921 create_handle_path (cr, object, 0, h);
1922 if (cairo_in_fill (cr, x, y))
1924 return GL_LABEL_OBJECT_HANDLE_P1;
1927 return GL_LABEL_OBJECT_HANDLE_NONE;
1934 * Local Variables: -- emacs
1936 * c-basic-offset: 8 -- emacs
1937 * tab-width: 8 -- emacs
1938 * indent-tabs-mode: nil -- emacs