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)
42 /*========================================================*/
44 /*========================================================*/
46 struct _glLabelObjectPrivate {
50 cairo_matrix_t matrix;
54 gboolean shadow_state;
57 glColorNode *shadow_color_node;
58 gdouble shadow_opacity;
72 /*========================================================*/
73 /* Private globals. */
74 /*========================================================*/
76 static guint signals[LAST_SIGNAL] = {0};
78 static guint instance = 0;
81 /*========================================================*/
82 /* Private function prototypes. */
83 /*========================================================*/
85 static void gl_label_object_finalize (GObject *object);
87 static void merge_changed_cb (glLabel *label,
88 glLabelObject *object);
90 static void set_size (glLabelObject *object,
95 /*****************************************************************************/
96 /* Boilerplate object stuff. */
97 /*****************************************************************************/
98 G_DEFINE_TYPE (glLabelObject, gl_label_object, G_TYPE_OBJECT);
102 gl_label_object_class_init (glLabelObjectClass *class)
104 GObjectClass *object_class = G_OBJECT_CLASS (class);
106 gl_debug (DEBUG_LABEL, "START");
108 gl_label_object_parent_class = g_type_class_peek_parent (class);
110 object_class->finalize = gl_label_object_finalize;
112 class->set_size = set_size;
115 g_signal_new ("changed",
116 G_OBJECT_CLASS_TYPE (object_class),
118 G_STRUCT_OFFSET (glLabelObjectClass, changed),
120 gl_marshal_VOID__VOID,
125 g_signal_new ("moved",
126 G_OBJECT_CLASS_TYPE (object_class),
128 G_STRUCT_OFFSET (glLabelObjectClass, moved),
130 gl_marshal_VOID__DOUBLE_DOUBLE,
132 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
133 signals[FLIP_ROTATE] =
134 g_signal_new ("flip_rotate",
135 G_OBJECT_CLASS_TYPE (object_class),
137 G_STRUCT_OFFSET (glLabelObjectClass, flip_rotate),
139 gl_marshal_VOID__VOID,
144 G_OBJECT_CLASS_TYPE (object_class),
146 G_STRUCT_OFFSET (glLabelObjectClass, top),
148 gl_marshal_VOID__VOID,
153 g_signal_new ("bottom",
154 G_OBJECT_CLASS_TYPE (object_class),
156 G_STRUCT_OFFSET (glLabelObjectClass, bottom),
158 gl_marshal_VOID__VOID,
162 g_signal_new ("removed",
163 G_OBJECT_CLASS_TYPE (object_class),
165 G_STRUCT_OFFSET (glLabelObjectClass, removed),
167 gl_marshal_VOID__VOID,
171 gl_debug (DEBUG_LABEL, "END");
176 gl_label_object_init (glLabelObject *object)
178 gl_debug (DEBUG_LABEL, "START");
180 object->priv = g_new0 (glLabelObjectPrivate, 1);
182 object->priv->name = g_strdup_printf ("object%d", instance++);
184 cairo_matrix_init_identity (&object->priv->matrix);
186 object->priv->shadow_state = FALSE;
187 object->priv->shadow_x = DEFAULT_SHADOW_X_OFFSET;
188 object->priv->shadow_y = DEFAULT_SHADOW_Y_OFFSET;
189 object->priv->shadow_color_node = gl_color_node_new_default ();
190 object->priv->shadow_opacity = DEFAULT_SHADOW_OPACITY;
192 gl_debug (DEBUG_LABEL, "END");
197 gl_label_object_finalize (GObject *object)
199 glLabelObject *label_object = GL_LABEL_OBJECT (object);
201 gl_debug (DEBUG_LABEL, "START");
203 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
205 g_free (label_object->priv->name);
206 g_free (label_object->priv);
208 G_OBJECT_CLASS (gl_label_object_parent_class)->finalize (object);
210 gl_debug (DEBUG_LABEL, "END");
214 /*****************************************************************************/
215 /* New label object. */
216 /*****************************************************************************/
218 gl_label_object_new (glLabel *label)
220 glLabelObject *object;
222 gl_debug (DEBUG_LABEL, "START");
224 object = g_object_new (gl_label_object_get_type(), NULL);
226 gl_label_object_set_parent (object, label);
228 gl_debug (DEBUG_LABEL, "END");
230 return G_OBJECT (object);
234 /*****************************************************************************/
235 /* Duplicate object. */
236 /*****************************************************************************/
238 gl_label_object_dup (glLabelObject *src_object,
241 glLabelObject *dst_object;
243 cairo_matrix_t matrix;
244 gboolean shadow_state;
245 gdouble shadow_x, shadow_y;
246 glColorNode *shadow_color_node;
247 gdouble shadow_opacity;
249 gl_debug (DEBUG_LABEL, "START");
251 g_return_val_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object), NULL);
253 dst_object = g_object_new (G_OBJECT_TYPE(src_object), NULL);
255 gl_label_object_set_parent (dst_object, label);
257 gl_label_object_get_position (src_object, &x, &y);
258 gl_label_object_get_size (src_object, &w, &h);
259 gl_label_object_get_matrix (src_object, &matrix);
260 gl_label_object_get_shadow_offset (src_object, &shadow_x, &shadow_y);
261 shadow_color_node = gl_label_object_get_shadow_color (src_object);
262 shadow_opacity = gl_label_object_get_shadow_opacity (src_object);
263 shadow_state = gl_label_object_get_shadow_state (src_object);
265 gl_label_object_set_position (dst_object, x, y);
266 gl_label_object_set_size (dst_object, w, h);
267 gl_label_object_set_matrix (dst_object, &matrix);
268 gl_label_object_set_shadow_offset (dst_object, shadow_x, shadow_y);
269 gl_label_object_set_shadow_color (dst_object, shadow_color_node);
270 gl_label_object_set_shadow_opacity (dst_object, shadow_opacity);
271 gl_label_object_set_shadow_state (dst_object, shadow_state);
273 gl_color_node_free (&shadow_color_node);
275 if ( GL_LABEL_OBJECT_GET_CLASS(src_object)->copy != NULL ) {
277 /* We have an object specific method, use it */
278 GL_LABEL_OBJECT_GET_CLASS(src_object)->copy (dst_object, src_object);
282 gl_debug (DEBUG_LABEL, "END");
288 /*****************************************************************************/
289 /* Emit "changed" signal (for derived objects). */
290 /*****************************************************************************/
292 gl_label_object_emit_changed (glLabelObject *object)
294 gl_debug (DEBUG_LABEL, "START");
296 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
298 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
300 gl_debug (DEBUG_LABEL, "END");
304 /*****************************************************************************/
305 /* Set parent label of object. */
306 /*****************************************************************************/
308 gl_label_object_set_parent (glLabelObject *object,
313 gl_debug (DEBUG_LABEL, "START");
315 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
316 g_return_if_fail (label && GL_IS_LABEL (label));
318 old_parent = object->parent;
319 if ( old_parent != NULL ) {
320 g_signal_handlers_disconnect_by_func (old_parent,
321 G_CALLBACK(merge_changed_cb),
323 gl_label_remove_object( old_parent, object );
325 gl_label_add_object( label, object );
327 g_signal_connect (G_OBJECT(label), "merge_changed",
328 G_CALLBACK(merge_changed_cb), object);
330 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
332 gl_debug (DEBUG_LABEL, "END");
336 /*****************************************************************************/
337 /* Get parent label of object. */
338 /*****************************************************************************/
340 gl_label_object_get_parent (glLabelObject *object)
342 gl_debug (DEBUG_LABEL, "START");
344 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
346 gl_debug (DEBUG_LABEL, "END");
348 return object->parent;
352 /*****************************************************************************/
353 /* Set remove object from parent. */
354 /*****************************************************************************/
356 gl_label_object_remove (glLabelObject *object)
360 gl_debug (DEBUG_LABEL, "START");
362 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
364 parent = object->parent;
365 if ( parent != NULL ) {
366 g_signal_handlers_disconnect_by_func (parent,
367 G_CALLBACK(merge_changed_cb),
369 gl_label_remove_object (parent, object);
371 g_signal_emit (G_OBJECT(object), signals[REMOVED], 0);
373 g_object_unref (G_OBJECT(object));
377 gl_debug (DEBUG_LABEL, "END");
381 /*****************************************************************************/
382 /* Set name of object. */
383 /*****************************************************************************/
385 gl_label_object_set_name (glLabelObject *object,
388 gl_debug (DEBUG_LABEL, "START");
390 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
392 g_free(object->priv->name);
393 object->priv->name = name;
395 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
397 gl_debug (DEBUG_LABEL, "END");
401 /*****************************************************************************/
402 /* Get name of object. */
403 /*****************************************************************************/
405 gl_label_object_get_name (glLabelObject *object)
407 gl_debug (DEBUG_LABEL, "START");
409 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
411 gl_debug (DEBUG_LABEL, "END");
413 return g_strdup(object->priv->name);
417 /*****************************************************************************/
418 /* Set position of object. */
419 /*****************************************************************************/
421 gl_label_object_set_position (glLabelObject *object,
427 gl_debug (DEBUG_LABEL, "START");
429 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
431 if ( (x != object->priv->x) || (y != object->priv->y) ) {
433 dx = x - object->priv->x;
434 dy = y - object->priv->y;
439 g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
443 gl_debug (DEBUG_LABEL, "END");
447 /*****************************************************************************/
448 /* Set position of object relative to old position. */
449 /*****************************************************************************/
451 gl_label_object_set_position_relative (glLabelObject *object,
455 gl_debug (DEBUG_LABEL, "START");
457 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
459 if ( (dx != 0.0) || (dy != 0.0) ) {
461 object->priv->x += dx;
462 object->priv->y += dy;
464 gl_debug (DEBUG_LABEL, " x = %f, y= %f",
468 g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
472 gl_debug (DEBUG_LABEL, "END");
476 /*****************************************************************************/
477 /* Get position of object. */
478 /*****************************************************************************/
480 gl_label_object_get_position (glLabelObject *object,
484 gl_debug (DEBUG_LABEL, "START");
486 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
488 *x = object->priv->x;
489 *y = object->priv->y;
491 gl_debug (DEBUG_LABEL, "END");
495 /*---------------------------------------------------------------------------*/
496 /* PRIVATE. Default set size method. */
497 /*---------------------------------------------------------------------------*/
499 set_size (glLabelObject *object,
503 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
505 if ( (object->priv->w != w) || (object->priv->h != h) ) {
510 g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
515 /*****************************************************************************/
516 /* Set size of object. */
517 /*****************************************************************************/
519 gl_label_object_set_size (glLabelObject *object,
523 gl_debug (DEBUG_LABEL, "START");
525 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
527 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
529 /* We have an object specific method, use it */
530 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
532 object->priv->aspect_ratio = h / w;
537 gl_debug (DEBUG_LABEL, "END");
541 /*****************************************************************************/
542 /* Set size of object honoring current aspect ratio. */
543 /*****************************************************************************/
545 gl_label_object_set_size_honor_aspect (glLabelObject *object,
549 gl_debug (DEBUG_LABEL, "START");
551 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
553 if ( h > w*object->priv->aspect_ratio ) {
555 h = w * object->priv->aspect_ratio;
559 w = h / object->priv->aspect_ratio;
563 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_size != NULL ) {
565 /* We have an object specific method, use it */
566 GL_LABEL_OBJECT_GET_CLASS(object)->set_size (object, w, h);
570 gl_debug (DEBUG_LABEL, "END");
574 /*****************************************************************************/
575 /* Get raw size method (don't let object content adjust size). */
576 /*****************************************************************************/
578 gl_label_object_get_raw_size (glLabelObject *object,
582 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
584 *w = object->priv->w;
585 *h = object->priv->h;
589 /*****************************************************************************/
590 /* Get size of object. */
591 /*****************************************************************************/
593 gl_label_object_get_size (glLabelObject *object,
597 gl_debug (DEBUG_LABEL, "START");
599 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
601 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_size != NULL ) {
603 /* We have an object specific method, use it */
604 GL_LABEL_OBJECT_GET_CLASS(object)->get_size (object, w, h);
608 gl_label_object_get_raw_size (object, w, h);
612 gl_debug (DEBUG_LABEL, "END");
616 /*****************************************************************************/
617 /* Get extent of object. */
618 /*****************************************************************************/
620 gl_label_object_get_extent (glLabelObject *object,
621 glLabelRegion *region)
625 gdouble xa1, ya1, xa2, ya2, xa3, ya3, xa4, ya4;
626 cairo_matrix_t matrix;
628 gl_debug (DEBUG_LABEL, "START");
630 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
632 gl_label_object_get_size (object, &w, &h);
633 line_w = gl_label_object_get_line_width (object);
635 /* setup untransformed corners of bounding box, account for line width */
645 /* transform these points */
646 gl_label_object_get_matrix (object, &matrix);
647 cairo_matrix_transform_point (&matrix, &xa1, &ya1);
648 cairo_matrix_transform_point (&matrix, &xa2, &ya2);
649 cairo_matrix_transform_point (&matrix, &xa3, &ya3);
650 cairo_matrix_transform_point (&matrix, &xa4, &ya4);
652 /* now find the maximum extent of these points in x and y */
653 region->x1 = MIN (xa1, MIN (xa2, MIN (xa3, xa4))) + object->priv->x;
654 region->y1 = MIN (ya1, MIN (ya2, MIN (ya3, ya4))) + object->priv->y;
655 region->x2 = MAX (xa1, MAX (xa2, MAX (xa3, xa4))) + object->priv->x;
656 region->y2 = MAX (ya1, MAX (ya2, MAX (ya3, ya4))) + object->priv->y;
658 gl_debug (DEBUG_LABEL, "END");
662 /*****************************************************************************/
663 /* Can text properties be set for this object? */
664 /*****************************************************************************/
666 gl_label_object_can_text (glLabelObject *object)
668 gl_debug (DEBUG_LABEL, "");
670 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
672 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
685 /*****************************************************************************/
686 /* Set font family for all text contained in object. */
687 /*****************************************************************************/
689 gl_label_object_set_font_family (glLabelObject *object,
690 const gchar *font_family)
692 gl_debug (DEBUG_LABEL, "START");
694 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
696 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family != NULL ) {
698 /* We have an object specific method, use it */
699 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_family (object, font_family);
703 gl_debug (DEBUG_LABEL, "END");
707 /****************************************************************************/
708 /* Set font size for all text contained in object. */
709 /****************************************************************************/
711 gl_label_object_set_font_size (glLabelObject *object,
714 gl_debug (DEBUG_LABEL, "START");
716 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
718 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size != NULL ) {
720 /* We have an object specific method, use it */
721 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_size (object, font_size);
725 gl_debug (DEBUG_LABEL, "END");
729 /****************************************************************************/
730 /* Set font weight for all text contained in object. */
731 /****************************************************************************/
733 gl_label_object_set_font_weight (glLabelObject *object,
734 PangoWeight font_weight)
736 gl_debug (DEBUG_LABEL, "START");
738 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
740 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight != NULL ) {
742 /* We have an object specific method, use it */
743 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_weight (object, font_weight);
747 gl_debug (DEBUG_LABEL, "END");
751 /****************************************************************************/
752 /* Set font italic flag for all text contained in object. */
753 /****************************************************************************/
755 gl_label_object_set_font_italic_flag (glLabelObject *object,
756 gboolean font_italic_flag)
758 gl_debug (DEBUG_LABEL, "START");
760 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
762 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag != NULL ) {
764 /* We have an object specific method, use it */
765 GL_LABEL_OBJECT_GET_CLASS(object)->set_font_italic_flag (object,
770 gl_debug (DEBUG_LABEL, "END");
774 /****************************************************************************/
775 /* Set text alignment for all text contained in object. */
776 /****************************************************************************/
778 gl_label_object_set_text_alignment (glLabelObject *object,
779 PangoAlignment text_alignment)
781 gl_debug (DEBUG_LABEL, "START");
783 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
785 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment != NULL ) {
787 /* We have an object specific method, use it */
788 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_alignment (object,
793 gl_debug (DEBUG_LABEL, "END");
797 /****************************************************************************/
798 /* Set text line spacing for all text contained in object. */
799 /****************************************************************************/
801 gl_label_object_set_text_line_spacing (glLabelObject *object,
802 gdouble text_line_spacing)
804 gl_debug (DEBUG_LABEL, "START");
806 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
808 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing != NULL ) {
810 /* We have an object specific method, use it */
811 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_line_spacing (object, text_line_spacing);
815 gl_debug (DEBUG_LABEL, "END");
819 /****************************************************************************/
820 /* Set text color for all text contained in object. */
821 /****************************************************************************/
823 gl_label_object_set_text_color (glLabelObject *object,
824 glColorNode *text_color_node)
826 gl_debug (DEBUG_LABEL, "START");
828 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
830 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color != NULL ) {
832 /* We have an object specific method, use it */
833 GL_LABEL_OBJECT_GET_CLASS(object)->set_text_color (object, text_color_node);
837 gl_debug (DEBUG_LABEL, "END");
841 /*****************************************************************************/
842 /* Get font family for all text contained in object. */
843 /*****************************************************************************/
845 gl_label_object_get_font_family (glLabelObject *object)
849 gl_debug (DEBUG_LABEL, "START");
851 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
853 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family != NULL ) {
855 /* We have an object specific method, use it */
856 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_family (object);
860 gl_debug (DEBUG_LABEL, "END");
866 /****************************************************************************/
867 /* Get font size for all text contained in object. */
868 /****************************************************************************/
870 gl_label_object_get_font_size (glLabelObject *object)
874 gl_debug (DEBUG_LABEL, "START");
876 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
878 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size != NULL ) {
880 /* We have an object specific method, use it */
881 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_size (object);
885 gl_debug (DEBUG_LABEL, "END");
891 /****************************************************************************/
892 /* Get font weight for all text contained in object. */
893 /****************************************************************************/
895 gl_label_object_get_font_weight (glLabelObject *object)
897 PangoWeight ret = PANGO_WEIGHT_NORMAL;
899 gl_debug (DEBUG_LABEL, "START");
901 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_WEIGHT_NORMAL);
903 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight != NULL ) {
905 /* We have an object specific method, use it */
906 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_weight (object);
910 gl_debug (DEBUG_LABEL, "END");
916 /****************************************************************************/
917 /* Get font italic flag for all text contained in object. */
918 /****************************************************************************/
920 gl_label_object_get_font_italic_flag (glLabelObject *object)
922 gboolean ret = FALSE;
924 gl_debug (DEBUG_LABEL, "START");
926 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
928 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag != NULL ) {
930 /* We have an object specific method, use it */
931 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_font_italic_flag (object);
935 gl_debug (DEBUG_LABEL, "END");
941 /****************************************************************************/
942 /* Get text alignment for all text contained in object. */
943 /****************************************************************************/
945 gl_label_object_get_text_alignment (glLabelObject *object)
947 PangoAlignment ret = PANGO_ALIGN_LEFT;
949 gl_debug (DEBUG_LABEL, "START");
951 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), PANGO_ALIGN_LEFT);
953 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment != NULL ) {
955 /* We have an object specific method, use it */
956 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_alignment (object);
960 gl_debug (DEBUG_LABEL, "END");
966 /****************************************************************************/
967 /* Get text line spacing for all text contained in object. */
968 /****************************************************************************/
970 gl_label_object_get_text_line_spacing (glLabelObject *object)
974 gl_debug (DEBUG_LABEL, "START");
976 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
978 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing != NULL ) {
980 /* We have an object specific method, use it */
981 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_line_spacing (object);
985 gl_debug (DEBUG_LABEL, "END");
991 /****************************************************************************/
992 /* Get text color for all text contained in object. */
993 /****************************************************************************/
995 gl_label_object_get_text_color (glLabelObject *object)
997 glColorNode *ret = NULL;
999 gl_debug (DEBUG_LABEL, "START");
1001 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1003 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color != NULL ) {
1005 /* We have an object specific method, use it */
1006 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_text_color (object);
1010 gl_debug (DEBUG_LABEL, "END");
1016 /*****************************************************************************/
1017 /* Can fill properties be set for this object? */
1018 /*****************************************************************************/
1020 gl_label_object_can_fill (glLabelObject *object)
1022 gl_debug (DEBUG_LABEL, "");
1024 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1026 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
1039 /****************************************************************************/
1040 /* Set fill color for object. */
1041 /****************************************************************************/
1043 gl_label_object_set_fill_color (glLabelObject *object,
1044 glColorNode *fill_color_node)
1046 gl_debug (DEBUG_LABEL, "START");
1048 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1050 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color != NULL ) {
1052 /* We have an object specific method, use it */
1053 GL_LABEL_OBJECT_GET_CLASS(object)->set_fill_color (object, fill_color_node);
1057 gl_debug (DEBUG_LABEL, "END");
1061 /****************************************************************************/
1062 /* Get fill color for object. */
1063 /****************************************************************************/
1065 gl_label_object_get_fill_color (glLabelObject *object)
1067 glColorNode *ret = NULL;
1069 gl_debug (DEBUG_LABEL, "START");
1071 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1073 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color != NULL ) {
1075 /* We have an object specific method, use it */
1076 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_fill_color (object);
1080 gl_debug (DEBUG_LABEL, "END");
1086 /*****************************************************************************/
1087 /* Can line color property be set for this object? */
1088 /*****************************************************************************/
1090 gl_label_object_can_line_color (glLabelObject *object)
1092 gl_debug (DEBUG_LABEL, "");
1094 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1096 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
1109 /****************************************************************************/
1110 /* Set line color for object. */
1111 /****************************************************************************/
1113 gl_label_object_set_line_color (glLabelObject *object,
1114 glColorNode *line_color_node)
1116 gl_debug (DEBUG_LABEL, "START");
1118 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1120 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color != NULL ) {
1122 /* We have an object specific method, use it */
1123 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_color (object, line_color_node);
1127 gl_debug (DEBUG_LABEL, "END");
1131 /****************************************************************************/
1132 /* Get line color for object. */
1133 /****************************************************************************/
1135 gl_label_object_get_line_color (glLabelObject *object)
1137 glColorNode *ret = NULL;
1139 gl_debug (DEBUG_LABEL, "START");
1141 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0);
1143 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color != NULL ) {
1145 /* We have an object specific method, use it */
1146 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_color (object);
1150 gl_debug (DEBUG_LABEL, "END");
1156 /*****************************************************************************/
1157 /* Can line width property be set for this object? */
1158 /*****************************************************************************/
1160 gl_label_object_can_line_width (glLabelObject *object)
1162 gl_debug (DEBUG_LABEL, "");
1164 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1166 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
1179 /****************************************************************************/
1180 /* Set line width for object. */
1181 /****************************************************************************/
1183 gl_label_object_set_line_width (glLabelObject *object,
1186 gl_debug (DEBUG_LABEL, "START");
1188 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1190 if ( GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width != NULL ) {
1192 /* We have an object specific method, use it */
1193 GL_LABEL_OBJECT_GET_CLASS(object)->set_line_width (object, line_width);
1197 gl_debug (DEBUG_LABEL, "END");
1201 /****************************************************************************/
1202 /* Get line width for object. */
1203 /****************************************************************************/
1205 gl_label_object_get_line_width (glLabelObject *object)
1209 gl_debug (DEBUG_LABEL, "START");
1211 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), 0.0);
1213 if ( GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width != NULL ) {
1215 /* We have an object specific method, use it */
1216 ret = GL_LABEL_OBJECT_GET_CLASS(object)->get_line_width (object);
1220 gl_debug (DEBUG_LABEL, "END");
1226 /****************************************************************************/
1227 /* Set shadow state of object. */
1228 /****************************************************************************/
1230 gl_label_object_set_shadow_state (glLabelObject *object,
1233 gl_debug (DEBUG_LABEL, "START");
1235 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1237 if (object->priv->shadow_state != state)
1239 object->priv->shadow_state = state;
1240 gl_label_object_emit_changed (object);
1243 gl_debug (DEBUG_LABEL, "END");
1247 /****************************************************************************/
1248 /* Get shadow state of object. */
1249 /****************************************************************************/
1251 gl_label_object_get_shadow_state (glLabelObject *object)
1253 gl_debug (DEBUG_LABEL, "");
1255 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1257 return object->priv->shadow_state;
1261 /****************************************************************************/
1262 /* Set offset of object's shadow. */
1263 /****************************************************************************/
1265 gl_label_object_set_shadow_offset (glLabelObject *object,
1269 gl_debug (DEBUG_LABEL, "START");
1271 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1273 if ( (x != object->priv->shadow_x) || (y != object->priv->shadow_y) )
1275 object->priv->shadow_x = x;
1276 object->priv->shadow_y = y;
1278 gl_label_object_emit_changed (object);
1281 gl_debug (DEBUG_LABEL, "END");
1285 /****************************************************************************/
1286 /* Get offset of object's shadow. */
1287 /****************************************************************************/
1289 gl_label_object_get_shadow_offset (glLabelObject *object,
1293 gl_debug (DEBUG_LABEL, "START");
1295 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1297 *x = object->priv->shadow_x;
1298 *y = object->priv->shadow_y;
1300 gl_debug (DEBUG_LABEL, "END");
1304 /****************************************************************************/
1305 /* Set color of object's shadow. */
1306 /****************************************************************************/
1308 gl_label_object_set_shadow_color (glLabelObject *object,
1309 glColorNode *color_node)
1311 gl_debug (DEBUG_LABEL, "START");
1313 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1315 if ( !gl_color_node_equal (object->priv->shadow_color_node, color_node ))
1317 gl_color_node_free (&(object->priv->shadow_color_node));
1318 object->priv->shadow_color_node = gl_color_node_dup (color_node);
1319 gl_label_object_emit_changed (GL_LABEL_OBJECT(object));
1322 gl_debug (DEBUG_LABEL, "END");
1326 /****************************************************************************/
1327 /* Get color of object's shadow. */
1328 /****************************************************************************/
1330 gl_label_object_get_shadow_color (glLabelObject *object)
1332 gl_debug (DEBUG_LABEL, "");
1334 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), NULL);
1336 return gl_color_node_dup (object->priv->shadow_color_node);
1340 /****************************************************************************/
1341 /* Set opacity of object's shadow. */
1342 /****************************************************************************/
1344 gl_label_object_set_shadow_opacity (glLabelObject *object,
1347 gl_debug (DEBUG_LABEL, "START");
1349 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1351 if (object->priv->shadow_opacity != alpha)
1353 object->priv->shadow_opacity = alpha;
1354 gl_label_object_emit_changed (object);
1357 gl_debug (DEBUG_LABEL, "END");
1361 /****************************************************************************/
1362 /* Get opacity of object's shadow. */
1363 /****************************************************************************/
1365 gl_label_object_get_shadow_opacity (glLabelObject *object)
1367 gl_debug (DEBUG_LABEL, "");
1369 g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
1371 return object->priv->shadow_opacity;
1375 /****************************************************************************/
1376 /* Flip object horizontally. */
1377 /****************************************************************************/
1379 gl_label_object_flip_horiz (glLabelObject *object)
1381 cairo_matrix_t flip_matrix;
1383 gl_debug (DEBUG_LABEL, "START");
1385 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1387 cairo_matrix_init_scale (&flip_matrix, -1.0, 1.0);
1388 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1390 g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1392 gl_debug (DEBUG_LABEL, "END");
1396 /****************************************************************************/
1397 /* Flip object vertically. */
1398 /****************************************************************************/
1400 gl_label_object_flip_vert (glLabelObject *object)
1402 cairo_matrix_t flip_matrix;
1404 gl_debug (DEBUG_LABEL, "START");
1406 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1408 cairo_matrix_init_scale (&flip_matrix, 1.0, -1.0);
1409 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &flip_matrix);
1411 g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1413 gl_debug (DEBUG_LABEL, "END");
1417 /****************************************************************************/
1418 /* Rotate object. */
1419 /****************************************************************************/
1421 gl_label_object_rotate (glLabelObject *object,
1424 cairo_matrix_t rotate_matrix;
1426 gl_debug (DEBUG_LABEL, "START");
1428 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1430 cairo_matrix_init_rotate (&rotate_matrix, theta_degs*(G_PI/180.));
1431 cairo_matrix_multiply (&object->priv->matrix, &object->priv->matrix, &rotate_matrix);
1433 g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
1435 gl_debug (DEBUG_LABEL, "END");
1439 /****************************************************************************/
1440 /* Set raw affine */
1441 /****************************************************************************/
1443 gl_label_object_set_matrix (glLabelObject *object,
1444 cairo_matrix_t *matrix)
1446 gl_debug (DEBUG_LABEL, "");
1448 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1450 object->priv->matrix = *matrix;
1454 /****************************************************************************/
1455 /* Get raw affine */
1456 /****************************************************************************/
1458 gl_label_object_get_matrix (glLabelObject *object,
1459 cairo_matrix_t *matrix)
1461 gl_debug (DEBUG_LABEL, "");
1463 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1465 *matrix = object->priv->matrix;
1469 /****************************************************************************/
1470 /* Bring label object to front/top. */
1471 /****************************************************************************/
1473 gl_label_object_raise_to_top (glLabelObject *object)
1477 gl_debug (DEBUG_LABEL, "START");
1479 label = object->parent;
1481 gl_label_raise_object_to_top (label, object);
1483 g_signal_emit (G_OBJECT(object), signals[TOP], 0);
1485 gl_debug (DEBUG_LABEL, "END");
1489 /****************************************************************************/
1490 /* Send label object to rear/bottom. */
1491 /****************************************************************************/
1493 gl_label_object_lower_to_bottom (glLabelObject *object)
1497 gl_debug (DEBUG_LABEL, "START");
1499 label = object->parent;
1501 gl_label_lower_object_to_bottom (label, object);
1503 g_signal_emit (G_OBJECT(object), signals[BOTTOM], 0);
1505 gl_debug (DEBUG_LABEL, "END");
1509 /*--------------------------------------------------------------------------*/
1510 /* PRIVATE. Label's merge data changed callback. */
1511 /*--------------------------------------------------------------------------*/
1513 merge_changed_cb (glLabel *label,
1514 glLabelObject *object)
1516 gl_label_object_emit_changed (object);
1520 /*****************************************************************************/
1522 /*****************************************************************************/
1524 gl_label_object_draw (glLabelObject *object,
1526 gboolean screen_flag,
1527 glMergeRecord *record)
1531 cairo_matrix_t matrix;
1532 gboolean shadow_state;
1533 gdouble shadow_x, shadow_y;
1535 gl_debug (DEBUG_LABEL, "START");
1537 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
1539 gl_label_object_get_position (object, &x0, &y0);
1540 gl_label_object_get_matrix (object, &matrix);
1543 cairo_translate (cr, x0, y0);
1545 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow != NULL ) {
1547 shadow_state = gl_label_object_get_shadow_state (object);
1551 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1554 cairo_translate (cr, shadow_x, shadow_y);
1555 cairo_transform (cr, &matrix);
1557 GL_LABEL_OBJECT_GET_CLASS(object)->draw_shadow (object,
1566 if ( GL_LABEL_OBJECT_GET_CLASS(object)->draw_object != NULL ) {
1569 cairo_transform (cr, &matrix);
1571 GL_LABEL_OBJECT_GET_CLASS(object)->draw_object (object,
1581 gl_debug (DEBUG_LABEL, "END");
1588 * Local Variables: -- emacs
1590 * c-basic-offset: 8 -- emacs
1591 * tab-width: 8 -- emacs
1592 * indent-tabs-mode: nil -- emacs