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 "mini-preview.h"
26 #include <glib/gi18n.h>
28 #include <libglabels.h>
29 #include "cairo-label-path.h"
37 /*===========================================*/
38 /* Private macros and constants. */
39 /*===========================================*/
42 #define SHADOW_OFFSET 3
44 #define ARROW_SCALE 0.35
45 #define UP_FONT_FAMILY "Sans"
48 /*===========================================*/
50 /*===========================================*/
64 struct _glMiniPreviewPrivate {
68 lglTemplate *template;
69 gint labels_per_sheet;
80 gboolean draw_arrow_flag;
83 gboolean update_scheduled_flag;
91 gboolean collate_flag;
92 gboolean outline_flag;
93 gboolean reverse_flag;
94 gboolean crop_marks_flag;
98 /*===========================================*/
100 /*===========================================*/
102 static gint mini_preview_signals[LAST_SIGNAL] = { 0 };
105 /*===========================================*/
106 /* Local function prototypes */
107 /*===========================================*/
109 static void gl_mini_preview_finalize (GObject *object);
111 static void gl_mini_preview_construct (glMiniPreview *this,
115 static gboolean button_press_event_cb (GtkWidget *widget,
116 GdkEventButton *event);
117 static gboolean motion_notify_event_cb (GtkWidget *widget,
118 GdkEventMotion *event);
119 static gboolean button_release_event_cb (GtkWidget *widget,
120 GdkEventButton *event);
123 static gboolean expose_event_cb (GtkWidget *widget,
124 GdkEventExpose *event,
125 glMiniPreview *this);
126 static void style_set_cb (GtkWidget *widget,
127 GtkStyle *previous_style,
128 glMiniPreview *this);
130 static void redraw (glMiniPreview *this);
131 static void draw (glMiniPreview *this,
134 static void draw_shadow (glMiniPreview *this,
140 static void draw_paper (glMiniPreview *this,
145 static void draw_labels (glMiniPreview *this,
147 lglTemplate *template,
149 static void draw_arrow (glMiniPreview *this,
152 static void draw_rich_preview (glMiniPreview *this,
156 static gint find_closest_label (glMiniPreview *this,
160 static gdouble set_transform_and_get_scale (glMiniPreview *this,
164 /****************************************************************************/
165 /* Object infrastructure. */
166 /****************************************************************************/
167 G_DEFINE_TYPE (glMiniPreview, gl_mini_preview, GTK_TYPE_EVENT_BOX);
170 /*****************************************************************************/
171 /* Class Init Function. */
172 /*****************************************************************************/
174 gl_mini_preview_class_init (glMiniPreviewClass *class)
176 GObjectClass *object_class = G_OBJECT_CLASS (class);
177 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
179 gl_debug (DEBUG_MINI_PREVIEW, "START");
181 gl_mini_preview_parent_class = g_type_class_peek_parent (class);
183 object_class->finalize = gl_mini_preview_finalize;
185 widget_class->button_press_event = button_press_event_cb;
186 widget_class->motion_notify_event = motion_notify_event_cb;
187 widget_class->button_release_event = button_release_event_cb;
189 mini_preview_signals[CLICKED] =
190 g_signal_new ("clicked",
191 G_OBJECT_CLASS_TYPE(object_class),
193 G_STRUCT_OFFSET (glMiniPreviewClass, clicked),
195 gl_marshal_VOID__INT,
196 G_TYPE_NONE, 1, G_TYPE_INT);
198 mini_preview_signals[PRESSED] =
199 g_signal_new ("pressed",
200 G_OBJECT_CLASS_TYPE(object_class),
202 G_STRUCT_OFFSET (glMiniPreviewClass, pressed),
204 gl_marshal_VOID__INT_INT,
205 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
207 mini_preview_signals[RELEASED] =
208 g_signal_new ("released",
209 G_OBJECT_CLASS_TYPE(object_class),
211 G_STRUCT_OFFSET (glMiniPreviewClass, released),
213 gl_marshal_VOID__INT_INT,
214 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
216 gl_debug (DEBUG_MINI_PREVIEW, "END");
220 /*****************************************************************************/
221 /* Object Instance Init Function. */
222 /*****************************************************************************/
224 gl_mini_preview_init (glMiniPreview *this)
226 gl_debug (DEBUG_MINI_PREVIEW, "START");
228 this->priv = g_new0 (glMiniPreviewPrivate, 1);
230 gtk_widget_add_events (GTK_WIDGET (this),
231 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
232 GDK_POINTER_MOTION_MASK);
234 gtk_event_box_set_visible_window (GTK_EVENT_BOX (this), FALSE);
236 this->priv->canvas = gtk_drawing_area_new ();
237 gtk_widget_set_has_window(this->priv->canvas, FALSE);
238 gtk_container_add (GTK_CONTAINER (this), this->priv->canvas);
240 g_signal_connect (G_OBJECT (this->priv->canvas), "expose-event",
241 G_CALLBACK (expose_event_cb), this);
242 g_signal_connect (G_OBJECT (this->priv->canvas), "style-set",
243 G_CALLBACK (style_set_cb), this);
245 gl_debug (DEBUG_MINI_PREVIEW, "END");
249 /*****************************************************************************/
250 /* Finalize Method. */
251 /*****************************************************************************/
253 gl_mini_preview_finalize (GObject *object)
255 glMiniPreview *this = GL_MINI_PREVIEW (object);
257 gl_debug (DEBUG_MINI_PREVIEW, "START");
259 g_return_if_fail (object != NULL);
260 g_return_if_fail (GL_IS_MINI_PREVIEW (object));
262 if (this->priv->label)
264 g_object_unref (this->priv->label);
266 lgl_template_free (this->priv->template);
267 g_free (this->priv->centers);
270 G_OBJECT_CLASS (gl_mini_preview_parent_class)->finalize (object);
272 gl_debug (DEBUG_MINI_PREVIEW, "END");
276 /*****************************************************************************/
277 /** New Object Generator. */
278 /*****************************************************************************/
280 gl_mini_preview_new (gint height,
285 gl_debug (DEBUG_MINI_PREVIEW, "START");
287 this = g_object_new (gl_mini_preview_get_type (), NULL);
289 gl_mini_preview_construct (this, height, width);
291 gl_debug (DEBUG_MINI_PREVIEW, "END");
293 return GTK_WIDGET (this);
297 /*--------------------------------------------------------------------------*/
298 /* Construct composite widget. */
299 /*--------------------------------------------------------------------------*/
301 gl_mini_preview_construct (glMiniPreview *this,
305 gl_debug (DEBUG_MINI_PREVIEW, "START");
307 gtk_widget_set_size_request (GTK_WIDGET (this->priv->canvas), width, height);
309 gl_debug (DEBUG_MINI_PREVIEW, "END");
313 /****************************************************************************/
314 /* Set template for mini-preview to determine geometry. */
315 /****************************************************************************/
317 gl_mini_preview_set_by_name (glMiniPreview *this,
320 lglTemplate *template;
322 gl_debug (DEBUG_MINI_PREVIEW, "START");
325 template = lgl_db_lookup_template_from_name (name);
327 gl_mini_preview_set_template (this, template);
329 lgl_template_free (template);
331 gl_debug (DEBUG_MINI_PREVIEW, "END");
335 /****************************************************************************/
336 /* Set template for mini-preview to determine geometry. */
337 /****************************************************************************/
339 gl_mini_preview_set_template (glMiniPreview *this,
340 const lglTemplate *template)
342 const lglTemplateFrame *frame;
343 lglTemplateOrigin *origins;
347 gl_debug (DEBUG_MINI_PREVIEW, "START");
349 frame = (lglTemplateFrame *)template->frames->data;
354 lgl_template_free (this->priv->template);
355 this->priv->template = lgl_template_dup (template);
358 * Set labels per sheet
360 this->priv->labels_per_sheet = lgl_template_frame_get_n_labels (frame);
365 g_free (this->priv->centers);
366 this->priv->centers = g_new0 (LabelCenter, this->priv->labels_per_sheet);
367 origins = lgl_template_frame_get_origins (frame);
368 lgl_template_frame_get_size (frame, &w, &h);
369 for ( i=0; i<this->priv->labels_per_sheet; i++ )
371 this->priv->centers[i].x = origins[i].x + w/2.0;
372 this->priv->centers[i].y = origins[i].y + h/2.0;
377 * Redraw modified preview
381 gl_debug (DEBUG_MINI_PREVIEW, "END");
385 /****************************************************************************/
386 /* Highlight given label outlines. */
387 /****************************************************************************/
389 gl_mini_preview_highlight_range (glMiniPreview *this,
393 gl_debug (DEBUG_MINI_PREVIEW, "START");
395 if ( (first_label != this->priv->highlight_first) ||
396 (last_label != this->priv->highlight_last) )
399 this->priv->highlight_first = first_label;
400 this->priv->highlight_last = last_label;
406 gl_debug (DEBUG_MINI_PREVIEW, "END");
410 /****************************************************************************/
411 /* Set draw arrow. */
412 /****************************************************************************/
414 gl_mini_preview_set_draw_arrow (glMiniPreview *this,
415 gboolean draw_arrow_flag)
417 if ( draw_arrow_flag != this->priv->draw_arrow_flag )
419 this->priv->draw_arrow_flag = draw_arrow_flag;
425 /****************************************************************************/
426 /* Set rotate flag. */
427 /****************************************************************************/
429 gl_mini_preview_set_rotate (glMiniPreview *this,
430 gboolean rotate_flag)
432 if ( rotate_flag != this->priv->rotate_flag )
434 this->priv->rotate_flag = rotate_flag;
440 /****************************************************************************/
442 /****************************************************************************/
444 gl_mini_preview_set_label (glMiniPreview *this,
447 if ( this->priv->label )
449 g_object_unref (this->priv->label);
451 this->priv->label = g_object_ref (label);
456 /****************************************************************************/
457 /* Set page number. */
458 /****************************************************************************/
460 gl_mini_preview_set_page (glMiniPreview *this,
463 if ( page != this->priv->page )
465 this->priv->page = page;
471 /****************************************************************************/
472 /* Set number of sheets. */
473 /****************************************************************************/
475 gl_mini_preview_set_n_sheets (glMiniPreview *this,
478 if ( n_sheets != this->priv->n_sheets )
480 this->priv->n_sheets = n_sheets;
486 /****************************************************************************/
487 /* Set number of copies (merge only). */
488 /****************************************************************************/
490 gl_mini_preview_set_n_copies (glMiniPreview *this,
493 if ( n_copies != this->priv->n_copies )
495 this->priv->n_copies = n_copies;
501 /****************************************************************************/
502 /* Set first label number on first sheet. */
503 /****************************************************************************/
505 gl_mini_preview_set_first (glMiniPreview *this,
508 if ( first != this->priv->first )
510 this->priv->first = first;
516 /****************************************************************************/
517 /* Set last label number on first sheet (non-merge only). */
518 /****************************************************************************/
520 gl_mini_preview_set_last (glMiniPreview *this,
523 if ( last != this->priv->last )
525 this->priv->last = last;
531 /****************************************************************************/
532 /* Set collate flag (merge only). */
533 /****************************************************************************/
535 gl_mini_preview_set_collate_flag (glMiniPreview *this,
536 gboolean collate_flag)
538 if ( collate_flag != this->priv->collate_flag )
540 this->priv->collate_flag = collate_flag;
546 /****************************************************************************/
547 /* Set outline flag. */
548 /****************************************************************************/
550 gl_mini_preview_set_outline_flag (glMiniPreview *this,
551 gboolean outline_flag)
553 if ( outline_flag != this->priv->outline_flag )
555 this->priv->outline_flag = outline_flag;
561 /****************************************************************************/
562 /* Set reverse flag. */
563 /****************************************************************************/
565 gl_mini_preview_set_reverse_flag (glMiniPreview *this,
566 gboolean reverse_flag)
568 if ( reverse_flag != this->priv->reverse_flag )
570 this->priv->reverse_flag = reverse_flag;
576 /****************************************************************************/
577 /* Set crop marks flag. */
578 /****************************************************************************/
580 gl_mini_preview_set_crop_marks_flag (glMiniPreview *this,
581 gboolean crop_marks_flag)
583 if ( crop_marks_flag != this->priv->crop_marks_flag )
585 this->priv->crop_marks_flag = crop_marks_flag;
591 /*--------------------------------------------------------------------------*/
592 /* Set transformation and return scale. */
593 /*--------------------------------------------------------------------------*/
595 set_transform_and_get_scale (glMiniPreview *this,
598 lglTemplate *template = this->priv->template;
599 GtkAllocation allocation;
602 gdouble offset_x, offset_y;
604 /* Establish scale and origin. */
605 gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
606 w = allocation.width;
607 h = allocation.height;
609 /* establish scale. */
610 scale = MIN( (w - 2*MARGIN - 2*SHADOW_OFFSET)/template->page_width,
611 (h - 2*MARGIN - 2*SHADOW_OFFSET)/template->page_height );
613 /* Find offset to center preview. */
614 offset_x = (w/scale - template->page_width) / 2.0;
615 offset_y = (h/scale - template->page_height) / 2.0;
617 /* Set transformation. */
618 cairo_scale (cr, scale, scale);
619 cairo_translate (cr, offset_x, offset_y);
625 /*--------------------------------------------------------------------------*/
626 /* Button press event handler */
627 /*--------------------------------------------------------------------------*/
629 button_press_event_cb (GtkWidget *widget,
630 GdkEventButton *event)
632 glMiniPreview *this = GL_MINI_PREVIEW (widget);
639 gl_debug (DEBUG_MINI_PREVIEW, "START");
641 if ( event->button == 1 )
644 window = gtk_widget_get_window (this->priv->canvas);
646 cr = gdk_cairo_create (window);
648 scale = set_transform_and_get_scale (this, cr);
652 cairo_device_to_user (cr, &x, &y);
654 i = find_closest_label (this, x, y);
656 g_signal_emit (G_OBJECT(this),
657 mini_preview_signals[CLICKED],
660 this->priv->first_i = i;
661 this->priv->last_i = i;
662 g_signal_emit (G_OBJECT(this),
663 mini_preview_signals[PRESSED],
664 0, this->priv->first_i, this->priv->last_i);
666 this->priv->dragging = TRUE;
667 this->priv->prev_i = i;
672 gl_debug (DEBUG_MINI_PREVIEW, "END");
677 /*--------------------------------------------------------------------------*/
678 /* Motion notify event handler */
679 /*--------------------------------------------------------------------------*/
681 motion_notify_event_cb (GtkWidget *widget,
682 GdkEventMotion *event)
684 glMiniPreview *this = GL_MINI_PREVIEW (widget);
691 gl_debug (DEBUG_MINI_PREVIEW, "START");
693 if (this->priv->dragging)
695 window = gtk_widget_get_window (this->priv->canvas);
697 cr = gdk_cairo_create (window);
699 scale = set_transform_and_get_scale (this, cr);
703 cairo_device_to_user (cr, &x, &y);
705 i = find_closest_label (this, x, y);
707 if ( i != this->priv->prev_i )
709 this->priv->last_i = i;
711 g_signal_emit (G_OBJECT(this),
712 mini_preview_signals[PRESSED],
714 MIN (this->priv->first_i, this->priv->last_i),
715 MAX (this->priv->first_i, this->priv->last_i));
717 this->priv->prev_i = i;
722 gl_debug (DEBUG_MINI_PREVIEW, "END");
727 /*--------------------------------------------------------------------------*/
728 /* Button release event handler */
729 /*--------------------------------------------------------------------------*/
731 button_release_event_cb (GtkWidget *widget,
732 GdkEventButton *event)
734 glMiniPreview *this = GL_MINI_PREVIEW (widget);
736 gl_debug (DEBUG_MINI_PREVIEW, "START");
738 if ( event->button == 1 )
740 this->priv->dragging = FALSE;
744 g_signal_emit (G_OBJECT(this),
745 mini_preview_signals[RELEASED],
746 0, this->priv->first_i, this->priv->last_i);
748 gl_debug (DEBUG_MINI_PREVIEW, "END");
753 /*--------------------------------------------------------------------------*/
754 /* Find index+1 of label closest to given coordinates. */
755 /*--------------------------------------------------------------------------*/
757 find_closest_label (glMiniPreview *this,
763 gdouble dx, dy, d2, min_d2;
765 dx = x - this->priv->centers[0].x;
766 dy = y - this->priv->centers[0].y;
767 min_d2 = dx*dx + dy*dy;
770 for ( i=1; i<this->priv->labels_per_sheet; i++ )
772 dx = x - this->priv->centers[i].x;
773 dy = y - this->priv->centers[i].y;
787 /*--------------------------------------------------------------------------*/
788 /* Expose event handler. */
789 /*--------------------------------------------------------------------------*/
791 expose_event_cb (GtkWidget *widget,
792 GdkEventExpose *event,
797 GtkAllocation allocation;
799 gl_debug (DEBUG_MINI_PREVIEW, "START");
801 this->priv->update_scheduled_flag = FALSE;
803 window = gtk_widget_get_window (widget);
805 cr = gdk_cairo_create (window);
808 event->area.x, event->area.y,
809 event->area.width, event->area.height);
812 gtk_widget_get_allocation (widget, &allocation);
813 cairo_translate (cr, allocation.x, allocation.y);
819 gl_debug (DEBUG_MINI_PREVIEW, "END");
824 /*--------------------------------------------------------------------------*/
825 /* Style set handler (updates colors when style/theme changes). */
826 /*--------------------------------------------------------------------------*/
828 style_set_cb (GtkWidget *widget,
829 GtkStyle *previous_style,
832 gl_debug (DEBUG_MINI_PREVIEW, "START");
836 gl_debug (DEBUG_MINI_PREVIEW, "END");
840 /*--------------------------------------------------------------------------*/
842 /*--------------------------------------------------------------------------*/
844 redraw (glMiniPreview *this)
849 gl_debug (DEBUG_MINI_PREVIEW, "START");
851 window = gtk_widget_get_window (this->priv->canvas);
856 if ( !this->priv->update_scheduled_flag )
858 this->priv->update_scheduled_flag = TRUE;
860 region = gdk_drawable_get_clip_region (window);
861 gdk_window_invalidate_region (window, region, TRUE);
862 gdk_region_destroy (region);
866 gl_debug (DEBUG_MINI_PREVIEW, "END");
870 /*--------------------------------------------------------------------------*/
871 /* Draw mini preview. */
872 /*--------------------------------------------------------------------------*/
874 draw (glMiniPreview *this,
877 lglTemplate *template = this->priv->template;
879 gdouble shadow_x, shadow_y;
882 gl_debug (DEBUG_MINI_PREVIEW, "START");
887 scale = set_transform_and_get_scale (this, cr);
890 shadow_x = SHADOW_OFFSET/scale;
891 shadow_y = SHADOW_OFFSET/scale;
893 draw_shadow (this, cr,
895 template->page_width, template->page_height);
897 draw_paper (this, cr,
898 template->page_width, template->page_height,
901 draw_labels (this, cr, template, 2.0/scale);
903 if (this->priv->draw_arrow_flag)
905 draw_arrow (this, cr);
908 if (this->priv->label)
910 draw_rich_preview (this, cr);
915 gl_debug (DEBUG_MINI_PREVIEW, "END");
920 /*--------------------------------------------------------------------------*/
921 /* Draw page shadow */
922 /*--------------------------------------------------------------------------*/
924 draw_shadow (glMiniPreview *this,
934 gl_debug (DEBUG_MINI_PREVIEW, "START");
938 cairo_rectangle (cr, x, y, width, height);
940 style = gtk_widget_get_style (GTK_WIDGET(this));
941 shadow_color = gl_color_from_gdk_color (&style->dark[GTK_STATE_NORMAL]);
942 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (shadow_color));
948 gl_debug (DEBUG_MINI_PREVIEW, "END");
952 /*--------------------------------------------------------------------------*/
954 /*--------------------------------------------------------------------------*/
956 draw_paper (glMiniPreview *this,
963 guint paper_color, outline_color;
965 gl_debug (DEBUG_MINI_PREVIEW, "START");
969 style = gtk_widget_get_style (GTK_WIDGET(this));
970 paper_color = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
971 outline_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]);
973 cairo_rectangle (cr, 0.0, 0.0, width, height);
975 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (paper_color));
976 cairo_fill_preserve (cr);
978 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (outline_color));
979 cairo_set_line_width (cr, line_width);
984 gl_debug (DEBUG_MINI_PREVIEW, "END");
988 /*--------------------------------------------------------------------------*/
990 /*--------------------------------------------------------------------------*/
992 draw_labels (glMiniPreview *this,
994 lglTemplate *template,
997 const lglTemplateFrame *frame;
999 lglTemplateOrigin *origins;
1002 guint highlight_color, paper_color, outline_color;
1004 gl_debug (DEBUG_MINI_PREVIEW, "START");
1006 frame = (lglTemplateFrame *)template->frames->data;
1008 n_labels = lgl_template_frame_get_n_labels (frame);
1009 origins = lgl_template_frame_get_origins (frame);
1011 style = gtk_widget_get_style (GTK_WIDGET(this));
1012 base_color = gl_color_from_gdk_color (&style->base[GTK_STATE_SELECTED]);
1014 paper_color = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
1015 highlight_color = gl_color_set_opacity (base_color, 0.10);
1016 if (this->priv->label)
1018 /* Outlines are more subtle when doing a rich preview. */
1019 outline_color = gl_color_set_opacity (base_color, 0.25);
1023 outline_color = gl_color_set_opacity (base_color, 1.00);
1026 for ( i=0; i < n_labels; i++ ) {
1030 cairo_translate (cr, origins[i].x, origins[i].y);
1031 gl_cairo_label_path (cr, template, FALSE, FALSE);
1033 if ( ((i+1) >= this->priv->highlight_first) &&
1034 ((i+1) <= this->priv->highlight_last) )
1036 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (highlight_color));
1037 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1038 cairo_fill_preserve (cr);
1041 cairo_set_line_width (cr, line_width);
1042 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (outline_color));
1051 gl_debug (DEBUG_MINI_PREVIEW, "END");
1055 /*--------------------------------------------------------------------------*/
1056 /* Draw arrow to indicate top of labels. */
1057 /*--------------------------------------------------------------------------*/
1059 draw_arrow (glMiniPreview *this,
1062 lglTemplateFrame *frame;
1063 lglTemplateOrigin *origins;
1064 gdouble width, height, min;
1067 guint base_color, arrow_color;
1069 PangoLayout *layout;
1070 PangoFontDescription *desc;
1071 PangoRectangle rect;
1073 const gchar *up = _("Up");
1075 frame = (lglTemplateFrame *)this->priv->template->frames->data;
1077 lgl_template_frame_get_size (frame, &width, &height);
1079 if ( width != height )
1082 origins = lgl_template_frame_get_origins (frame);
1085 min = MIN (width, height);
1090 style = gtk_widget_get_style (GTK_WIDGET(this));
1091 base_color = gl_color_from_gdk_color (&style->base[GTK_STATE_SELECTED]);
1092 arrow_color = gl_color_set_opacity (base_color, 0.25);
1093 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (arrow_color));
1095 cairo_translate (cr, x0 + width/2, y0 + height/2);
1096 cairo_scale (cr, 1, -1);
1097 if ( this->priv->rotate_flag )
1099 cairo_rotate (cr, -M_PI/2.0);
1102 cairo_new_path (cr);
1103 cairo_move_to (cr, 0, -min*ARROW_SCALE/3);
1104 cairo_line_to (cr, 0, min*ARROW_SCALE);
1106 cairo_new_sub_path (cr);
1107 cairo_move_to (cr, -min*ARROW_SCALE/2, min*ARROW_SCALE/2);
1108 cairo_line_to (cr, 0, min*ARROW_SCALE);
1109 cairo_line_to (cr, min*ARROW_SCALE/2, min*ARROW_SCALE/2);
1111 cairo_set_line_width (cr, 0.25*min*ARROW_SCALE);
1115 layout = pango_cairo_create_layout (cr);
1117 desc = pango_font_description_new ();
1118 pango_font_description_set_family (desc, UP_FONT_FAMILY);
1119 pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
1120 pango_font_description_set_size (desc, min*UP_SCALE*PANGO_SCALE);
1121 pango_layout_set_font_description (layout, desc);
1122 pango_font_description_free (desc);
1124 pango_layout_set_text (layout, up, -1);
1125 pango_layout_set_width (layout, -1);
1126 pango_layout_get_pixel_extents (layout, NULL, &rect);
1128 cairo_move_to (cr, -rect.width/2, -min/4+rect.height/2);
1130 cairo_scale (cr, 1, -1);
1131 pango_cairo_show_layout (cr, layout);
1139 /*--------------------------------------------------------------------------*/
1140 /* Draw rich preview using print renderers. */
1141 /*--------------------------------------------------------------------------*/
1143 draw_rich_preview (glMiniPreview *this,
1149 merge = gl_label_get_merge (this->priv->label);
1153 gl_print_simple_sheet (this->priv->label,
1156 this->priv->n_sheets,
1159 this->priv->outline_flag,
1160 this->priv->reverse_flag,
1161 this->priv->crop_marks_flag);
1165 /* FIXME: maybe the renderers should be more self contained.
1166 * This will only work for the first page, since
1167 * previous pages must be rendered to establish
1171 state.p_record = (GList *)gl_merge_get_record_list (merge);
1173 if (this->priv->collate_flag)
1175 gl_print_collated_merge_sheet (this->priv->label,
1178 this->priv->n_copies,
1180 this->priv->outline_flag,
1181 this->priv->reverse_flag,
1182 this->priv->crop_marks_flag,
1187 gl_print_uncollated_merge_sheet (this->priv->label,
1190 this->priv->n_copies,
1192 this->priv->outline_flag,
1193 this->priv->reverse_flag,
1194 this->priv->crop_marks_flag,
1203 * Local Variables: -- emacs
1205 * c-basic-offset: 8 -- emacs
1206 * tab-width: 8 -- emacs
1207 * indent-tabs-mode: nil -- emacs