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,
384 gl_debug (DEBUG_LABEL, "START");
386 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
388 if ( (x != object->priv->x) || (y != object->priv->y) )
392 gl_label_checkpoint (object->priv->parent, _("Move"));
398 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
402 gl_debug (DEBUG_LABEL, "END");
406 /*****************************************************************************/
407 /* Set position of object relative to old position. */
408 /*****************************************************************************/
410 gl_label_object_set_position_relative (glLabelObject *object,
415 gl_debug (DEBUG_LABEL, "START");
417 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
419 if ( (dx != 0.0) || (dy != 0.0) )
423 gl_label_checkpoint (object->priv->parent, _("Move"));
426 object->priv->x += dx;
427 object->priv->y += dy;
429 gl_debug (DEBUG_LABEL, " x = %f, y= %f",
433 g_signal_emit (G_OBJECT(object), signals[MOVED], 0);
436 gl_debug (DEBUG_LABEL, "END");
440 /*****************************************************************************/
441 /* Get position of object. */
442 /*****************************************************************************/
444 gl_label_object_get_position (glLabelObject *object,
448 gl_debug (DEBUG_LABEL, "START");
450 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
452 *x = object->priv->x;
453 *y = object->priv->y;
455 gl_debug (DEBUG_LABEL, "END");
459 /*---------------------------------------------------------------------------*/
460 /* PRIVATE. Default set size method. */
461 /*---------------------------------------------------------------------------*/
463 set_size (glLabelObject *object,
468 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
470 if ( (object->priv->w != w) || (object->priv->h != h) )
474 gl_label_checkpoint (object->priv->parent, _("Resize"));
480 gl_label_object_emit_changed (object);
485 /*****************************************************************************/
486 /* Set size of object. */
487 /*****************************************************************************/
489 gl_label_object_set_size (glLabelObject *object,
494 gl_debug (DEBUG_LABEL, "START");
496 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
498 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
500 /* We have an object specific method, use it */
501 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
503 object->priv->aspect_ratio = h / w;
506 gl_debug (DEBUG_LABEL, "END");
510 /*****************************************************************************/
511 /* Set raw size of object. */
512 /*****************************************************************************/
514 gl_label_object_set_raw_size (glLabelObject *object,
519 gl_debug (DEBUG_LABEL, "START");
521 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
523 set_size (object, w, h, checkpoint);
524 object->priv->aspect_ratio = h / w;
526 gl_debug (DEBUG_LABEL, "END");
530 /*****************************************************************************/
531 /* Set size of object honoring current aspect ratio. */
532 /*****************************************************************************/
534 gl_label_object_set_size_honor_aspect (glLabelObject *object,
539 gl_debug (DEBUG_LABEL, "START");
541 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
543 if ( h > w*object->priv->aspect_ratio )
545 h = w * object->priv->aspect_ratio;
549 w = h / object->priv->aspect_ratio;
552 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
554 /* We have an object specific method, use it */
555 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h, checkpoint);
558 gl_debug (DEBUG_LABEL, "END");
562 /*****************************************************************************/
563 /* Get raw size method (don't let object content adjust size). */
564 /*****************************************************************************/
566 gl_label_object_get_raw_size (glLabelObject *object,
570 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
572 *w = object->priv->w;
573 *h = object->priv->h;
577 /*****************************************************************************/
578 /* Get size of object. */
579 /*****************************************************************************/
581 gl_label_object_get_size (glLabelObject *object,
585 gl_debug (DEBUG_LABEL, "START");
587 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
589 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
591 /* We have an object specific method, use it */
592 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
596 gl_label_object_get_raw_size (object, w, h);
599 gl_debug (DEBUG_LABEL, "END");
603 /*****************************************************************************/
604 /* Get extent of object. */
605 /*****************************************************************************/
607 gl_label_object_get_extent (glLabelObject *object,
608 glLabelRegion *region)
612 gdouble xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
613 cairo_matrix_t matrix;
615 gl_debug (DEBUG_LABEL, "START");
617 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
619 gl_label_object_get_size (object, &w, &h);
620 line_w = gl_label_object_get_line_width (object);
622 /* setup untransformed corners of bounding box, account for line width */
632 /* transform these points */
633 gl_label_object_get_matrix (object, &matrix);
634 cairo_matrix_transform_point (&matrix, &xa1, &ya1);
635 cairo_matrix_transform_point (&matrix, &xa2, &ya2);
636 cairo_matrix_transform_point (&matrix, &xa3, &ya3);
637 cairo_matrix_transform_point (&matrix, &xa4, &ya4);
639 /* now find the maximum extent of these points in x and y */
640 region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
641 region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
642 region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
643 region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
645 gl_debug (DEBUG_LABEL, "END");
649 /*****************************************************************************/
650 /* Can text properties be set for this object? */
651 /*****************************************************************************/
653 gl_label_object_can_text (glLabelObject *object)
655 gl_debug (DEBUG_LABEL, "");
657 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
659 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
670 /*****************************************************************************/
671 /* Set font family for all text contained in object. */
672 /*****************************************************************************/
674 gl_label_object_set_font_family (glLabelObject *object,
675 const gchar *font_family,
678 gl_debug (DEBUG_LABEL, "START");
680 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
682 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
684 /* We have an object specific method, use it */
685 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family, checkpoint);
688 gl_debug (DEBUG_LABEL, "END");
692 /****************************************************************************/
693 /* Set font size for all text contained in object. */
694 /****************************************************************************/
696 gl_label_object_set_font_size (glLabelObject *object,
700 gl_debug (DEBUG_LABEL, "START");
702 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
704 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
706 /* We have an object specific method, use it */
707 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size, checkpoint);
710 gl_debug (DEBUG_LABEL, "END");
714 /****************************************************************************/
715 /* Set font weight for all text contained in object. */
716 /****************************************************************************/
718 gl_label_object_set_font_weight (glLabelObject *object,
719 PangoWeight font_weight,
722 gl_debug (DEBUG_LABEL, "START");
724 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
726 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL )
728 /* We have an object specific method, use it */
729 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight, checkpoint);
732 gl_debug (DEBUG_LABEL, "END");
736 /****************************************************************************/
737 /* Set font italic flag for all text contained in object. */
738 /****************************************************************************/
740 gl_label_object_set_font_italic_flag (glLabelObject *object,
741 gboolean font_italic_flag,
744 gl_debug (DEBUG_LABEL, "START");
746 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
748 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
750 /* We have an object specific method, use it */
751 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag, checkpoint);
754 gl_debug (DEBUG_LABEL, "END");
758 /****************************************************************************/
759 /* Set text alignment for all text contained in object. */
760 /****************************************************************************/
762 gl_label_object_set_text_alignment (glLabelObject *object,
763 PangoAlignment text_alignment,
766 gl_debug (DEBUG_LABEL, "START");
768 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
770 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
772 /* We have an object specific method, use it */
773 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment, checkpoint);
776 gl_debug (DEBUG_LABEL, "END");
780 /****************************************************************************/
781 /* Set vertical text alignment for all text contained in object. */
782 /****************************************************************************/
784 gl_label_object_set_text_valignment (glLabelObject *object,
785 glValignment text_valignment,
788 gl_debug (DEBUG_LABEL, "START");
790 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
792 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment != NULL )
794 /* We have an object specific method, use it */
795 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_valignment (object, text_valignment, checkpoint);
798 gl_debug (DEBUG_LABEL, "END");
802 /****************************************************************************/
803 /* Set text line spacing for all text contained in object. */
804 /****************************************************************************/
806 gl_label_object_set_text_line_spacing (glLabelObject *object,
807 gdouble text_line_spacing,
810 gl_debug (DEBUG_LABEL, "START");
812 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
814 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
816 /* We have an object specific method, use it */
817 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing, checkpoint);
820 gl_debug (DEBUG_LABEL, "END");
824 /****************************************************************************/
825 /* Set text color for all text contained in object. */
826 /****************************************************************************/
828 gl_label_object_set_text_color (glLabelObject *object,
829 glColorNode *text_color_node,
832 gl_debug (DEBUG_LABEL, "START");
834 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
836 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
838 /* We have an object specific method, use it */
839 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node, checkpoint);
842 gl_debug (DEBUG_LABEL, "END");
846 /*****************************************************************************/
847 /* Get font family for all text contained in object. */
848 /*****************************************************************************/
850 gl_label_object_get_font_family (glLabelObject *object)
854 gl_debug (DEBUG_LABEL, "START");
856 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
858 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
860 /* We have an object specific method, use it */
861 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
864 gl_debug (DEBUG_LABEL, "END");
870 /****************************************************************************/
871 /* Get font size for all text contained in object. */
872 /****************************************************************************/
874 gl_label_object_get_font_size (glLabelObject *object)
878 gl_debug (DEBUG_LABEL, "START");
880 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
882 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
884 /* We have an object specific method, use it */
885 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
888 gl_debug (DEBUG_LABEL, "END");
894 /****************************************************************************/
895 /* Get font weight for all text contained in object. */
896 /****************************************************************************/
898 gl_label_object_get_font_weight (glLabelObject *object)
900 PangoWeight ret = PANGO_WEIGHT_NORMAL;
902 gl_debug (DEBUG_LABEL, "START");
904 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
906 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
908 /* We have an object specific method, use it */
909 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
912 gl_debug (DEBUG_LABEL, "END");
918 /****************************************************************************/
919 /* Get font italic flag for all text contained in object. */
920 /****************************************************************************/
922 gl_label_object_get_font_italic_flag (glLabelObject *object)
924 gboolean ret = FALSE;
926 gl_debug (DEBUG_LABEL, "START");
928 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
930 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
932 /* We have an object specific method, use it */
933 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
936 gl_debug (DEBUG_LABEL, "END");
942 /****************************************************************************/
943 /* Get text alignment for all text contained in object. */
944 /****************************************************************************/
946 gl_label_object_get_text_alignment (glLabelObject *object)
948 PangoAlignment ret = PANGO_ALIGN_LEFT;
950 gl_debug (DEBUG_LABEL, "START");
952 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
954 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
956 /* We have an object specific method, use it */
957 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
960 gl_debug (DEBUG_LABEL, "END");
966 /****************************************************************************/
967 /* Get text alignment for all text contained in object. */
968 /****************************************************************************/
970 gl_label_object_get_text_valignment (glLabelObject *object)
972 glValignment ret = GL_VALIGN_TOP;
974 gl_debug (DEBUG_LABEL, "START");
976 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), GL_VALIGN_TOP);
978 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment != NULL )
980 /* We have an object specific method, use it */
981 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_valignment (object);
984 gl_debug (DEBUG_LABEL, "END");
990 /****************************************************************************/
991 /* Get text line spacing for all text contained in object. */
992 /****************************************************************************/
994 gl_label_object_get_text_line_spacing (glLabelObject *object)
998 gl_debug (DEBUG_LABEL, "START");
1000 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1002 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
1004 /* We have an object specific method, use it */
1005 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
1008 gl_debug (DEBUG_LABEL, "END");
1014 /****************************************************************************/
1015 /* Get text color for all text contained in object. */
1016 /****************************************************************************/
1018 gl_label_object_get_text_color (glLabelObject *object)
1020 glColorNode *ret = NULL;
1022 gl_debug (DEBUG_LABEL, "START");
1024 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1026 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
1028 /* We have an object specific method, use it */
1029 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
1032 gl_debug (DEBUG_LABEL, "END");
1038 /*****************************************************************************/
1039 /* Can fill properties be set for this object? */
1040 /*****************************************************************************/
1042 gl_label_object_can_fill (glLabelObject *object)
1044 gl_debug (DEBUG_LABEL, "");
1046 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1048 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1060 /****************************************************************************/
1061 /* Set fill color for object. */
1062 /****************************************************************************/
1064 gl_label_object_set_fill_color (glLabelObject *object,
1065 glColorNode *fill_color_node,
1066 gboolean checkpoint)
1068 gl_debug (DEBUG_LABEL, "START");
1070 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1072 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
1074 /* We have an object specific method, use it */
1075 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node, checkpoint);
1078 gl_debug (DEBUG_LABEL, "END");
1082 /****************************************************************************/
1083 /* Get fill color for object. */
1084 /****************************************************************************/
1086 gl_label_object_get_fill_color (glLabelObject *object)
1088 glColorNode *ret = NULL;
1090 gl_debug (DEBUG_LABEL, "START");
1092 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1094 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
1096 /* We have an object specific method, use it */
1097 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1100 gl_debug (DEBUG_LABEL, "END");
1106 /*****************************************************************************/
1107 /* Can line color property be set for this object? */
1108 /*****************************************************************************/
1110 gl_label_object_can_line_color (glLabelObject *object)
1112 gl_debug (DEBUG_LABEL, "");
1114 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1116 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1128 /****************************************************************************/
1129 /* Set line color for object. */
1130 /****************************************************************************/
1132 gl_label_object_set_line_color (glLabelObject *object,
1133 glColorNode *line_color_node,
1134 gboolean checkpoint)
1136 gl_debug (DEBUG_LABEL, "START");
1138 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1140 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1142 /* We have an object specific method, use it */
1143 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node, checkpoint);
1146 gl_debug (DEBUG_LABEL, "END");
1150 /****************************************************************************/
1151 /* Get line color for object. */
1152 /****************************************************************************/
1154 gl_label_object_get_line_color (glLabelObject *object)
1156 glColorNode *ret = NULL;
1158 gl_debug (DEBUG_LABEL, "START");
1160 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1162 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
1164 /* We have an object specific method, use it */
1165 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1168 gl_debug (DEBUG_LABEL, "END");
1174 /*****************************************************************************/
1175 /* Can line width property be set for this object? */
1176 /*****************************************************************************/
1178 gl_label_object_can_line_width (glLabelObject *object)
1180 gl_debug (DEBUG_LABEL, "");
1182 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1184 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1196 /****************************************************************************/
1197 /* Set line width for object. */
1198 /****************************************************************************/
1200 gl_label_object_set_line_width (glLabelObject *object,
1202 gboolean checkpoint)
1204 gl_debug (DEBUG_LABEL, "START");
1206 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1208 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1210 /* We have an object specific method, use it */
1211 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width, checkpoint);
1214 gl_debug (DEBUG_LABEL, "END");
1218 /****************************************************************************/
1219 /* Get line width for object. */
1220 /****************************************************************************/
1222 gl_label_object_get_line_width (glLabelObject *object)
1226 gl_debug (DEBUG_LABEL, "START");
1228 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1230 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
1232 /* We have an object specific method, use it */
1233 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1236 gl_debug (DEBUG_LABEL, "END");
1242 /****************************************************************************/
1243 /* Set shadow state of object. */
1244 /****************************************************************************/
1246 gl_label_object_set_shadow_state (glLabelObject *object,
1248 gboolean checkpoint)
1250 gl_debug (DEBUG_LABEL, "START");
1252 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1254 if (object->priv->shadow_state != state)
1258 gl_label_checkpoint (object->priv->parent, _("Shadow state"));
1261 object->priv->shadow_state = state;
1263 gl_label_object_emit_changed (object);
1266 gl_debug (DEBUG_LABEL, "END");
1270 /****************************************************************************/
1271 /* Get shadow state of object. */
1272 /****************************************************************************/
1274 gl_label_object_get_shadow_state (glLabelObject *object)
1276 gl_debug (DEBUG_LABEL, "");
1278 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1280 return object->priv->shadow_state;
1284 /****************************************************************************/
1285 /* Set offset of object's shadow. */
1286 /****************************************************************************/
1288 gl_label_object_set_shadow_offset (glLabelObject *object,
1291 gboolean checkpoint)
1293 gl_debug (DEBUG_LABEL, "START");
1295 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1297 if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1301 gl_label_checkpoint (object->priv->parent, _("Shadow offset"));
1304 object->priv->shadow_x = x;
1305 object->priv->shadow_y = y;
1307 gl_label_object_emit_changed (object);
1310 gl_debug (DEBUG_LABEL, "END");
1314 /****************************************************************************/
1315 /* Get offset of object's shadow. */
1316 /****************************************************************************/
1318 gl_label_object_get_shadow_offset (glLabelObject *object,
1322 gl_debug (DEBUG_LABEL, "START");
1324 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1326 *x = object->priv->shadow_x;
1327 *y = object->priv->shadow_y;
1329 gl_debug (DEBUG_LABEL, "END");
1333 /****************************************************************************/
1334 /* Set color of object's shadow. */
1335 /****************************************************************************/
1337 gl_label_object_set_shadow_color (glLabelObject *object,
1338 glColorNode *color_node,
1339 gboolean checkpoint)
1341 gl_debug (DEBUG_LABEL, "START");
1343 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1345 if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1349 gl_label_checkpoint (object->priv->parent, _("Shadow color"));
1352 gl_color_node_free (&(object->priv->shadow_color_node));
1353 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1355 gl_label_object_emit_changed (object);
1358 gl_debug (DEBUG_LABEL, "END");
1362 /****************************************************************************/
1363 /* Get color of object's shadow. */
1364 /****************************************************************************/
1366 gl_label_object_get_shadow_color (glLabelObject *object)
1368 gl_debug (DEBUG_LABEL, "");
1370 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1372 return gl_color_node_dup (object->priv->shadow_color_node);
1376 /****************************************************************************/
1377 /* Set opacity of object's shadow. */
1378 /****************************************************************************/
1380 gl_label_object_set_shadow_opacity (glLabelObject *object,
1382 gboolean checkpoint)
1384 gl_debug (DEBUG_LABEL, "START");
1386 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1388 if (object->priv->shadow_opacity != alpha)
1392 gl_label_checkpoint (object->priv->parent, _("Shadow opacity"));
1395 object->priv->shadow_opacity = alpha;
1397 gl_label_object_emit_changed (object);
1400 gl_debug (DEBUG_LABEL, "END");
1404 /****************************************************************************/
1405 /* Get opacity of object's shadow. */
1406 /****************************************************************************/
1408 gl_label_object_get_shadow_opacity (glLabelObject *object)
1410 gl_debug (DEBUG_LABEL, "");
1412 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1414 return object->priv->shadow_opacity;
1418 /****************************************************************************/
1419 /* Flip object horizontally. */
1420 /****************************************************************************/
1422 gl_label_object_flip_horiz (glLabelObject *object)
1424 cairo_matrix_t flip_matrix;
1426 gl_debug (DEBUG_LABEL, "START");
1428 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1430 cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1431 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1433 gl_debug (DEBUG_LABEL, "END");
1437 /****************************************************************************/
1438 /* Flip object vertically. */
1439 /****************************************************************************/
1441 gl_label_object_flip_vert (glLabelObject *object)
1443 cairo_matrix_t flip_matrix;
1445 gl_debug (DEBUG_LABEL, "START");
1447 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1449 cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1450 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1452 gl_debug (DEBUG_LABEL, "END");
1456 /****************************************************************************/
1457 /* Rotate object. */
1458 /****************************************************************************/
1460 gl_label_object_rotate (glLabelObject *object,
1463 cairo_matrix_t rotate_matrix;
1465 gl_debug (DEBUG_LABEL, "START");
1467 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1469 cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1470 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1472 gl_debug (DEBUG_LABEL, "END");
1476 /****************************************************************************/
1477 /* Set raw affine */
1478 /****************************************************************************/
1480 gl_label_object_set_matrix (glLabelObject *object,
1481 cairo_matrix_t *matrix)
1483 gl_debug (DEBUG_LABEL, "");
1485 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1487 object->priv->matrix = *matrix;
1491 /****************************************************************************/
1492 /* Get raw affine */
1493 /****************************************************************************/
1495 gl_label_object_get_matrix (glLabelObject *object,
1496 cairo_matrix_t *matrix)
1498 gl_debug (DEBUG_LABEL, "");
1500 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1502 *matrix = object->priv->matrix;
1506 /*****************************************************************************/
1508 /*****************************************************************************/
1510 gl_label_object_draw (glLabelObject *object,
1512 gboolean screen_flag,
1513 glMergeRecord *record)
1517 cairo_matrix_t matrix;
1518 gboolean shadow_state;
1519 gdouble shadow_x, shadow_y;
1521 gl_debug (DEBUG_LABEL, "START");
1523 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1525 gl_label_object_get_position (object, &x0, &y0);
1526 gl_label_object_get_matrix (object, &matrix);
1529 cairo_translate (cr, x0, y0);
1531 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
1533 shadow_state = gl_label_object_get_shadow_state (object);
1537 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1540 cairo_translate (cr, shadow_x, shadow_y);
1541 cairo_transform (cr, &matrix);
1543 GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1552 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1555 cairo_transform (cr, &matrix);
1557 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1567 gl_debug (DEBUG_LABEL, "END");
1571 /*****************************************************************************/
1572 /* Is object located at coordinates. */
1573 /*****************************************************************************/
1575 gl_label_object_is_located_at (glLabelObject *object,
1580 gboolean ret_val = FALSE;
1582 cairo_matrix_t matrix;
1585 gl_debug (DEBUG_LABEL, "START");
1587 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1589 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1592 gl_label_object_get_position (object, &x0, &y0);
1593 gl_label_object_get_matrix (object, &matrix);
1597 cairo_translate (cr, x0, y0);
1598 cairo_transform (cr, &matrix);
1602 cairo_device_to_user (cr, &x, &y);
1604 ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
1609 gl_debug (DEBUG_LABEL, "END");
1615 /*****************************************************************************/
1616 /* Draw object handles */
1617 /*****************************************************************************/
1619 gl_label_object_draw_handles (glLabelObject *object,
1623 cairo_matrix_t matrix;
1625 gl_debug (DEBUG_LABEL, "START");
1627 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1629 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1632 gl_label_object_get_position (object, &x0, &y0);
1633 gl_label_object_get_matrix (object, &matrix);
1637 cairo_translate (cr, x0, y0);
1638 cairo_transform (cr, &matrix);
1640 GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
1645 gl_debug (DEBUG_LABEL, "END");
1649 /*--------------------------------------------------------------------------*/
1650 /* Draw individual handle */
1651 /*--------------------------------------------------------------------------*/
1653 draw_handle (cairo_t *cr,
1654 glLabelObject *object,
1658 gdouble scale_x, scale_y;
1661 gl_debug (DEBUG_VIEW, "START");
1665 cairo_translate (cr, x_handle, y_handle);
1669 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1670 cairo_scale (cr, scale_x, scale_y);
1672 cairo_rectangle (cr,
1673 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1674 HANDLE_PIXELS, HANDLE_PIXELS);
1676 cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
1677 cairo_fill_preserve (cr);
1679 cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
1680 cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
1685 gl_debug (DEBUG_VIEW, "END");
1689 /*--------------------------------------------------------------------------*/
1690 /* Create handle path */
1691 /*--------------------------------------------------------------------------*/
1693 create_handle_path (cairo_t *cr,
1694 glLabelObject *object,
1698 gdouble scale_x, scale_y;
1701 gl_debug (DEBUG_VIEW, "START");
1705 cairo_translate (cr, x_handle, y_handle);
1709 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1710 cairo_scale (cr, scale_x, scale_y);
1712 cairo_rectangle (cr,
1713 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1714 HANDLE_PIXELS, HANDLE_PIXELS);
1718 gl_debug (DEBUG_VIEW, "END");
1722 /*****************************************************************************/
1723 /* Draw box style handles. */
1724 /*****************************************************************************/
1726 gl_label_object_draw_handles_box (glLabelObject *object,
1731 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1734 draw_handle (cr, object, w/2, 0);
1737 draw_handle (cr, object, w, 0);
1740 draw_handle (cr, object, w, h/2);
1743 draw_handle (cr, object, w, h);
1746 draw_handle (cr, object, w/2, h);
1749 draw_handle (cr, object, 0, h);
1752 draw_handle (cr, object, 0, h/2);
1755 draw_handle (cr, object, 0, 0);
1759 /*****************************************************************************/
1760 /* Draw line style handles. */
1761 /*****************************************************************************/
1763 gl_label_object_draw_handles_line (glLabelObject *object,
1768 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1771 draw_handle (cr, object, w, h);
1774 draw_handle (cr, object, 0, 0);
1778 /*****************************************************************************/
1779 /* Get handle at given coordinates, if any. */
1780 /*****************************************************************************/
1782 gl_label_object_handle_at (glLabelObject *object,
1787 glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
1789 cairo_matrix_t matrix;
1792 gl_debug (DEBUG_LABEL, "START");
1794 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
1796 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1799 gl_label_object_get_position (object, &x0, &y0);
1800 gl_label_object_get_matrix (object, &matrix);
1804 cairo_translate (cr, x0, y0);
1805 cairo_transform (cr, &matrix);
1809 cairo_device_to_user (cr, &x, &y);
1811 handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
1816 gl_debug (DEBUG_LABEL, "END");
1822 /*****************************************************************************/
1823 /* Get handle at given coordinates for box style handles, if any. */
1824 /*****************************************************************************/
1826 gl_label_object_box_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_SE;
1843 create_handle_path (cr, object, 0, h);
1844 if (cairo_in_fill (cr, x, y))
1846 return GL_LABEL_OBJECT_HANDLE_SW;
1850 create_handle_path (cr, object, w, 0);
1851 if (cairo_in_fill (cr, x, y))
1853 return GL_LABEL_OBJECT_HANDLE_NE;
1857 create_handle_path (cr, object, 0, 0);
1858 if (cairo_in_fill (cr, x, y))
1860 return GL_LABEL_OBJECT_HANDLE_NW;
1864 create_handle_path (cr, object, w, h/2);
1865 if (cairo_in_fill (cr, x, y))
1867 return GL_LABEL_OBJECT_HANDLE_E;
1871 create_handle_path (cr, object, w/2, h);
1872 if (cairo_in_fill (cr, x, y))
1874 return GL_LABEL_OBJECT_HANDLE_S;
1878 create_handle_path (cr, object, 0, h/2);
1879 if (cairo_in_fill (cr, x, y))
1881 return GL_LABEL_OBJECT_HANDLE_W;
1885 create_handle_path (cr, object, w/2, 0);
1886 if (cairo_in_fill (cr, x, y))
1888 return GL_LABEL_OBJECT_HANDLE_N;
1891 return GL_LABEL_OBJECT_HANDLE_NONE;
1895 /*****************************************************************************/
1896 /* Get handle at given coordinates for line style handles, if any. */
1897 /*****************************************************************************/
1899 gl_label_object_line_handle_at (glLabelObject *object,
1906 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1909 create_handle_path (cr, object, w, h);
1910 if (cairo_in_fill (cr, x, y))
1912 return GL_LABEL_OBJECT_HANDLE_P2;
1916 create_handle_path (cr, object, 0, 0);
1917 if (cairo_in_fill (cr, x, y))
1919 return GL_LABEL_OBJECT_HANDLE_P1;
1922 return GL_LABEL_OBJECT_HANDLE_NONE;
1929 * Local Variables: -- emacs
1931 * c-basic-offset: 8 -- emacs
1932 * tab-width: 8 -- emacs
1933 * indent-tabs-mode: nil -- emacs