]> git.sur5r.net Git - glabels/blob - src/view-object.c
Imported Upstream version 2.2.8
[glabels] / src / view-object.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  view_object.c:  GLabels label object base class
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24
25
26 #include "view-object.h"
27
28 #include <glib.h>
29
30 #include "debug.h"
31
32 /*========================================================*/
33 /* Private constants and macros.                          */
34 /*========================================================*/
35
36 #define HANDLE_FILL_RGBA_ARGS      0.0,   0.75,  0.0,   0.4
37 #define HANDLE_OUTLINE_RGBA_ARGS   0.0,   0.0,   0.0,   0.8
38
39 #define HANDLE_OUTLINE_WIDTH_PIXELS   1.0
40 #define HANDLE_PIXELS 7
41
42 /*========================================================*/
43 /* Private types.                                         */
44 /*========================================================*/
45
46 struct _glViewObjectPrivate {
47
48         glLabelObject              *object;
49
50         glView                     *view;
51         glViewObjectHandlesStyle    handles_style;
52
53         GtkWidget                  *property_editor;
54 };
55
56 /*========================================================*/
57 /* Private globals.                                       */
58 /*========================================================*/
59
60
61 /*========================================================*/
62 /* Private function prototypes.                           */
63 /*========================================================*/
64
65 static void     gl_view_object_finalize      (GObject             *object);
66
67 static void     object_removed_cb            (glViewObject        *view_object,
68                                               glLabelObject       *object);
69
70 static void     object_top_cb                (glViewObject        *view_object,
71                                               glLabelObject       *object);
72
73 static void     object_bottom_cb             (glViewObject        *view_object,
74                                               glLabelObject       *object);
75
76
77
78
79
80 \f
81 /*****************************************************************************/
82 /* Boilerplate object stuff.                                                 */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glViewObject, gl_view_object, G_TYPE_OBJECT);
85
86 static void
87 gl_view_object_class_init (glViewObjectClass *class)
88 {
89         GObjectClass *object_class = G_OBJECT_CLASS (class);
90
91         gl_debug (DEBUG_VIEW, "START");
92
93         gl_view_object_parent_class = g_type_class_peek_parent (class);
94
95         object_class->finalize = gl_view_object_finalize;
96
97         gl_debug (DEBUG_VIEW, "END");
98 }
99
100 static void
101 gl_view_object_init (glViewObject *view_object)
102 {
103         gl_debug (DEBUG_VIEW, "START");
104
105         view_object->priv = g_new0 (glViewObjectPrivate, 1);
106
107         gl_debug (DEBUG_VIEW, "END");
108 }
109
110 static void
111 gl_view_object_finalize (GObject *object)
112 {
113         glViewObject  *view_object = GL_VIEW_OBJECT (object);
114         glView        *view;
115
116         gl_debug (DEBUG_VIEW, "START");
117
118         g_return_if_fail (object && GL_IS_VIEW_OBJECT (object));
119
120         view = view_object->priv->view;
121         view->object_list = g_list_remove (view->object_list, object);
122         view->selected_object_list =
123                 g_list_remove (view->selected_object_list, object);
124
125         g_object_unref (view_object->priv->object);
126         if (view_object->priv->property_editor) {
127                 gl_debug (DEBUG_VIEW, "Destroy editor");
128                 g_object_unref (G_OBJECT(view_object->priv->property_editor));
129         }
130         g_free (view_object->priv);
131
132         G_OBJECT_CLASS (gl_view_object_parent_class)->finalize (object);
133
134         gl_debug (DEBUG_VIEW, "END");
135 }
136
137 /*****************************************************************************/
138 /* NEW object view.                                                          */
139 /*****************************************************************************/
140 GObject *
141 gl_view_object_new (void)
142 {
143         glViewObject *view_object;
144
145         gl_debug (DEBUG_VIEW, "START");
146
147         view_object = g_object_new (gl_view_object_get_type(), NULL);
148
149         gl_debug (DEBUG_VIEW, "END");
150
151         return G_OBJECT (view_object);
152 }
153
154 /*****************************************************************************/
155 /* Set parent view to which this object view belongs.                        */
156 /*****************************************************************************/
157 void
158 gl_view_object_set_view       (glViewObject *view_object,
159                                glView *view)
160 {
161         gl_debug (DEBUG_VIEW, "START");
162
163         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
164         g_return_if_fail (view && GL_IS_VIEW (view));
165         
166         view_object->priv->view = view;
167
168         view->object_list = g_list_append (view->object_list, view_object);
169
170         g_signal_connect_swapped (G_OBJECT (view_object->priv->object), "changed",
171                                   G_CALLBACK (gl_view_update), view);
172         g_signal_connect_swapped (G_OBJECT (view_object->priv->object), "moved",
173                                   G_CALLBACK (gl_view_update), view);
174
175         gl_debug (DEBUG_VIEW, "END");
176 }
177
178 /*****************************************************************************/
179 /* Set Label object to follow.                                               */
180 /*****************************************************************************/
181 void
182 gl_view_object_set_object     (glViewObject            *view_object,
183                                glLabelObject           *object,
184                                glViewObjectHandlesStyle style)
185 {
186         gl_debug (DEBUG_VIEW, "START");
187
188         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
189         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
190         
191         view_object->priv->object = g_object_ref (G_OBJECT (object));
192         view_object->priv->handles_style = style;
193
194         g_signal_connect_swapped (G_OBJECT (object), "removed",
195                                   G_CALLBACK (object_removed_cb), view_object);
196         g_signal_connect_swapped (G_OBJECT (object), "top",
197                                   G_CALLBACK (object_top_cb), view_object);
198         g_signal_connect_swapped (G_OBJECT (object), "bottom",
199                                   G_CALLBACK (object_bottom_cb), view_object);
200
201         gl_debug (DEBUG_VIEW, "END");
202 }
203
204 /*---------------------------------------------------------------------------*/
205 /* PRIVATE.  Handle object "removed" signal.                                 */
206 /*---------------------------------------------------------------------------*/
207 static void
208 object_removed_cb (glViewObject  *view_object,
209                    glLabelObject *object)
210 {
211         glView *view;
212         gl_debug (DEBUG_VIEW, "START");
213
214         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
215         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
216
217         view = gl_view_object_get_view (view_object);
218         view->object_list = g_list_remove (view->object_list, view_object);
219         g_object_unref (G_OBJECT (view_object));
220
221         gl_debug (DEBUG_VIEW, "END");
222 }
223
224 /*---------------------------------------------------------------------------*/
225 /* PRIVATE. Handle object "top" signal.                                      */
226 /*---------------------------------------------------------------------------*/
227 static void
228 object_top_cb (glViewObject  *view_object,
229                glLabelObject *object)
230 {
231         glView *view;
232         gl_debug (DEBUG_VIEW, "START");
233
234         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
235         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
236
237         view = gl_view_object_get_view (view_object);
238
239         /* Move to end of list, representing front most object */
240         view->object_list = g_list_remove (view->object_list, view_object);
241         view->object_list = g_list_append (view->object_list, view_object);
242
243         gl_debug (DEBUG_VIEW, "END");
244 }
245
246 /*---------------------------------------------------------------------------*/
247 /* PRIVATE. Handle object "removed" signal.                                  */
248 /*---------------------------------------------------------------------------*/
249 static void
250 object_bottom_cb (glViewObject  *view_object,
251                   glLabelObject *object)
252 {
253         glView *view;
254         gl_debug (DEBUG_VIEW, "START");
255
256         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
257         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
258
259         view = gl_view_object_get_view (view_object);
260
261         /* Move to front of list, representing rear most object */
262         view->object_list = g_list_remove (view->object_list, view_object);
263         view->object_list = g_list_prepend (view->object_list, view_object);
264
265         gl_debug (DEBUG_VIEW, "END");
266 }
267
268 /*****************************************************************************/
269 /* Return parent view associated with this view.                             */
270 /*****************************************************************************/
271 glView *
272 gl_view_object_get_view   (glViewObject *view_object)
273 {
274         gl_debug (DEBUG_VIEW, "START");
275
276         g_return_val_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object), NULL);
277
278         gl_debug (DEBUG_VIEW, "END");
279
280         return view_object->priv->view;
281 }
282
283 /*****************************************************************************/
284 /* Return label object that we are following.                                */
285 /*****************************************************************************/
286 glLabelObject *
287 gl_view_object_get_object (glViewObject *view_object)
288 {
289         gl_debug (DEBUG_VIEW, "START");
290
291         g_return_val_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object), NULL);
292         
293         gl_debug (DEBUG_VIEW, "END");
294
295         return view_object->priv->object;
296 }
297
298 /*****************************************************************************/
299 /* Get property editor.                                                      */
300 /*****************************************************************************/
301 GtkWidget *
302 gl_view_object_get_editor (glViewObject *view_object)
303 {
304         gl_debug (DEBUG_VIEW, "START");
305
306         g_return_val_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object), NULL);
307
308         if ( GL_VIEW_OBJECT_GET_CLASS(view_object)->construct_editor != NULL ) {
309
310                 if (view_object->priv->property_editor == NULL) {
311                         view_object->priv->property_editor =
312                                 GL_VIEW_OBJECT_GET_CLASS(view_object)->construct_editor (view_object);
313                 }
314                 g_signal_connect (G_OBJECT (view_object->priv->property_editor),
315                                   "destroy",
316                                   G_CALLBACK (gtk_widget_destroyed),
317                                   &view_object->priv->property_editor);
318         
319                 gtk_widget_show (view_object->priv->property_editor);
320
321         }
322
323
324         gl_debug (DEBUG_VIEW, "END");
325
326         return view_object->priv->property_editor;
327 }
328
329
330 /*****************************************************************************/
331 /* Select object.                                                            */
332 /*****************************************************************************/
333 void
334 gl_view_object_select (glViewObject *view_object)
335 {
336         gl_debug (DEBUG_VIEW, "START");
337
338         gl_view_select_object(view_object->priv->view, view_object);
339
340         gl_debug (DEBUG_VIEW, "END");
341 }
342
343 /*****************************************************************************/
344 /* Is object at (x,y)?                                                       */
345 /*****************************************************************************/
346 gboolean
347 gl_view_object_at (glViewObject  *view_object,
348                    cairo_t       *cr,
349                    gdouble        x,
350                    gdouble        y)
351 {
352         glLabelObject *object = view_object->priv->object;
353         gdouble        x0, y0;
354         cairo_matrix_t matrix;
355         gboolean       return_val = FALSE;
356
357         gl_debug (DEBUG_VIEW, "START");
358
359         g_return_val_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object), FALSE);
360         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), FALSE);
361
362         gl_label_object_get_position (object, &x0, &y0);
363         gl_label_object_get_matrix (object, &matrix);
364
365         cairo_save (cr);
366         cairo_translate (cr, x0, y0);
367         cairo_transform (cr, &matrix);
368
369         cairo_device_to_user (cr, &x, &y);
370
371         if ( GL_VIEW_OBJECT_GET_CLASS(view_object)->object_at != NULL ) {
372
373                 return_val = GL_VIEW_OBJECT_GET_CLASS(view_object)->object_at (view_object, cr, x, y);
374
375         }
376
377         cairo_restore (cr);
378
379         return return_val;
380
381         gl_debug (DEBUG_VIEW, "END");
382 }
383
384
385 /*--------------------------------------------------------------------------*/
386 /* Create handle path                                                       */
387 /*--------------------------------------------------------------------------*/
388 static void
389 create_handle_path (cairo_t                *cr,
390                     glLabelObject          *object,
391                     gdouble                 scale,
392                     gdouble                 x_handle,
393                     gdouble                 y_handle)
394 {
395         gl_debug (DEBUG_VIEW, "START");
396
397         cairo_rectangle (cr,
398                          x_handle - HANDLE_PIXELS/scale/2, y_handle - HANDLE_PIXELS/scale/2,
399                          HANDLE_PIXELS/scale, HANDLE_PIXELS/scale);
400
401         gl_debug (DEBUG_VIEW, "END");
402 }
403
404 /*****************************************************************************/
405 /* Draw object handles                                                       */
406 /*****************************************************************************/
407 void
408 gl_view_object_draw_handles (glViewObject *view_object,
409                              cairo_t      *cr)
410 {
411         glLabelObject *object = view_object->priv->object;
412         gdouble        x0, y0;
413         cairo_matrix_t matrix;
414         gdouble        scale;
415         gdouble        w, h;
416
417         gl_debug (DEBUG_VIEW, "START");
418
419         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
420         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
421
422         scale = view_object->priv->view->home_scale * view_object->priv->view->zoom;
423
424         gl_label_object_get_position (object, &x0, &y0);
425         gl_label_object_get_matrix (object, &matrix);
426
427         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
428
429         cairo_save (cr);
430
431         cairo_translate (cr, x0, y0);
432         cairo_transform (cr, &matrix);
433
434         switch (view_object->priv->handles_style)
435         {
436         case GL_VIEW_OBJECT_HANDLES_BOX:
437
438                 /* North */
439                 cairo_new_path (cr);
440                 create_handle_path (cr, object, scale, w/2, 0);
441
442                 /* North East */
443                 cairo_new_sub_path (cr);
444                 create_handle_path (cr, object, scale, w, 0);
445
446                 /* East */
447                 cairo_new_sub_path (cr);
448                 create_handle_path (cr, object, scale, w, h/2);
449
450                 /* South East */
451                 cairo_new_sub_path (cr);
452                 create_handle_path (cr, object, scale, w, h);
453
454                 /* South */
455                 cairo_new_sub_path (cr);
456                 create_handle_path (cr, object, scale, w/2, h);
457
458                 /* South West */
459                 cairo_new_sub_path (cr);
460                 create_handle_path (cr, object, scale, 0, h);
461
462                 /* West */
463                 cairo_new_sub_path (cr);
464                 create_handle_path (cr, object, scale, 0, h/2);
465
466                 /* North West */
467                 cairo_new_sub_path (cr);
468                 create_handle_path (cr, object, scale, 0, 0);
469
470                 break;
471
472         case GL_VIEW_OBJECT_HANDLES_LINE:
473                 /* P1 */
474                 cairo_new_path (cr);
475                 create_handle_path (cr, object, scale, 0, 0);
476
477                 /* P2 */
478                 cairo_new_sub_path (cr);
479                 create_handle_path (cr, object, scale, w, h);
480
481                 break;
482         }
483
484         cairo_set_source_rgba (cr, HANDLE_FILL_RGBA_ARGS);
485         cairo_fill_preserve (cr);
486                                
487         cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS/scale);
488         cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
489         cairo_stroke (cr);
490
491         cairo_restore (cr);
492
493         gl_debug (DEBUG_VIEW, "END");
494 }
495
496 /*****************************************************************************/
497 /* Is there an object handle at (x,y).                                       */
498 /*****************************************************************************/
499 glViewObjectHandle
500 gl_view_object_handle_at (glViewObject *view_object,
501                           cairo_t      *cr,
502                           gdouble       x,
503                           gdouble       y)
504 {
505         glLabelObject *object = view_object->priv->object;
506         gdouble        x0, y0;
507         cairo_matrix_t matrix;
508         gdouble        scale;
509         gdouble        w, h;
510         glViewObjectHandle handle = GL_VIEW_OBJECT_HANDLE_NONE;
511
512         gl_debug (DEBUG_VIEW, "START");
513
514         g_return_val_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object), handle);
515         g_return_val_if_fail (object && GL_IS_LABEL_OBJECT (object), handle);
516
517         scale = view_object->priv->view->home_scale * view_object->priv->view->zoom;
518
519         gl_label_object_get_position (object, &x0, &y0);
520         gl_label_object_get_matrix (object, &matrix);
521
522         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
523
524         cairo_save (cr);
525
526         cairo_translate (cr, x0, y0);
527         cairo_transform (cr, &matrix);
528
529         cairo_device_to_user (cr, &x, &y);
530
531         switch (view_object->priv->handles_style)
532         {
533         case GL_VIEW_OBJECT_HANDLES_BOX:
534
535                 /* South East */
536                 create_handle_path (cr, object, scale, w, h);
537                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_SE; break;}
538
539                 /* South West */
540                 create_handle_path (cr, object, scale, 0, h);
541                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_SW; break;}
542
543                 /* North East */
544                 create_handle_path (cr, object, scale, w, 0);
545                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_NE; break;}
546
547                 /* North West */
548                 create_handle_path (cr, object, scale, 0, 0);
549                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_NW; break;}
550
551                 /* East */
552                 create_handle_path (cr, object, scale, w, h/2);
553                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_E; break;}
554
555                 /* South */
556                 create_handle_path (cr, object, scale, w/2, h);
557                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_S; break;}
558
559                 /* West */
560                 create_handle_path (cr, object, scale, 0, h/2);
561                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_W; break;}
562
563                 /* North */
564                 create_handle_path (cr, object, scale, w/2, 0);
565                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_N; break;}
566
567                 break;
568
569         case GL_VIEW_OBJECT_HANDLES_LINE:
570                 /* P2 */
571                 create_handle_path (cr, object, scale, w, h);
572                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_P2; break;}
573
574                 /* P1 */
575                 create_handle_path (cr, object, scale, 0, 0);
576                 if (cairo_in_fill (cr, x, y))   {handle = GL_VIEW_OBJECT_HANDLE_P1; break;}
577
578                 break;
579
580         }
581
582         cairo_restore (cr);
583
584         return handle;
585 }
586
587 /*---------------------------------------------------------------------------*/
588 /* PRIVATE.  Resize object.                                                  */
589 /*---------------------------------------------------------------------------*/
590 void
591 gl_view_object_resize_event (glViewObject       *view_object,
592                              glViewObjectHandle  handle,
593                              gboolean            honor_aspect,
594                              cairo_t            *cr,
595                              gdouble             x,
596                              gdouble             y)
597 {
598         glLabelObject *object;
599         cairo_matrix_t matrix;
600         gdouble        x0, y0, x1, y1, x2, y2;
601         gdouble        w, h;
602         gdouble        dx=0, dy=0;
603
604         gl_debug (DEBUG_VIEW, "x,y world = %g, %g", x, y);
605
606         object = view_object->priv->object;
607
608         /*
609          * Change to item relative coordinates
610          */
611         cairo_save (cr);
612         gl_label_object_get_position (object, &x0, &y0);
613         cairo_translate (cr, x0, y0);
614         gl_label_object_get_matrix (object, &matrix);
615         cairo_transform (cr, &matrix);
616
617         /*
618          * Initialize origin and 2 corners in object relative coordinates.
619          */
620         x0 = 0.0;
621         y0 = 0.0;
622
623         x1 = 0.0;
624         y1 = 0.0;
625
626         gl_label_object_get_size (object, &x2, &y2);
627
628         gl_debug (DEBUG_VIEW, "x0,y0 object = %g, %g", x0, y0);
629         gl_debug (DEBUG_VIEW, "x1,y1 object = %g, %g", x1, y1);
630         gl_debug (DEBUG_VIEW, "x2,y2 object = %g, %g", x2, y2);
631
632         /*
633          * Translate x,y into object relative coordinates.
634          */
635         cairo_device_to_user (cr, &x, &y);
636
637         gl_debug (DEBUG_VIEW, "x,y object = %g, %g", x, y);
638         
639         /*
640          * Get new size
641          */
642         switch (handle)
643         {
644
645         case GL_VIEW_OBJECT_HANDLE_NW:
646                 w = MAX (x2 - x, 0);
647                 h = MAX (y2 - y, 0);
648                 break;
649
650         case GL_VIEW_OBJECT_HANDLE_N:
651                 w = x2 - x1;
652                 h = MAX (y2 - y, 0);
653                 break;
654
655         case GL_VIEW_OBJECT_HANDLE_NE:
656                 w = MAX (x - x1, 0);
657                 h = MAX (y2 - y, 0);
658                 break;
659
660         case GL_VIEW_OBJECT_HANDLE_E:
661                 w = MAX (x - x1, 0);
662                 h = y2 - y1;
663                 break;
664
665         case GL_VIEW_OBJECT_HANDLE_SE:
666                 w = MAX (x - x1, 0);
667                 h = MAX (y - y1, 0);
668                 break;
669
670         case GL_VIEW_OBJECT_HANDLE_S:
671                 w = x2 - x1;
672                 h = MAX (y - y1, 0);
673                 break;
674
675         case GL_VIEW_OBJECT_HANDLE_SW:
676                 w = MAX (x2 - x, 0);
677                 h = MAX (y - y1, 0);
678                 break;
679
680         case GL_VIEW_OBJECT_HANDLE_W:
681                 w = MAX (x2 - x, 0);
682                 h = y2 - y1;
683                 break;
684         case GL_VIEW_OBJECT_HANDLE_P1:
685                 x1 = x;
686                 y1 = y;
687                 dx = (x2 - x);
688                 dy = (y2 - y);
689                 x0 = x0 + x1;
690                 y0 = y0 + y1;
691                 break;
692
693         case GL_VIEW_OBJECT_HANDLE_P2:
694                 dx = x - x1;
695                 dy = y - y1;
696                 x0 = x0 + x1;
697                 y0 = y0 + y1;
698                 break;
699
700         default:
701                 g_print ("Invalid handle.\n");  /* Should not happen! */
702
703         }
704         if ( (handle != GL_VIEW_OBJECT_HANDLE_P1) && (handle != GL_VIEW_OBJECT_HANDLE_P2) )
705         {
706                 if ( honor_aspect )
707                 {
708                         gl_label_object_set_size_honor_aspect (object, w, h);
709                 }
710                 else
711                 {
712                         gl_label_object_set_size (object, w, h);
713                 }
714
715                 /*
716                  * Query the new size in case it was constrained.
717                  */
718                 gl_label_object_get_size (object, &w, &h);
719
720                 /*
721                  * Get new position
722                  */
723                 switch (handle)
724                 {
725
726                 case GL_VIEW_OBJECT_HANDLE_NW:
727                         x0 += x2 - w;
728                         y0 += y2 - h;
729                         break;
730
731                 case GL_VIEW_OBJECT_HANDLE_N:
732                 case GL_VIEW_OBJECT_HANDLE_NE:
733                         /* x unchanged */
734                         y0 += y2 - h;
735                         break;
736
737                 case GL_VIEW_OBJECT_HANDLE_E:
738                 case GL_VIEW_OBJECT_HANDLE_SE:
739                 case GL_VIEW_OBJECT_HANDLE_S:
740                         /* unchanged */
741                         break;
742
743                 case GL_VIEW_OBJECT_HANDLE_SW:
744                 case GL_VIEW_OBJECT_HANDLE_W:
745                         x0 += x2 - w;
746                         /* y unchanged */
747                         break;
748
749                 default:
750                         g_print ("Invalid handle.\n");  /* Should not happen! */
751                 }
752         }
753         else
754         {
755                 gl_label_object_set_size (object, dx, dy);
756         }
757
758         /*
759          * Put new origin back into world coordinates and set.
760          */
761         cairo_user_to_device (cr, &x0, &y0);
762         cairo_restore (cr);
763         cairo_device_to_user (cr, &x0, &y0);
764         gl_label_object_set_position (object, x0, y0);
765 }