]> git.sur5r.net Git - glabels/blob - glabels2/src/wdgt-mini-preview.c
2007-09-27 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / wdgt-mini-preview.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  *  wdgt_mini_preview.c:  mini preview widget module
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 #include <config.h>
26
27 #include "wdgt-mini-preview.h"
28
29 #include <math.h>
30
31 #include "cairo-label-path.h"
32 #include "marshal.h"
33 #include "color.h"
34
35 #include "debug.h"
36
37 /*===========================================*/
38 /* Private macros and constants.             */
39 /*===========================================*/
40
41 #define PAPER_RGB_ARGS          1.0,   1.0,   1.0
42 #define PAPER_OUTLINE_RGB_ARGS  0.0,   0.0,   0.0
43 #define LABEL_OUTLINE_RGB_ARGS  0.5,   0.5,   0.5
44
45 #define SHADOW_X_OFFSET 5
46 #define SHADOW_Y_OFFSET 5
47
48 /*===========================================*/
49 /* Private types                             */
50 /*===========================================*/
51
52 enum {
53         CLICKED,
54         PRESSED,
55         LAST_SIGNAL
56 };
57
58 typedef struct {
59         gdouble x;
60         gdouble y;
61 } LabelCenter;
62
63 struct _glWdgtMiniPreviewPrivate {
64
65         gint            height;
66         gint            width;
67
68         lglTemplate    *template;
69         gdouble         scale;
70         gdouble         offset_x;
71         gdouble         offset_y;
72         gint            labels_per_sheet;
73         LabelCenter    *centers;
74
75         gint            highlight_first;
76         gint            highlight_last;
77
78         gboolean        dragging;
79         gint            first_i;
80         gint            last_i;
81         gint            prev_i;
82 };
83
84 /*===========================================*/
85 /* Private globals                           */
86 /*===========================================*/
87
88 static gint wdgt_mini_preview_signals[LAST_SIGNAL] = { 0 };
89
90 /*===========================================*/
91 /* Local function prototypes                 */
92 /*===========================================*/
93
94 static void gl_wdgt_mini_preview_finalize      (GObject                *object);
95
96 static void gl_wdgt_mini_preview_construct     (glWdgtMiniPreview      *preview,
97                                                 gint                    height,
98                                                 gint                    width);
99
100 static gboolean expose_event_cb                (GtkWidget              *widget,
101                                                 GdkEventExpose         *event);
102 static void style_set_cb                       (GtkWidget              *widget,
103                                                 GtkStyle               *previous_style);
104 static gboolean button_press_event_cb          (GtkWidget              *widget,
105                                                 GdkEventButton         *event);
106 static gboolean motion_notify_event_cb         (GtkWidget              *widget,
107                                                 GdkEventMotion         *event);
108 static gboolean button_release_event_cb        (GtkWidget              *widget,
109                                                 GdkEventButton         *event);
110
111
112 static void redraw                             (GtkWidget              *widget);
113 static void draw                               (glWdgtMiniPreview      *preview,
114                                                 cairo_t                *cr);
115
116 static void draw_shadow                        (glWdgtMiniPreview      *preview,
117                                                 cairo_t                *cr,
118                                                 gdouble                      x,
119                                                 gdouble                 y,
120                                                 gdouble                 width,
121                                                 gdouble                 height);
122 static void draw_paper                         (glWdgtMiniPreview      *preview,
123                                                 cairo_t                *cr,
124                                                 gdouble                 width,
125                                                 gdouble                 height,
126                                                 gdouble                 line_width);
127 static void draw_labels                        (glWdgtMiniPreview      *preview,
128                                                 cairo_t                *cr,
129                                                 lglTemplate            *template,
130                                                 gdouble                 line_width);
131
132 static gint find_closest_label                 (glWdgtMiniPreview      *preview,
133                                                 gdouble                 x,
134                                                 gdouble                 y);
135
136
137 \f
138 /****************************************************************************/
139 /* Boilerplate Object stuff.                                                */
140 /****************************************************************************/
141 G_DEFINE_TYPE (glWdgtMiniPreview, gl_wdgt_mini_preview, GTK_TYPE_DRAWING_AREA);
142
143
144 static void
145 gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass *class)
146 {
147         GObjectClass   *object_class = G_OBJECT_CLASS (class);
148         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
149
150         gl_debug (DEBUG_MINI_PREVIEW, "START");
151
152         gl_wdgt_mini_preview_parent_class = gtk_type_class (gtk_hbox_get_type ());
153
154         object_class->finalize = gl_wdgt_mini_preview_finalize;
155
156         widget_class->expose_event         = expose_event_cb;
157         widget_class->style_set            = style_set_cb;
158         widget_class->button_press_event   = button_press_event_cb;
159         widget_class->motion_notify_event  = motion_notify_event_cb;
160         widget_class->button_release_event = button_release_event_cb;
161
162         wdgt_mini_preview_signals[CLICKED] =
163             g_signal_new ("clicked",
164                           G_OBJECT_CLASS_TYPE(object_class),
165                           G_SIGNAL_RUN_LAST,
166                           G_STRUCT_OFFSET (glWdgtMiniPreviewClass, clicked),
167                           NULL, NULL,
168                           gl_marshal_VOID__INT,
169                           G_TYPE_NONE, 1, G_TYPE_INT);
170
171         wdgt_mini_preview_signals[PRESSED] =
172             g_signal_new ("pressed",
173                           G_OBJECT_CLASS_TYPE(object_class),
174                           G_SIGNAL_RUN_LAST,
175                           G_STRUCT_OFFSET (glWdgtMiniPreviewClass, pressed),
176                           NULL, NULL,
177                           gl_marshal_VOID__INT_INT,
178                           G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
179
180         gl_debug (DEBUG_MINI_PREVIEW, "END");
181 }
182
183 static void
184 gl_wdgt_mini_preview_init (glWdgtMiniPreview *preview)
185 {
186         gl_debug (DEBUG_MINI_PREVIEW, "START");
187
188         preview->priv = g_new0 (glWdgtMiniPreviewPrivate, 1);
189
190         gtk_widget_add_events (GTK_WIDGET (preview),
191                                GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
192                                GDK_POINTER_MOTION_MASK);
193
194         gl_debug (DEBUG_MINI_PREVIEW, "END");
195 }
196
197 static void
198 gl_wdgt_mini_preview_finalize (GObject *object)
199 {
200         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (object);
201
202         gl_debug (DEBUG_MINI_PREVIEW, "START");
203
204         g_return_if_fail (object != NULL);
205         g_return_if_fail (GL_IS_WDGT_MINI_PREVIEW (object));
206
207         lgl_template_free (preview->priv->template);
208         g_free (preview->priv->centers);
209         g_free (preview->priv);
210
211         G_OBJECT_CLASS (gl_wdgt_mini_preview_parent_class)->finalize (object);
212
213         gl_debug (DEBUG_MINI_PREVIEW, "END");
214 }
215
216 GtkWidget *
217 gl_wdgt_mini_preview_new (gint height,
218                           gint width)
219 {
220         glWdgtMiniPreview *preview;
221
222         gl_debug (DEBUG_MINI_PREVIEW, "START");
223
224         preview = g_object_new (gl_wdgt_mini_preview_get_type (), NULL);
225
226         gl_wdgt_mini_preview_construct (preview, height, width);
227
228         gl_debug (DEBUG_MINI_PREVIEW, "END");
229
230         return GTK_WIDGET (preview);
231 }
232
233 /*--------------------------------------------------------------------------*/
234 /* Construct composite widget.                                              */
235 /*--------------------------------------------------------------------------*/
236 static void
237 gl_wdgt_mini_preview_construct (glWdgtMiniPreview *preview,
238                                 gint               height,
239                                 gint               width)
240 {
241         gl_debug (DEBUG_MINI_PREVIEW, "START");
242
243         preview->priv->height = height;
244         preview->priv->width  = width;
245
246         gtk_widget_set_size_request (GTK_WIDGET (preview), width, height);
247
248         gl_debug (DEBUG_MINI_PREVIEW, "END");
249 }
250
251 /****************************************************************************/
252 /* Set label for mini-preview to determine geometry.                        */
253 /****************************************************************************/
254 void gl_wdgt_mini_preview_set_label_by_name (glWdgtMiniPreview *preview,
255                                              const gchar       *name)
256 {
257         lglTemplate *template;
258
259         gl_debug (DEBUG_MINI_PREVIEW, "START");
260
261         /* Fetch template */
262         template = lgl_template_from_name (name);
263
264         gl_wdgt_mini_preview_set_template (preview, template);
265
266         lgl_template_free (template);
267
268         gl_debug (DEBUG_MINI_PREVIEW, "END");
269 }
270
271 /****************************************************************************/
272 /* Set label for mini-preview to determine geometry.                        */
273 /****************************************************************************/
274 void gl_wdgt_mini_preview_set_template (glWdgtMiniPreview *preview,
275                                         const lglTemplate *template)
276 {
277         const lglTemplateFrame    *frame;
278         lglTemplateOrigin         *origins;
279         gdouble                    w, h;
280         gint                       i;
281
282         gl_debug (DEBUG_MINI_PREVIEW, "START");
283
284         frame = lgl_template_get_first_frame (template);
285
286         /*
287          * Set template
288          */
289         lgl_template_free (preview->priv->template);
290         preview->priv->template = lgl_template_dup (template);
291
292         /*
293          * Set scale and offsets
294          */
295         w = preview->priv->width - 4 - 2*SHADOW_X_OFFSET;
296         h = preview->priv->height - 4 - 2*SHADOW_Y_OFFSET;
297         if ( (w/template->page_width) > (h/template->page_height) ) {
298                 preview->priv->scale = h / template->page_height;
299         } else {
300                 preview->priv->scale = w / template->page_width;
301         }
302         preview->priv->offset_x = (preview->priv->width/preview->priv->scale - template->page_width) / 2.0;
303         preview->priv->offset_y = (preview->priv->height/preview->priv->scale - template->page_height) / 2.0;
304
305         /*
306          * Set labels per sheet
307          */
308         preview->priv->labels_per_sheet = lgl_template_frame_get_n_labels (frame);
309
310         /*
311          * Initialize centers
312          */
313         g_free (preview->priv->centers);
314         preview->priv->centers = g_new0 (LabelCenter, preview->priv->labels_per_sheet);
315         origins = lgl_template_frame_get_origins (frame);
316         lgl_template_frame_get_size (frame, &w, &h);
317         for ( i=0; i<preview->priv->labels_per_sheet; i++ )
318         {
319                 preview->priv->centers[i].x = origins[i].x + w/2.0;
320                 preview->priv->centers[i].y = origins[i].y + h/2.0;
321         }
322         g_free (origins);
323
324         /*
325          * Redraw modified preview
326          */
327         redraw( GTK_WIDGET (preview));
328
329         gl_debug (DEBUG_MINI_PREVIEW, "END");
330 }
331
332 /****************************************************************************/
333 /* Highlight given label outlines.                                          */
334 /****************************************************************************/
335 void
336 gl_wdgt_mini_preview_highlight_range (glWdgtMiniPreview *preview,
337                                       gint               first_label,
338                                       gint               last_label)
339 {
340         gl_debug (DEBUG_MINI_PREVIEW, "START");
341
342         preview->priv->highlight_first = first_label;
343         preview->priv->highlight_last =  last_label;
344
345         redraw( GTK_WIDGET (preview));
346
347         gl_debug (DEBUG_MINI_PREVIEW, "END");
348 }
349
350
351 /*--------------------------------------------------------------------------*/
352 /* Expose event handler.                                                    */
353 /*--------------------------------------------------------------------------*/
354 static gboolean
355 expose_event_cb (GtkWidget       *widget,
356                  GdkEventExpose  *event)
357 {
358         cairo_t *cr;
359
360         gl_debug (DEBUG_MINI_PREVIEW, "START");
361
362         cr = gdk_cairo_create (widget->window);
363
364         cairo_rectangle (cr,
365                         event->area.x, event->area.y,
366                         event->area.width, event->area.height);
367         cairo_clip (cr);
368         
369         draw (GL_WDGT_MINI_PREVIEW (widget), cr);
370
371         cairo_destroy (cr);
372
373         gl_debug (DEBUG_MINI_PREVIEW, "END");
374         return FALSE;
375 }
376
377 /*--------------------------------------------------------------------------*/
378 /* Button press event handler                                               */
379 /*--------------------------------------------------------------------------*/
380 static gboolean
381 button_press_event_cb (GtkWidget      *widget,
382                        GdkEventButton *event)
383 {
384         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (widget);
385         cairo_t           *cr;
386         gdouble            x, y;
387         gint               i;
388
389         gl_debug (DEBUG_MINI_PREVIEW, "START");
390
391         if ( event->button == 1 )
392         {
393                 cr = gdk_cairo_create (widget->window);
394
395                 /* Set transformation. */
396                 cairo_identity_matrix (cr);
397                 cairo_scale (cr, preview->priv->scale, preview->priv->scale);
398                 cairo_translate (cr, preview->priv->offset_x, preview->priv->offset_y);
399
400                 x = event->x;
401                 y = event->y;
402                 cairo_device_to_user (cr, &x, &y);
403
404                 i = find_closest_label (preview, x, y);
405
406                 g_signal_emit (G_OBJECT(preview),
407                                wdgt_mini_preview_signals[CLICKED],
408                                0, i);
409
410                 preview->priv->first_i = i;
411                 preview->priv->last_i  = i;
412                 g_signal_emit (G_OBJECT(preview),
413                                wdgt_mini_preview_signals[PRESSED],
414                                0, preview->priv->first_i, preview->priv->last_i);
415
416                 preview->priv->dragging = TRUE;
417                 preview->priv->prev_i   = i;
418
419                 cairo_destroy (cr);
420         }
421
422         gl_debug (DEBUG_MINI_PREVIEW, "END");
423         return FALSE;
424 }
425
426 /*--------------------------------------------------------------------------*/
427 /* Motion notify event handler                                              */
428 /*--------------------------------------------------------------------------*/
429 static gboolean
430 motion_notify_event_cb (GtkWidget      *widget,
431                         GdkEventMotion *event)
432 {
433         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (widget);
434         cairo_t           *cr;
435         gdouble            x, y;
436         gint               i;
437
438         gl_debug (DEBUG_MINI_PREVIEW, "START");
439
440         if (preview->priv->dragging)
441         {
442                 cr = gdk_cairo_create (widget->window);
443
444                 /* Set transformation. */
445                 cairo_identity_matrix (cr);
446                 cairo_scale (cr, preview->priv->scale, preview->priv->scale);
447                 cairo_translate (cr, preview->priv->offset_x, preview->priv->offset_y);
448
449                 x = event->x;
450                 y = event->y;
451                 cairo_device_to_user (cr, &x, &y);
452
453                 i = find_closest_label (preview, x, y);
454
455                 if ( i != preview->priv->prev_i )
456                 {
457                         preview->priv->last_i = i;
458
459                         g_signal_emit (G_OBJECT(preview),
460                                        wdgt_mini_preview_signals[PRESSED],
461                                        0,
462                                        MIN (preview->priv->first_i, preview->priv->last_i),
463                                        MAX (preview->priv->first_i, preview->priv->last_i));
464
465                         preview->priv->prev_i = i;
466                 }
467                 cairo_destroy (cr);
468         }
469
470         gl_debug (DEBUG_MINI_PREVIEW, "END");
471         return FALSE;
472 }
473
474 /*--------------------------------------------------------------------------*/
475 /* Button release event handler                                             */
476 /*--------------------------------------------------------------------------*/
477 static gboolean
478 button_release_event_cb (GtkWidget      *widget,
479                          GdkEventButton *event)
480 {
481         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (widget);
482         
483         gl_debug (DEBUG_MINI_PREVIEW, "START");
484
485         if ( event->button == 1 )
486         {
487                 preview->priv->dragging = FALSE;
488
489         }
490
491         gl_debug (DEBUG_MINI_PREVIEW, "END");
492         return FALSE;
493 }
494
495 /*--------------------------------------------------------------------------*/
496 /* Style set handler (updates colors when style/theme changes).             */
497 /*--------------------------------------------------------------------------*/
498 static void
499 style_set_cb (GtkWidget        *widget,
500               GtkStyle         *previous_style)
501 {
502         gl_debug (DEBUG_MINI_PREVIEW, "START");
503
504         redraw( widget );
505
506         gl_debug (DEBUG_MINI_PREVIEW, "END");
507 }
508
509 /*--------------------------------------------------------------------------*/
510 /* Redraw.                                                                  */
511 /*--------------------------------------------------------------------------*/
512 static void
513 redraw (GtkWidget *widget)
514 {
515         GdkRegion *region;
516         
517         gl_debug (DEBUG_MINI_PREVIEW, "START");
518
519         if (widget->window)
520         {
521
522                 region = gdk_drawable_get_clip_region (widget->window);
523
524                 gdk_window_invalidate_region (widget->window, region, TRUE);
525                 gdk_window_process_updates (widget->window, TRUE);
526
527                 gdk_region_destroy (region);
528         }
529
530         gl_debug (DEBUG_MINI_PREVIEW, "END");
531 }
532
533 /*--------------------------------------------------------------------------*/
534 /* Find index+1 of label closest to given coordinates.                      */
535 /*--------------------------------------------------------------------------*/
536 static gint
537 find_closest_label (glWdgtMiniPreview      *preview,
538                     gdouble                 x,
539                     gdouble                 y)
540 {
541         gint    i;
542         gint    min_i;
543         gdouble dx, dy, d2, min_d2;
544
545         dx = x - preview->priv->centers[0].x;
546         dy = y - preview->priv->centers[0].y;
547         min_d2 = dx*dx + dy*dy;
548         min_i = 0;
549
550         for ( i=1; i<preview->priv->labels_per_sheet; i++ )
551         {
552                 dx = x - preview->priv->centers[i].x;
553                 dy = y - preview->priv->centers[i].y;
554                 d2 = dx*dx + dy*dy;
555
556                 if ( d2 < min_d2 )
557                 {
558                         min_d2 = d2;
559                         min_i  = i;
560                 }
561         }
562
563         return min_i + 1;
564 }
565
566 /*--------------------------------------------------------------------------*/
567 /* Draw mini preview.                                                       */
568 /*--------------------------------------------------------------------------*/
569 static void
570 draw (glWdgtMiniPreview  *preview,
571       cairo_t            *cr)
572 {
573         lglTemplate *template = preview->priv->template;
574         gdouble      shadow_x, shadow_y;
575
576         gl_debug (DEBUG_MINI_PREVIEW, "START");
577
578         if (template)
579         {
580
581                 /* Set transformation. */
582                 cairo_identity_matrix (cr);
583                 cairo_scale (cr, preview->priv->scale, preview->priv->scale);
584                 cairo_translate (cr, preview->priv->offset_x, preview->priv->offset_y);
585
586
587                 /* update shadow */
588                 shadow_x = SHADOW_X_OFFSET/preview->priv->scale;
589                 shadow_y = SHADOW_Y_OFFSET/preview->priv->scale;
590
591                 draw_shadow (preview, cr,
592                              shadow_x, shadow_y,
593                              template->page_width, template->page_height);
594
595                 draw_paper (preview, cr,
596                             template->page_width, template->page_height,
597                             1.0/preview->priv->scale);
598
599                 draw_labels (preview, cr, template, 1.0/preview->priv->scale);
600                              
601         }
602
603         gl_debug (DEBUG_MINI_PREVIEW, "END");
604
605 }
606
607
608 /*--------------------------------------------------------------------------*/
609 /* Draw page shadow                                                         */
610 /*--------------------------------------------------------------------------*/
611 static void
612 draw_shadow (glWdgtMiniPreview      *preview,
613              cairo_t                *cr,
614              gdouble                 x,
615              gdouble                 y,
616              gdouble                 width,
617              gdouble                 height)
618 {
619         GtkStyle *style;
620         guint     shadow_color;
621
622         gl_debug (DEBUG_MINI_PREVIEW, "START");
623
624         cairo_save (cr);
625
626         cairo_rectangle (cr, x, y, width, height);
627
628         style = gtk_widget_get_style (GTK_WIDGET(preview));
629         shadow_color = gl_color_from_gdk_color (&style->bg[GTK_STATE_ACTIVE]);
630         cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (shadow_color));
631
632         cairo_fill (cr);
633
634         cairo_restore (cr);
635
636         gl_debug (DEBUG_MINI_PREVIEW, "END");
637 }
638
639 /*--------------------------------------------------------------------------*/
640 /* Draw page                                                                */
641 /*--------------------------------------------------------------------------*/
642 static void
643 draw_paper (glWdgtMiniPreview      *preview,
644             cairo_t                *cr,
645             gdouble                 width,
646             gdouble                 height,
647             gdouble                 line_width)
648 {
649         cairo_save (cr);
650
651         gl_debug (DEBUG_MINI_PREVIEW, "START");
652
653         cairo_rectangle (cr, 0.0, 0.0, width, height);
654
655         cairo_set_source_rgb (cr, PAPER_RGB_ARGS);
656         cairo_fill_preserve (cr);
657
658         cairo_set_source_rgb (cr, PAPER_OUTLINE_RGB_ARGS);
659         cairo_set_line_width (cr, line_width);
660         cairo_stroke (cr);
661
662         cairo_restore (cr);
663
664         gl_debug (DEBUG_MINI_PREVIEW, "END");
665 }
666
667 /*--------------------------------------------------------------------------*/
668 /* Draw labels                                                              */
669 /*--------------------------------------------------------------------------*/
670 static void
671 draw_labels (glWdgtMiniPreview *preview,
672              cairo_t           *cr,
673              lglTemplate       *template,
674              gdouble            line_width)
675 {
676         const lglTemplateFrame    *frame;
677         gint                       i, n_labels;
678         lglTemplateOrigin         *origins;
679         GtkStyle                  *style;
680         guint                      highlight_color;
681
682         gl_debug (DEBUG_MINI_PREVIEW, "START");
683
684         frame = lgl_template_get_first_frame (template);
685
686         n_labels = lgl_template_frame_get_n_labels (frame);
687         origins  = lgl_template_frame_get_origins (frame);
688
689         style = gtk_widget_get_style (GTK_WIDGET(preview));
690         highlight_color = gl_color_from_gdk_color (&style->base[GTK_STATE_SELECTED]);
691
692         for ( i=0; i < n_labels; i++ ) {
693
694                 cairo_save (cr);
695
696                 cairo_translate (cr, origins[i].x, origins[i].y);
697                 gl_cairo_label_path (cr, template, FALSE, FALSE);
698
699                 if ( ((i+1) >= preview->priv->highlight_first) &&
700                      ((i+1) <= preview->priv->highlight_last) )
701                 {
702                         cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (highlight_color));
703                 }
704                 else
705                 {
706                         cairo_set_source_rgb (cr, PAPER_RGB_ARGS);
707                 }
708                 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
709                 cairo_fill_preserve (cr);
710
711                 cairo_set_line_width (cr, line_width);
712                 cairo_set_source_rgb (cr, LABEL_OUTLINE_RGB_ARGS);
713                 cairo_stroke (cr);
714
715                 cairo_restore (cr);
716
717         }
718
719         g_free (origins);
720
721         gl_debug (DEBUG_MINI_PREVIEW, "END");
722 }
723