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"
33 /*========================================================*/
34 /* Private defines. */
35 /*========================================================*/
37 #define DEFAULT_SHADOW_X_OFFSET (3.6)
38 #define DEFAULT_SHADOW_Y_OFFSET (3.6)
39 #define DEFAULT_SHADOW_OPACITY (0.5)
41 #define HANDLE_FILL_RGBA_ARGS 0.0, 0.75, 0.0, 0.4
42 #define HANDLE_OUTLINE_RGBA_ARGS 0.0, 0.0, 0.0, 0.8
44 #define HANDLE_OUTLINE_WIDTH_PIXELS 1.0
45 #define HANDLE_PIXELS 7
48 /*========================================================*/
50 /*========================================================*/
52 struct _glLabelObjectPrivate {
56 gboolean selected_flag;
60 cairo_matrix_t matrix;
64 gboolean shadow_state;
67 glColorNode *shadow_color_node;
68 gdouble shadow_opacity;
77 /*========================================================*/
78 /* Private globals. */
79 /*========================================================*/
81 static guint instance = 0;
83 static guint signals[LAST_SIGNAL] = {0};
86 /*========================================================*/
87 /* Private function prototypes. */
88 /*========================================================*/
90 static void gl_label_object_finalize (GObject *object);
92 static void set_size (glLabelObject *object,
97 /*****************************************************************************/
98 /* Boilerplate object stuff. */
99 /*****************************************************************************/
100 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT);
104 gl_label_object_class_init (glLabelObjectClass *class)
106 GObjectClass *object_class = G_OBJECT_CLASS (class);
108 gl_debug (DEBUG_LABEL, "START");
110 gl_label_object_parent_class = g_type_class_peek_parent (class);
112 object_class->finalize = gl_label_object_finalize;
114 class->set_size = set_size;
115 class->draw_handles = gl_label_object_draw_handles_box; /* Default style */
116 class->handle_at = gl_label_object_box_handle_at; /* Default style */
119 g_signal_new ("changed",
120 G_OBJECT_CLASS_TYPE (object_class),
122 G_STRUCT_OFFSET (glLabelObjectClass, changed),
124 gl_marshal_VOID__VOID,
128 gl_debug (DEBUG_LABEL, "END");
133 gl_label_object_init (glLabelObject *object)
135 gl_debug (DEBUG_LABEL, "START");
137 object->priv = g_new0 (glLabelObjectPrivate, 1);
139 object->priv->name = g_strdup_printf ("object%d", instance++);
141 cairo_matrix_init_identity (&object->priv->matrix);
143 object->priv->shadow_state = FALSE;
144 object->priv->shadow_x = DEFAULT_SHADOW_X_OFFSET;
145 object->priv->shadow_y = DEFAULT_SHADOW_Y_OFFSET;
146 object->priv->shadow_color_node = gl_color_node_new_default ();
147 object->priv->shadow_opacity = DEFAULT_SHADOW_OPACITY;
149 gl_debug (DEBUG_LABEL, "END");
154 gl_label_object_finalize (GObject *object)
156 glLabelObject *label_object = GL_LABEL_OBJECT (object);
158 gl_debug (DEBUG_LABEL, "START");
160 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
162 g_free (label_object->priv->name);
163 g_free (label_object->priv);
165 G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
167 gl_debug (DEBUG_LABEL, "END");
171 /*****************************************************************************/
172 /* New label object. */
173 /*****************************************************************************/
175 gl_label_object_new (glLabel *label)
177 glLabelObject *object;
179 gl_debug (DEBUG_LABEL, "START");
181 object = g_object_new (gl_label_object_get_type(), NULL);
183 gl_label_object_set_parent (object, label);
185 gl_debug (DEBUG_LABEL, "END");
187 return G_OBJECT (object);
191 /*****************************************************************************/
192 /* Duplicate object. */
193 /*****************************************************************************/
195 gl_label_object_dup (glLabelObject *src_object,
198 glLabelObject *dst_object;
200 cairo_matrix_t matrix;
201 gboolean shadow_state;
202 gdouble shadow_x, shadow_y;
203 glColorNode *shadow_color_node;
204 gdouble shadow_opacity;
206 gl_debug (DEBUG_LABEL, "START");
208 g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
210 dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
212 gl_label_object_set_parent (dst_object, label);
214 gl_label_object_get_position (src_object, &x, &y);
215 gl_label_object_get_size (src_object, &w, &h);
216 gl_label_object_get_matrix (src_object, &matrix);
217 gl_label_object_get_shadow_offset (src_object, &shadow_x, &shadow_y);
218 shadow_color_node = gl_label_object_get_shadow_color (src_object);
219 shadow_opacity = gl_label_object_get_shadow_opacity (src_object);
220 shadow_state = gl_label_object_get_shadow_state (src_object);
222 gl_label_object_set_position (dst_object, x, y);
223 gl_label_object_set_size (dst_object, w, h);
224 gl_label_object_set_matrix (dst_object, &matrix);
225 gl_label_object_set_shadow_offset (dst_object, shadow_x, shadow_y);
226 gl_label_object_set_shadow_color (dst_object, shadow_color_node);
227 gl_label_object_set_shadow_opacity (dst_object, shadow_opacity);
228 gl_label_object_set_shadow_state (dst_object, shadow_state);
230 gl_color_node_free (&shadow_color_node);
232 if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL )
234 /* We have an object specific method, use it */
235 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
238 gl_debug (DEBUG_LABEL, "END");
244 /*****************************************************************************/
245 /* Emit "changed" signal (for derived objects). */
246 /*****************************************************************************/
248 gl_label_object_emit_changed (glLabelObject *object)
250 gl_debug (DEBUG_LABEL, "START");
252 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
254 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
256 gl_debug (DEBUG_LABEL, "END");
260 /*****************************************************************************/
261 /* Set parent label of object. */
262 /*****************************************************************************/
264 gl_label_object_set_parent (glLabelObject *object,
269 gl_debug (DEBUG_LABEL, "START");
271 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
272 g_return_if_fail (label && GL_IS_LABEL (label));
274 old_parent = object->parent;
275 if ( old_parent != NULL )
277 g_object_ref (object);
278 gl_label_delete_object( old_parent, object );
280 object->parent = label;
281 gl_label_add_object (label, object);
283 gl_label_object_emit_changed (object);
287 /*****************************************************************************/
288 /* Get parent label of object. */
289 /*****************************************************************************/
291 gl_label_object_get_parent (glLabelObject *object)
293 gl_debug (DEBUG_LABEL, "START");
295 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
297 gl_debug (DEBUG_LABEL, "END");
299 return object->parent;
303 /*****************************************************************************/
305 /*****************************************************************************/
307 gl_label_object_select (glLabelObject *object)
309 object->priv->selected_flag = TRUE;
313 /*****************************************************************************/
314 /* Unselect object. */
315 /*****************************************************************************/
317 gl_label_object_unselect (glLabelObject *object)
319 object->priv->selected_flag = FALSE;
323 /*****************************************************************************/
324 /* Is object selected? */
325 /*****************************************************************************/
327 gl_label_object_is_selected (glLabelObject *object)
329 return object->priv->selected_flag;
333 /*****************************************************************************/
334 /* Set name of object. */
335 /*****************************************************************************/
337 gl_label_object_set_name (glLabelObject *object,
340 gl_debug (DEBUG_LABEL, "START");
342 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
344 g_free(object->priv->name);
345 object->priv->name = name;
347 gl_label_object_emit_changed (object);
349 gl_debug (DEBUG_LABEL, "END");
353 /*****************************************************************************/
354 /* Get name of object. */
355 /*****************************************************************************/
357 gl_label_object_get_name (glLabelObject *object)
359 gl_debug (DEBUG_LABEL, "START");
361 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
363 gl_debug (DEBUG_LABEL, "END");
365 return g_strdup(object->priv->name);
369 /*****************************************************************************/
370 /* Set position of object. */
371 /*****************************************************************************/
373 gl_label_object_set_position (glLabelObject *object,
379 gl_debug (DEBUG_LABEL, "START");
381 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
383 if ( (x != object->priv->x) || (y != object->priv->y) )
385 dx = x - object->priv->x;
386 dy = y - object->priv->y;
392 gl_label_object_emit_changed (object);
394 gl_debug (DEBUG_LABEL, "END");
398 /*****************************************************************************/
399 /* Set position of object relative to old position. */
400 /*****************************************************************************/
402 gl_label_object_set_position_relative (glLabelObject *object,
406 gl_debug (DEBUG_LABEL, "START");
408 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
410 if ( (dx != 0.0) || (dy != 0.0) )
412 object->priv->x += dx;
413 object->priv->y += dy;
415 gl_debug (DEBUG_LABEL, " x = %f, y= %f",
420 gl_label_object_emit_changed (object);
422 gl_debug (DEBUG_LABEL, "END");
426 /*****************************************************************************/
427 /* Get position of object. */
428 /*****************************************************************************/
430 gl_label_object_get_position (glLabelObject *object,
434 gl_debug (DEBUG_LABEL, "START");
436 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
438 *x = object->priv->x;
439 *y = object->priv->y;
441 gl_debug (DEBUG_LABEL, "END");
445 /*---------------------------------------------------------------------------*/
446 /* PRIVATE. Default set size method. */
447 /*---------------------------------------------------------------------------*/
449 set_size (glLabelObject *object,
453 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
455 if ( (object->priv->w != w) || (object->priv->h != h) )
460 gl_label_object_emit_changed (object);
465 /*****************************************************************************/
466 /* Set size of object. */
467 /*****************************************************************************/
469 gl_label_object_set_size (glLabelObject *object,
473 gl_debug (DEBUG_LABEL, "START");
475 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
477 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
479 /* We have an object specific method, use it */
480 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
482 object->priv->aspect_ratio = h / w;
485 gl_debug (DEBUG_LABEL, "END");
489 /*****************************************************************************/
490 /* Set size of object honoring current aspect ratio. */
491 /*****************************************************************************/
493 gl_label_object_set_size_honor_aspect (glLabelObject *object,
497 gl_debug (DEBUG_LABEL, "START");
499 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
501 if ( h > w*object->priv->aspect_ratio )
503 h = w * object->priv->aspect_ratio;
507 w = h / object->priv->aspect_ratio;
510 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL )
512 /* We have an object specific method, use it */
513 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
516 gl_debug (DEBUG_LABEL, "END");
520 /*****************************************************************************/
521 /* Get raw size method (don't let object content adjust size). */
522 /*****************************************************************************/
524 gl_label_object_get_raw_size (glLabelObject *object,
528 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
530 *w = object->priv->w;
531 *h = object->priv->h;
535 /*****************************************************************************/
536 /* Get size of object. */
537 /*****************************************************************************/
539 gl_label_object_get_size (glLabelObject *object,
543 gl_debug (DEBUG_LABEL, "START");
545 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
547 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL )
549 /* We have an object specific method, use it */
550 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
554 gl_label_object_get_raw_size (object, w, h);
557 gl_debug (DEBUG_LABEL, "END");
561 /*****************************************************************************/
562 /* Get extent of object. */
563 /*****************************************************************************/
565 gl_label_object_get_extent (glLabelObject *object,
566 glLabelRegion *region)
570 gdouble xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
571 cairo_matrix_t matrix;
573 gl_debug (DEBUG_LABEL, "START");
575 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
577 gl_label_object_get_size (object, &w, &h);
578 line_w = gl_label_object_get_line_width (object);
580 /* setup untransformed corners of bounding box, account for line width */
590 /* transform these points */
591 gl_label_object_get_matrix (object, &matrix);
592 cairo_matrix_transform_point (&matrix, &xa1, &ya1);
593 cairo_matrix_transform_point (&matrix, &xa2, &ya2);
594 cairo_matrix_transform_point (&matrix, &xa3, &ya3);
595 cairo_matrix_transform_point (&matrix, &xa4, &ya4);
597 /* now find the maximum extent of these points in x and y */
598 region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
599 region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
600 region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
601 region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
603 gl_debug (DEBUG_LABEL, "END");
607 /*****************************************************************************/
608 /* Can text properties be set for this object? */
609 /*****************************************************************************/
611 gl_label_object_can_text (glLabelObject *object)
613 gl_debug (DEBUG_LABEL, "");
615 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
617 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
628 /*****************************************************************************/
629 /* Set font family for all text contained in object. */
630 /*****************************************************************************/
632 gl_label_object_set_font_family (glLabelObject *object,
633 const gchar *font_family)
635 gl_debug (DEBUG_LABEL, "START");
637 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
639 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL )
642 /* We have an object specific method, use it */
643 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family);
646 gl_debug (DEBUG_LABEL, "END");
650 /****************************************************************************/
651 /* Set font size for all text contained in object. */
652 /****************************************************************************/
654 gl_label_object_set_font_size (glLabelObject *object,
657 gl_debug (DEBUG_LABEL, "START");
659 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
661 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL )
663 /* We have an object specific method, use it */
664 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size);
667 gl_debug (DEBUG_LABEL, "END");
671 /****************************************************************************/
672 /* Set font weight for all text contained in object. */
673 /****************************************************************************/
675 gl_label_object_set_font_weight (glLabelObject *object,
676 PangoWeight font_weight)
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_weight != NULL )
684 /* We have an object specific method, use it */
685 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight);
688 gl_debug (DEBUG_LABEL, "END");
692 /****************************************************************************/
693 /* Set font italic flag for all text contained in object. */
694 /****************************************************************************/
696 gl_label_object_set_font_italic_flag (glLabelObject *object,
697 gboolean font_italic_flag)
699 gl_debug (DEBUG_LABEL, "START");
701 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
703 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL )
705 /* We have an object specific method, use it */
706 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object, font_italic_flag);
709 gl_debug (DEBUG_LABEL, "END");
713 /****************************************************************************/
714 /* Set text alignment for all text contained in object. */
715 /****************************************************************************/
717 gl_label_object_set_text_alignment (glLabelObject *object,
718 PangoAlignment text_alignment)
720 gl_debug (DEBUG_LABEL, "START");
722 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
724 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL )
726 /* We have an object specific method, use it */
727 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object, text_alignment);
730 gl_debug (DEBUG_LABEL, "END");
734 /****************************************************************************/
735 /* Set text line spacing for all text contained in object. */
736 /****************************************************************************/
738 gl_label_object_set_text_line_spacing (glLabelObject *object,
739 gdouble text_line_spacing)
741 gl_debug (DEBUG_LABEL, "START");
743 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
745 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL )
747 /* We have an object specific method, use it */
748 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing);
751 gl_debug (DEBUG_LABEL, "END");
755 /****************************************************************************/
756 /* Set text color for all text contained in object. */
757 /****************************************************************************/
759 gl_label_object_set_text_color (glLabelObject *object,
760 glColorNode *text_color_node)
762 gl_debug (DEBUG_LABEL, "START");
764 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
766 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL )
768 /* We have an object specific method, use it */
769 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node);
772 gl_debug (DEBUG_LABEL, "END");
776 /*****************************************************************************/
777 /* Get font family for all text contained in object. */
778 /*****************************************************************************/
780 gl_label_object_get_font_family (glLabelObject *object)
784 gl_debug (DEBUG_LABEL, "START");
786 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
788 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL )
790 /* We have an object specific method, use it */
791 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
794 gl_debug (DEBUG_LABEL, "END");
800 /****************************************************************************/
801 /* Get font size for all text contained in object. */
802 /****************************************************************************/
804 gl_label_object_get_font_size (glLabelObject *object)
808 gl_debug (DEBUG_LABEL, "START");
810 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
812 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL )
814 /* We have an object specific method, use it */
815 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
818 gl_debug (DEBUG_LABEL, "END");
824 /****************************************************************************/
825 /* Get font weight for all text contained in object. */
826 /****************************************************************************/
828 gl_label_object_get_font_weight (glLabelObject *object)
830 PangoWeight ret = PANGO_WEIGHT_NORMAL;
832 gl_debug (DEBUG_LABEL, "START");
834 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
836 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL )
838 /* We have an object specific method, use it */
839 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
842 gl_debug (DEBUG_LABEL, "END");
848 /****************************************************************************/
849 /* Get font italic flag for all text contained in object. */
850 /****************************************************************************/
852 gl_label_object_get_font_italic_flag (glLabelObject *object)
854 gboolean ret = FALSE;
856 gl_debug (DEBUG_LABEL, "START");
858 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
860 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL )
862 /* We have an object specific method, use it */
863 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
866 gl_debug (DEBUG_LABEL, "END");
872 /****************************************************************************/
873 /* Get text alignment for all text contained in object. */
874 /****************************************************************************/
876 gl_label_object_get_text_alignment (glLabelObject *object)
878 PangoAlignment ret = PANGO_ALIGN_LEFT;
880 gl_debug (DEBUG_LABEL, "START");
882 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
884 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL )
886 /* We have an object specific method, use it */
887 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
890 gl_debug (DEBUG_LABEL, "END");
896 /****************************************************************************/
897 /* Get text line spacing for all text contained in object. */
898 /****************************************************************************/
900 gl_label_object_get_text_line_spacing (glLabelObject *object)
904 gl_debug (DEBUG_LABEL, "START");
906 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
908 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL )
910 /* We have an object specific method, use it */
911 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
914 gl_debug (DEBUG_LABEL, "END");
920 /****************************************************************************/
921 /* Get text color for all text contained in object. */
922 /****************************************************************************/
924 gl_label_object_get_text_color (glLabelObject *object)
926 glColorNode *ret = NULL;
928 gl_debug (DEBUG_LABEL, "START");
930 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
932 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL )
934 /* We have an object specific method, use it */
935 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
938 gl_debug (DEBUG_LABEL, "END");
944 /*****************************************************************************/
945 /* Can fill properties be set for this object? */
946 /*****************************************************************************/
948 gl_label_object_can_fill (glLabelObject *object)
950 gl_debug (DEBUG_LABEL, "");
952 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
954 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
966 /****************************************************************************/
967 /* Set fill color for object. */
968 /****************************************************************************/
970 gl_label_object_set_fill_color (glLabelObject *object,
971 glColorNode *fill_color_node)
973 gl_debug (DEBUG_LABEL, "START");
975 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
977 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL )
979 /* We have an object specific method, use it */
980 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node);
983 gl_debug (DEBUG_LABEL, "END");
987 /****************************************************************************/
988 /* Get fill color for object. */
989 /****************************************************************************/
991 gl_label_object_get_fill_color (glLabelObject *object)
993 glColorNode *ret = NULL;
995 gl_debug (DEBUG_LABEL, "START");
997 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
999 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL )
1001 /* We have an object specific method, use it */
1002 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1005 gl_debug (DEBUG_LABEL, "END");
1011 /*****************************************************************************/
1012 /* Can line color property be set for this object? */
1013 /*****************************************************************************/
1015 gl_label_object_can_line_color (glLabelObject *object)
1017 gl_debug (DEBUG_LABEL, "");
1019 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1021 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1033 /****************************************************************************/
1034 /* Set line color for object. */
1035 /****************************************************************************/
1037 gl_label_object_set_line_color (glLabelObject *object,
1038 glColorNode *line_color_node)
1040 gl_debug (DEBUG_LABEL, "START");
1042 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1044 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL )
1046 /* We have an object specific method, use it */
1047 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node);
1050 gl_debug (DEBUG_LABEL, "END");
1054 /****************************************************************************/
1055 /* Get line color for object. */
1056 /****************************************************************************/
1058 gl_label_object_get_line_color (glLabelObject *object)
1060 glColorNode *ret = NULL;
1062 gl_debug (DEBUG_LABEL, "START");
1064 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1066 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL )
1068 /* We have an object specific method, use it */
1069 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1072 gl_debug (DEBUG_LABEL, "END");
1078 /*****************************************************************************/
1079 /* Can line width property be set for this object? */
1080 /*****************************************************************************/
1082 gl_label_object_can_line_width (glLabelObject *object)
1084 gl_debug (DEBUG_LABEL, "");
1086 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1088 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1100 /****************************************************************************/
1101 /* Set line width for object. */
1102 /****************************************************************************/
1104 gl_label_object_set_line_width (glLabelObject *object,
1107 gl_debug (DEBUG_LABEL, "START");
1109 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1111 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL )
1113 /* We have an object specific method, use it */
1114 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width);
1117 gl_debug (DEBUG_LABEL, "END");
1121 /****************************************************************************/
1122 /* Get line width for object. */
1123 /****************************************************************************/
1125 gl_label_object_get_line_width (glLabelObject *object)
1129 gl_debug (DEBUG_LABEL, "START");
1131 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1133 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL )
1135 /* We have an object specific method, use it */
1136 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1139 gl_debug (DEBUG_LABEL, "END");
1145 /****************************************************************************/
1146 /* Set shadow state of object. */
1147 /****************************************************************************/
1149 gl_label_object_set_shadow_state (glLabelObject *object,
1152 gl_debug (DEBUG_LABEL, "START");
1154 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1156 if (object->priv->shadow_state != state)
1158 object->priv->shadow_state = state;
1161 gl_debug (DEBUG_LABEL, "END");
1165 /****************************************************************************/
1166 /* Get shadow state of object. */
1167 /****************************************************************************/
1169 gl_label_object_get_shadow_state (glLabelObject *object)
1171 gl_debug (DEBUG_LABEL, "");
1173 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1175 return object->priv->shadow_state;
1179 /****************************************************************************/
1180 /* Set offset of object's shadow. */
1181 /****************************************************************************/
1183 gl_label_object_set_shadow_offset (glLabelObject *object,
1187 gl_debug (DEBUG_LABEL, "START");
1189 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1191 if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1193 object->priv->shadow_x = x;
1194 object->priv->shadow_y = y;
1197 gl_debug (DEBUG_LABEL, "END");
1201 /****************************************************************************/
1202 /* Get offset of object's shadow. */
1203 /****************************************************************************/
1205 gl_label_object_get_shadow_offset (glLabelObject *object,
1209 gl_debug (DEBUG_LABEL, "START");
1211 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1213 *x = object->priv->shadow_x;
1214 *y = object->priv->shadow_y;
1216 gl_debug (DEBUG_LABEL, "END");
1220 /****************************************************************************/
1221 /* Set color of object's shadow. */
1222 /****************************************************************************/
1224 gl_label_object_set_shadow_color (glLabelObject *object,
1225 glColorNode *color_node)
1227 gl_debug (DEBUG_LABEL, "START");
1229 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1231 if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1233 gl_color_node_free (&(object->priv->shadow_color_node));
1234 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1237 gl_debug (DEBUG_LABEL, "END");
1241 /****************************************************************************/
1242 /* Get color of object's shadow. */
1243 /****************************************************************************/
1245 gl_label_object_get_shadow_color (glLabelObject *object)
1247 gl_debug (DEBUG_LABEL, "");
1249 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1251 return gl_color_node_dup (object->priv->shadow_color_node);
1255 /****************************************************************************/
1256 /* Set opacity of object's shadow. */
1257 /****************************************************************************/
1259 gl_label_object_set_shadow_opacity (glLabelObject *object,
1262 gl_debug (DEBUG_LABEL, "START");
1264 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1266 if (object->priv->shadow_opacity != alpha)
1268 object->priv->shadow_opacity = alpha;
1271 gl_debug (DEBUG_LABEL, "END");
1275 /****************************************************************************/
1276 /* Get opacity of object's shadow. */
1277 /****************************************************************************/
1279 gl_label_object_get_shadow_opacity (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_opacity;
1289 /****************************************************************************/
1290 /* Flip object horizontally. */
1291 /****************************************************************************/
1293 gl_label_object_flip_horiz (glLabelObject *object)
1295 cairo_matrix_t flip_matrix;
1297 gl_debug (DEBUG_LABEL, "START");
1299 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1301 cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1302 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1304 gl_debug (DEBUG_LABEL, "END");
1308 /****************************************************************************/
1309 /* Flip object vertically. */
1310 /****************************************************************************/
1312 gl_label_object_flip_vert (glLabelObject *object)
1314 cairo_matrix_t flip_matrix;
1316 gl_debug (DEBUG_LABEL, "START");
1318 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1320 cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1321 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1323 gl_debug (DEBUG_LABEL, "END");
1327 /****************************************************************************/
1328 /* Rotate object. */
1329 /****************************************************************************/
1331 gl_label_object_rotate (glLabelObject *object,
1334 cairo_matrix_t rotate_matrix;
1336 gl_debug (DEBUG_LABEL, "START");
1338 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1340 cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1341 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1343 gl_debug (DEBUG_LABEL, "END");
1347 /****************************************************************************/
1348 /* Set raw affine */
1349 /****************************************************************************/
1351 gl_label_object_set_matrix (glLabelObject *object,
1352 cairo_matrix_t *matrix)
1354 gl_debug (DEBUG_LABEL, "");
1356 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1358 object->priv->matrix = *matrix;
1362 /****************************************************************************/
1363 /* Get raw affine */
1364 /****************************************************************************/
1366 gl_label_object_get_matrix (glLabelObject *object,
1367 cairo_matrix_t *matrix)
1369 gl_debug (DEBUG_LABEL, "");
1371 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1373 *matrix = object->priv->matrix;
1377 /*****************************************************************************/
1379 /*****************************************************************************/
1381 gl_label_object_draw (glLabelObject *object,
1383 gboolean screen_flag,
1384 glMergeRecord *record)
1388 cairo_matrix_t matrix;
1389 gboolean shadow_state;
1390 gdouble shadow_x, shadow_y;
1392 gl_debug (DEBUG_LABEL, "START");
1394 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1396 gl_label_object_get_position (object, &x0, &y0);
1397 gl_label_object_get_matrix (object, &matrix);
1400 cairo_translate (cr, x0, y0);
1402 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL )
1404 shadow_state = gl_label_object_get_shadow_state (object);
1408 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1411 cairo_translate (cr, shadow_x, shadow_y);
1412 cairo_transform (cr, &matrix);
1414 GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1423 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1426 cairo_transform (cr, &matrix);
1428 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1438 gl_debug (DEBUG_LABEL, "END");
1442 /*****************************************************************************/
1443 /* Is object located at coordinates. */
1444 /*****************************************************************************/
1446 gl_label_object_is_located_at (glLabelObject *object,
1451 gboolean ret_val = FALSE;
1453 cairo_matrix_t matrix;
1456 gl_debug (DEBUG_LABEL, "START");
1458 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1460 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1463 gl_label_object_get_position (object, &x0, &y0);
1464 gl_label_object_get_matrix (object, &matrix);
1468 cairo_translate (cr, x0, y0);
1469 cairo_transform (cr, &matrix);
1473 cairo_device_to_user (cr, &x, &y);
1475 ret_val = GL_LABEL_OBJECT_GET_CLASS(object)->object_at (object, cr, x, y);
1480 gl_debug (DEBUG_LABEL, "END");
1486 /*****************************************************************************/
1487 /* Draw object handles */
1488 /*****************************************************************************/
1490 gl_label_object_draw_handles (glLabelObject *object,
1494 cairo_matrix_t matrix;
1496 gl_debug (DEBUG_LABEL, "START");
1498 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1500 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1503 gl_label_object_get_position (object, &x0, &y0);
1504 gl_label_object_get_matrix (object, &matrix);
1508 cairo_translate (cr, x0, y0);
1509 cairo_transform (cr, &matrix);
1511 GL_LABEL_OBJECT_GET_CLASS(object)->draw_handles (object, cr);
1516 gl_debug (DEBUG_LABEL, "END");
1520 /*--------------------------------------------------------------------------*/
1521 /* Draw individual handle */
1522 /*--------------------------------------------------------------------------*/
1524 draw_handle (cairo_t *cr,
1525 glLabelObject *object,
1529 gdouble scale_x, scale_y;
1532 gl_debug (DEBUG_VIEW, "START");
1536 cairo_translate (cr, x_handle, y_handle);
1540 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1541 cairo_scale (cr, scale_x, scale_y);
1543 cairo_rectangle (cr,
1544 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1545 HANDLE_PIXELS, HANDLE_PIXELS);
1547 cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
1548 cairo_fill_preserve (cr);
1550 cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
1551 cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
1556 gl_debug (DEBUG_VIEW, "END");
1560 /*--------------------------------------------------------------------------*/
1561 /* Create handle path */
1562 /*--------------------------------------------------------------------------*/
1564 create_handle_path (cairo_t *cr,
1565 glLabelObject *object,
1569 gdouble scale_x, scale_y;
1572 gl_debug (DEBUG_VIEW, "START");
1576 cairo_translate (cr, x_handle, y_handle);
1580 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
1581 cairo_scale (cr, scale_x, scale_y);
1583 cairo_rectangle (cr,
1584 -HANDLE_PIXELS/2.0, -HANDLE_PIXELS/2.0,
1585 HANDLE_PIXELS, HANDLE_PIXELS);
1589 gl_debug (DEBUG_VIEW, "END");
1593 /*****************************************************************************/
1594 /* Draw box style handles. */
1595 /*****************************************************************************/
1597 gl_label_object_draw_handles_box (glLabelObject *object,
1602 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1605 draw_handle (cr, object, w/2, 0);
1608 draw_handle (cr, object, w, 0);
1611 draw_handle (cr, object, w, h/2);
1614 draw_handle (cr, object, w, h);
1617 draw_handle (cr, object, w/2, h);
1620 draw_handle (cr, object, 0, h);
1623 draw_handle (cr, object, 0, h/2);
1626 draw_handle (cr, object, 0, 0);
1630 /*****************************************************************************/
1631 /* Draw line style handles. */
1632 /*****************************************************************************/
1634 gl_label_object_draw_handles_line (glLabelObject *object,
1639 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1642 draw_handle (cr, object, w, h);
1645 draw_handle (cr, object, 0, 0);
1649 /*****************************************************************************/
1650 /* Get handle at given coordinates, if any. */
1651 /*****************************************************************************/
1653 gl_label_object_handle_at (glLabelObject *object,
1658 glLabelObjectHandle handle = GL_LABEL_OBJECT_HANDLE_NONE;
1660 cairo_matrix_t matrix;
1663 gl_debug (DEBUG_LABEL, "START");
1665 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
1667 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL )
1670 gl_label_object_get_position (object, &x0, &y0);
1671 gl_label_object_get_matrix (object, &matrix);
1675 cairo_translate (cr, x0, y0);
1676 cairo_transform (cr, &matrix);
1680 cairo_device_to_user (cr, &x, &y);
1682 handle = GL_LABEL_OBJECT_GET_CLASS(object)->handle_at (object, cr, x, y);
1687 gl_debug (DEBUG_LABEL, "END");
1693 /*****************************************************************************/
1694 /* Get handle at given coordinates for box style handles, if any. */
1695 /*****************************************************************************/
1697 gl_label_object_box_handle_at (glLabelObject *object,
1704 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1707 create_handle_path (cr, object, w, h);
1708 if (cairo_in_fill (cr, x, y))
1710 return GL_LABEL_OBJECT_HANDLE_SE;
1714 create_handle_path (cr, object, 0, h);
1715 if (cairo_in_fill (cr, x, y))
1717 return GL_LABEL_OBJECT_HANDLE_SW;
1721 create_handle_path (cr, object, w, 0);
1722 if (cairo_in_fill (cr, x, y))
1724 return GL_LABEL_OBJECT_HANDLE_NE;
1728 create_handle_path (cr, object, 0, 0);
1729 if (cairo_in_fill (cr, x, y))
1731 return GL_LABEL_OBJECT_HANDLE_NW;
1735 create_handle_path (cr, object, w, h/2);
1736 if (cairo_in_fill (cr, x, y))
1738 return GL_LABEL_OBJECT_HANDLE_E;
1742 create_handle_path (cr, object, w/2, h);
1743 if (cairo_in_fill (cr, x, y))
1745 return GL_LABEL_OBJECT_HANDLE_S;
1749 create_handle_path (cr, object, 0, h/2);
1750 if (cairo_in_fill (cr, x, y))
1752 return GL_LABEL_OBJECT_HANDLE_W;
1756 create_handle_path (cr, object, w/2, 0);
1757 if (cairo_in_fill (cr, x, y))
1759 return GL_LABEL_OBJECT_HANDLE_N;
1762 return GL_LABEL_OBJECT_HANDLE_NONE;
1766 /*****************************************************************************/
1767 /* Get handle at given coordinates for line style handles, if any. */
1768 /*****************************************************************************/
1770 gl_label_object_line_handle_at (glLabelObject *object,
1777 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1780 create_handle_path (cr, object, w, h);
1781 if (cairo_in_fill (cr, x, y))
1783 return GL_LABEL_OBJECT_HANDLE_P2;
1787 create_handle_path (cr, object, 0, h);
1788 if (cairo_in_fill (cr, x, y))
1790 return GL_LABEL_OBJECT_HANDLE_P1;
1793 return GL_LABEL_OBJECT_HANDLE_NONE;
1800 * Local Variables: -- emacs
1802 * c-basic-offset: 8 -- emacs
1803 * tab-width: 8 -- emacs
1804 * indent-tabs-mode: nil -- emacs