1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * print.c: Print module
8 * Copyright (C) 2001-2006 Jim Evins <evins@snaught.com>.
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.
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.
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
28 #include <glib/gi18n.h>
32 #include <gtk/gtkenums.h>
35 #include "label-text.h"
36 #include "label-box.h"
37 #include "label-line.h"
38 #include "label-ellipse.h"
39 #include "label-image.h"
40 #include "label-barcode.h"
42 #include <libglabels/template.h>
47 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
48 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
50 #define TICK_OFFSET 2.25
51 #define TICK_LENGTH 18.0
53 /*=========================================================================*/
55 /*=========================================================================*/
57 typedef struct _PrintInfo {
58 /* gnome print context */
59 GnomePrintContext *pc;
61 /* gnome print configuration */
62 GnomePrintConfig *config;
64 /* gLabels Template */
66 gboolean label_rotate_flag;
77 /*=========================================================================*/
78 /* Private function prototypes. */
79 /*=========================================================================*/
80 static PrintInfo *print_info_new (GnomePrintJob *job,
83 static void print_info_free (PrintInfo **pi);
86 static void print_page_begin (PrintInfo *pi);
88 static void print_page_end (PrintInfo *pi);
90 static void print_crop_marks (PrintInfo *pi);
92 static void print_label (PrintInfo *pi,
96 glMergeRecord *record,
97 gboolean outline_flag,
98 gboolean reverse_flag);
101 static void draw_label (PrintInfo *pi,
103 glMergeRecord *record);
106 static void draw_object (PrintInfo *pi,
107 glLabelObject *object,
108 glMergeRecord *record);
110 static void draw_text_object (PrintInfo *pi,
112 glMergeRecord *record);
114 static void draw_box_object (PrintInfo *pi,
116 glMergeRecord *record);
118 static void draw_line_object (PrintInfo *pi,
120 glMergeRecord *record);
122 static void draw_ellipse_object (PrintInfo *pi,
123 glLabelEllipse *object,
124 glMergeRecord *record);
126 static void draw_image_object (PrintInfo *pi,
127 glLabelImage *object,
128 glMergeRecord *record);
130 static void draw_barcode_object (PrintInfo *pi,
131 glLabelBarcode *object,
132 glMergeRecord *record);
135 static void draw_outline (PrintInfo *pi,
138 static void clip_to_outline (PrintInfo *pi,
141 static void clip_punchouts (PrintInfo *pi,
145 static void create_rectangle_path (GnomePrintContext *pc,
151 static void create_ellipse_path (GnomePrintContext *pc,
157 static void create_rounded_rectangle_path (GnomePrintContext *pc,
164 static void create_clipped_circle_path (GnomePrintContext *pc,
171 #ifndef NO_ALPHA_HACK
172 static guchar * get_pixels_as_rgb (const GdkPixbuf *pixbuf);
176 /*****************************************************************************/
177 /* Simple (no merge data) print command. */
178 /*****************************************************************************/
180 gl_print_simple (GnomePrintJob *job,
188 const glTemplateLabelType *label_type;
189 gint i_sheet, i_label;
190 glTemplateOrigin *origins;
192 gl_debug (DEBUG_PRINT, "START");
194 pi = print_info_new (job, label);
195 label_type = gl_template_get_first_label_type (pi->template);
197 origins = gl_template_get_origins (label_type);
199 for (i_sheet = 0; i_sheet < n_sheets; i_sheet++) {
201 print_page_begin (pi);
202 if (flags->crop_marks) {
203 print_crop_marks (pi);
206 for (i_label = first - 1; i_label < last; i_label++) {
208 print_label (pi, label,
209 origins[i_label].x, origins[i_label].y,
210 NULL, flags->outline, flags->reverse);
219 print_info_free (&pi);
221 gl_debug (DEBUG_PRINT, "END");
224 /*****************************************************************************/
225 /* Merge print command (collated copies) */
226 /*****************************************************************************/
228 gl_print_merge_collated (GnomePrintJob *job,
235 const GList *record_list;
237 const glTemplateLabelType *label_type;
238 gint i_sheet, i_label, n_labels_per_page, i_copy;
239 glMergeRecord *record;
241 glTemplateOrigin *origins;
243 gl_debug (DEBUG_PRINT, "START");
245 merge = gl_label_get_merge (label);
246 record_list = gl_merge_get_record_list (merge);
248 pi = print_info_new (job, label);
249 label_type = gl_template_get_first_label_type (pi->template);
251 n_labels_per_page = gl_template_get_n_labels (label_type);
252 origins = gl_template_get_origins (label_type);
257 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
258 record = (glMergeRecord *)p->data;
260 if ( record->select_flag ) {
261 for (i_copy = 0; i_copy < n_copies; i_copy++) {
263 if ((i_label == 0) || (i_sheet == 0)) {
265 print_page_begin (pi);
266 if (flags->crop_marks) {
267 print_crop_marks (pi);
271 print_label (pi, label,
275 flags->outline, flags->reverse);
277 i_label = (i_label + 1) % n_labels_per_page;
291 print_info_free (&pi);
293 gl_debug (DEBUG_PRINT, "END");
296 /*****************************************************************************/
297 /* Merge print command (uncollated copies) */
298 /*****************************************************************************/
300 gl_print_merge_uncollated (GnomePrintJob *job,
307 const GList *record_list;
309 const glTemplateLabelType *label_type;
310 gint i_sheet, i_label, n_labels_per_page, i_copy;
311 glMergeRecord *record;
313 glTemplateOrigin *origins;
315 gl_debug (DEBUG_PRINT, "START");
317 merge = gl_label_get_merge (label);
318 record_list = gl_merge_get_record_list (merge);
320 pi = print_info_new (job, label);
321 label_type = gl_template_get_first_label_type (pi->template);
323 n_labels_per_page = gl_template_get_n_labels (label_type);
324 origins = gl_template_get_origins (label_type);
329 for (i_copy = 0; i_copy < n_copies; i_copy++) {
331 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
332 record = (glMergeRecord *)p->data;
334 if ( record->select_flag ) {
337 if ((i_label == 0) || (i_sheet == 0)) {
339 print_page_begin (pi);
340 if (flags->crop_marks) {
341 print_crop_marks (pi);
345 print_label (pi, label,
349 flags->outline, flags->reverse);
351 i_label = (i_label + 1) % n_labels_per_page;
365 print_info_free (&pi);
367 gl_debug (DEBUG_PRINT, "END");
370 /*****************************************************************************/
371 /* Batch print. Call appropriate function above. */
372 /*****************************************************************************/
374 gl_print_batch (GnomePrintJob *job,
382 glTemplate *template;
383 const glTemplateLabelType *label_type;
386 gl_debug (DEBUG_PRINT, "START");
388 merge = gl_label_get_merge (label);
389 template = gl_label_get_template (label);
390 label_type = gl_template_get_first_label_type (template);
392 if ( merge == NULL ) {
393 n_per_page = gl_template_get_n_labels(label_type);
395 gl_print_simple (job, label, n_sheets, first, n_per_page, flags);
397 gl_print_merge_collated (job, label, n_copies, first, flags);
399 gl_template_free (template);
401 gl_debug (DEBUG_PRINT, "END");
404 /*---------------------------------------------------------------------------*/
405 /* PRIVATE. new print info structure */
406 /*---------------------------------------------------------------------------*/
408 print_info_new (GnomePrintJob *job,
411 PrintInfo *pi = g_new0 (PrintInfo, 1);
412 glTemplate *template;
414 gl_debug (DEBUG_PRINT, "START");
416 g_return_val_if_fail (job && GNOME_IS_PRINT_JOB (job), NULL);
417 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
419 template = gl_label_get_template (label);
421 g_return_val_if_fail (template, NULL);
422 g_return_val_if_fail (template->page_size, NULL);
423 g_return_val_if_fail (template->page_width > 0, NULL);
424 g_return_val_if_fail (template->page_height > 0, NULL);
426 pi->pc = gnome_print_job_get_context (job);
427 pi->config = gnome_print_job_get_config (job);
429 gl_debug (DEBUG_PRINT,
430 "setting page size = \"%s\"", template->page_size);
432 gnome_print_config_set_length (pi->config,
433 (guchar *)GNOME_PRINT_KEY_PAPER_WIDTH,
434 template->page_width,
435 GNOME_PRINT_PS_UNIT);
436 gnome_print_config_set_length (pi->config,
437 (guchar *)GNOME_PRINT_KEY_PAPER_HEIGHT,
438 template->page_height,
439 GNOME_PRINT_PS_UNIT);
441 pi->page_width = template->page_width;
442 pi->page_height = template->page_height;
444 pi->template = template;
445 pi->label_rotate_flag = gl_label_get_rotate_flag (label);
449 gl_debug (DEBUG_PRINT, "END");
454 /*---------------------------------------------------------------------------*/
455 /* PRIVATE. free print info structure */
456 /*---------------------------------------------------------------------------*/
458 print_info_free (PrintInfo **pi)
460 gl_debug (DEBUG_PRINT, "START");
462 gl_template_free ((*pi)->template);
463 (*pi)->template = NULL;
465 gnome_print_context_close ((*pi)->pc);
470 gl_debug (DEBUG_PRINT, "END");
473 /*---------------------------------------------------------------------------*/
474 /* PRIVATE. Begin a new page. */
475 /*---------------------------------------------------------------------------*/
477 print_page_begin (PrintInfo *pi)
481 gl_debug (DEBUG_PRINT, "START");
485 str = g_strdup_printf ("sheet%02d", pi->sheet);
486 gnome_print_beginpage (pi->pc, (guchar *)str);
489 /* Translate and scale, so that our origin is at the upper left. */
490 gnome_print_translate (pi->pc, 0.0, pi->page_height);
491 gnome_print_scale (pi->pc, 1.0, -1.0);
493 gl_debug (DEBUG_PRINT, "END");
496 /*---------------------------------------------------------------------------*/
497 /* PRIVATE. End a page. */
498 /*---------------------------------------------------------------------------*/
500 print_page_end (PrintInfo *pi)
502 gl_debug (DEBUG_PRINT, "START");
504 gnome_print_showpage (pi->pc);
506 gl_debug (DEBUG_PRINT, "END");
509 /*---------------------------------------------------------------------------*/
510 /* PRIVATE. Print crop tick marks. */
511 /*---------------------------------------------------------------------------*/
513 print_crop_marks (PrintInfo *pi)
515 const glTemplateLabelType *label_type;
516 gdouble w, h, page_w, page_h;
518 glTemplateLayout *layout;
519 gdouble xmin, ymin, xmax, ymax, dx, dy;
520 gdouble x1, y1, x2, y2, x3, y3, x4, y4;
523 gl_debug (DEBUG_PRINT, "START");
525 label_type = gl_template_get_first_label_type (pi->template);
527 gl_template_get_label_size (label_type, &w, &h);
529 page_w = pi->page_width;
530 page_h = pi->page_height;
532 gnome_print_setrgbcolor (pi->pc, 0.0, 0.0, 0.0);
533 gnome_print_setopacity (pi->pc, 1.0);
534 gnome_print_setlinewidth (pi->pc, 0.25);
536 for (p=label_type->layouts; p != NULL; p=p->next) {
538 layout = (glTemplateLayout *)p->data;
542 xmax = layout->x0 + layout->dx*(layout->nx - 1) + w;
543 ymax = layout->y0 + layout->dy*(layout->ny - 1) + h;
551 for (ix=0; ix < nx; ix++) {
556 y1 = MAX((ymin - TICK_OFFSET), 0.0);
557 y2 = MAX((y1 - TICK_LENGTH), 0.0);
559 y3 = MIN((ymax + TICK_OFFSET), page_h);
560 y4 = MIN((y3 + TICK_LENGTH), page_h);
562 gnome_print_moveto (pi->pc, x1, y1);
563 gnome_print_lineto (pi->pc, x1, y2);
564 gnome_print_stroke (pi->pc);
566 gnome_print_moveto (pi->pc, x2, y1);
567 gnome_print_lineto (pi->pc, x2, y2);
568 gnome_print_stroke (pi->pc);
570 gnome_print_moveto (pi->pc, x1, y3);
571 gnome_print_lineto (pi->pc, x1, y4);
572 gnome_print_stroke (pi->pc);
574 gnome_print_moveto (pi->pc, x2, y3);
575 gnome_print_lineto (pi->pc, x2, y4);
576 gnome_print_stroke (pi->pc);
580 for (iy=0; iy < ny; iy++) {
585 x1 = MAX((xmin - TICK_OFFSET), 0.0);
586 x2 = MAX((x1 - TICK_LENGTH), 0.0);
588 x3 = MIN((xmax + TICK_OFFSET), page_w);
589 x4 = MIN((x3 + TICK_LENGTH), page_w);
591 gnome_print_moveto (pi->pc, x1, y1);
592 gnome_print_lineto (pi->pc, x2, y1);
593 gnome_print_stroke (pi->pc);
595 gnome_print_moveto (pi->pc, x1, y2);
596 gnome_print_lineto (pi->pc, x2, y2);
597 gnome_print_stroke (pi->pc);
599 gnome_print_moveto (pi->pc, x3, y1);
600 gnome_print_lineto (pi->pc, x4, y1);
601 gnome_print_stroke (pi->pc);
603 gnome_print_moveto (pi->pc, x3, y2);
604 gnome_print_lineto (pi->pc, x4, y2);
605 gnome_print_stroke (pi->pc);
611 gl_debug (DEBUG_PRINT, "END");
614 /*---------------------------------------------------------------------------*/
615 /* PRIVATE. Print i'th label. */
616 /*---------------------------------------------------------------------------*/
618 print_label (PrintInfo *pi,
622 glMergeRecord *record,
623 gboolean outline_flag,
624 gboolean reverse_flag)
626 const glTemplateLabelType *label_type;
627 gdouble width, height;
629 gl_debug (DEBUG_PRINT, "START");
631 label_type = gl_template_get_first_label_type (pi->template);
633 gl_label_get_size (label, &width, &height);
635 gnome_print_gsave (pi->pc);
637 /* Transform coordinate system to be relative to upper corner */
638 /* of the current label */
639 gnome_print_translate (pi->pc, x, y);
640 if (gl_label_get_rotate_flag (label)) {
641 gl_debug (DEBUG_PRINT, "Rotate flag set");
642 gnome_print_rotate (pi->pc, -90.0);
643 gnome_print_translate (pi->pc, -width, 0.0);
645 if ( reverse_flag ) {
646 gnome_print_translate (pi->pc, width, 0.0);
647 gnome_print_scale (pi->pc, -1.0, 1.0);
650 clip_to_outline (pi, label);
651 draw_label (pi, label, record);
653 draw_outline (pi, label);
655 clip_punchouts (pi, label);
657 gnome_print_grestore (pi->pc);
659 gl_debug (DEBUG_PRINT, "END");
662 /*---------------------------------------------------------------------------*/
663 /* PRIVATE. Draw label. */
664 /*---------------------------------------------------------------------------*/
666 draw_label (PrintInfo *pi,
668 glMergeRecord *record)
671 glLabelObject *object;
673 gl_debug (DEBUG_PRINT, "START");
675 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
676 object = (glLabelObject *) p_obj->data;
678 draw_object (pi, object, record);
681 gl_debug (DEBUG_PRINT, "END");
684 /*---------------------------------------------------------------------------*/
685 /* PRIVATE. Draw object. */
686 /*---------------------------------------------------------------------------*/
688 draw_object (PrintInfo *pi,
689 glLabelObject *object,
690 glMergeRecord *record)
695 gl_debug (DEBUG_PRINT, "START");
697 gl_label_object_get_position (object, &x0, &y0);
698 gl_label_object_get_affine (object, affine);
700 gnome_print_gsave (pi->pc);
702 gnome_print_translate (pi->pc, x0, y0);
703 gnome_print_concat (pi->pc, affine);
705 if (GL_IS_LABEL_TEXT(object)) {
706 draw_text_object (pi, GL_LABEL_TEXT(object), record);
707 } else if (GL_IS_LABEL_BOX(object)) {
708 draw_box_object (pi, GL_LABEL_BOX(object), record);
709 } else if (GL_IS_LABEL_LINE(object)) {
710 draw_line_object (pi, GL_LABEL_LINE(object), record);
711 } else if (GL_IS_LABEL_ELLIPSE(object)) {
712 draw_ellipse_object (pi, GL_LABEL_ELLIPSE(object), record);
713 } else if (GL_IS_LABEL_IMAGE(object)) {
714 draw_image_object (pi, GL_LABEL_IMAGE(object), record);
715 } else if (GL_IS_LABEL_BARCODE(object)) {
716 draw_barcode_object (pi, GL_LABEL_BARCODE(object), record);
719 gnome_print_grestore (pi->pc);
721 gl_debug (DEBUG_PRINT, "END");
724 /*---------------------------------------------------------------------------*/
725 /* PRIVATE. Draw text object. */
726 /*---------------------------------------------------------------------------*/
728 draw_text_object (PrintInfo *pi,
730 glMergeRecord *record)
735 gdouble x_offset, y_offset, w, object_w, object_h;
740 GnomeFontWeight font_weight;
741 gboolean font_italic_flag;
743 glColorNode *color_node;
744 GtkJustification just;
745 gboolean auto_shrink;
746 GnomeGlyphList *glyphlist;
749 gdouble text_line_spacing;
750 gboolean shadow_state;
751 gdouble shadow_x, shadow_y;
752 glColorNode *shadow_color_node;
753 gdouble shadow_opacity;
757 gl_debug (DEBUG_PRINT, "START");
759 gl_label_object_get_size (GL_LABEL_OBJECT(object), &object_w, &object_h);
760 lines = gl_label_text_get_lines (object);
761 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object));
762 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object));
763 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object));
764 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object));
766 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object));
767 color = gl_color_node_expand (color_node, record);
768 gl_color_node_free (&color_node);
770 just = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object));
772 gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object));
773 auto_shrink = gl_label_text_get_auto_shrink (object);
775 shadow_state = gl_label_object_get_shadow_state (GL_LABEL_OBJECT (object));
776 gl_label_object_get_shadow_offset (GL_LABEL_OBJECT (object), &shadow_x, &shadow_y);
777 shadow_color_node = gl_label_object_get_shadow_color (GL_LABEL_OBJECT (object));
778 if (shadow_color_node->field_flag)
780 shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT;
782 shadow_opacity = gl_label_object_get_shadow_opacity (GL_LABEL_OBJECT (object));
783 shadow_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, color);
784 gl_color_node_free (&shadow_color_node);
786 text = gl_text_node_lines_expand (lines, record);
787 line = g_strsplit (text, "\n", -1);
790 art_affine_identity (affine);
792 if (record && auto_shrink) {
793 /* auto shrink text size to keep within text box limits. */
794 for (i = 0; line[i] != NULL; i++) {
796 font = gnome_font_find_closest_from_weight_slant (
797 (guchar *)font_family,
801 glyphlist = gnome_glyphlist_from_text_dumb (
806 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
808 gnome_glyphlist_unref (glyphlist);
810 /* If width is too large, iteratively shrink font_size until this
811 line fits the width, or until the font size is ridiculously
813 while ( (w > object_w) && (font_size >= 1.0) ) {
817 font = gnome_font_find_closest_from_weight_slant (
818 (guchar *)font_family,
822 glyphlist = gnome_glyphlist_from_text_dumb (
827 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
829 gnome_glyphlist_unref (glyphlist);
835 font = gnome_font_find_closest_from_weight_slant (
836 (guchar *)font_family,
840 gnome_print_setfont (pi->pc, font);
842 gnome_print_setrgbcolor (pi->pc,
843 GL_COLOR_F_RED (shadow_color),
844 GL_COLOR_F_GREEN (shadow_color),
845 GL_COLOR_F_BLUE (shadow_color));
846 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_color));
848 for (i = 0; line[i] != NULL; i++) {
850 glyphlist = gnome_glyphlist_from_text_dumb (font, color,
854 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
856 gnome_glyphlist_unref (glyphlist);
859 case GTK_JUSTIFY_LEFT:
860 x_offset = GL_LABEL_TEXT_MARGIN;
862 case GTK_JUSTIFY_CENTER:
863 x_offset = (object_w - GL_LABEL_TEXT_MARGIN - w) / 2.0;
865 case GTK_JUSTIFY_RIGHT:
866 x_offset = object_w - GL_LABEL_TEXT_MARGIN - w;
870 break; /* shouldn't happen */
872 x_offset += shadow_x;
874 /* Work out the y position to the BOTTOM of the first line */
875 y_offset = GL_LABEL_TEXT_MARGIN +
876 + gnome_font_get_descender (font)
877 + (i + 1) * font_size * text_line_spacing
880 /* Remove any text line spacing from the first row. */
881 y_offset -= font_size * (text_line_spacing - 1);
884 gnome_print_moveto (pi->pc, x_offset, y_offset);
886 gnome_print_gsave (pi->pc);
887 gnome_print_scale (pi->pc, 1.0, -1.0);
888 gnome_print_show (pi->pc, (guchar *)line[i]);
889 gnome_print_grestore (pi->pc);
892 gnome_print_setrgbcolor (pi->pc,
893 GL_COLOR_F_RED (color),
894 GL_COLOR_F_GREEN (color),
895 GL_COLOR_F_BLUE (color));
896 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (color));
898 for (i = 0; line[i] != NULL; i++) {
900 glyphlist = gnome_glyphlist_from_text_dumb (font, color,
904 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
906 gnome_glyphlist_unref (glyphlist);
909 case GTK_JUSTIFY_LEFT:
910 x_offset = GL_LABEL_TEXT_MARGIN;
912 case GTK_JUSTIFY_CENTER:
913 x_offset = (object_w - GL_LABEL_TEXT_MARGIN - w) / 2.0;
915 case GTK_JUSTIFY_RIGHT:
916 x_offset = object_w - GL_LABEL_TEXT_MARGIN - w;
920 break; /* shouldn't happen */
923 /* Work out the y position to the BOTTOM of the first line */
924 y_offset = GL_LABEL_TEXT_MARGIN +
925 + gnome_font_get_descender (font)
926 + (i + 1) * font_size * text_line_spacing;
928 /* Remove any text line spacing from the first row. */
929 y_offset -= font_size * (text_line_spacing - 1);
932 gnome_print_moveto (pi->pc, x_offset, y_offset);
934 gnome_print_gsave (pi->pc);
935 gnome_print_scale (pi->pc, 1.0, -1.0);
936 gnome_print_show (pi->pc, (guchar *)line[i]);
937 gnome_print_grestore (pi->pc);
942 gl_text_node_lines_free (&lines);
943 g_free (font_family);
945 gl_debug (DEBUG_PRINT, "END");
948 /*---------------------------------------------------------------------------*/
949 /* PRIVATE. Draw box object. */
950 /*---------------------------------------------------------------------------*/
952 draw_box_object (PrintInfo *pi,
954 glMergeRecord *record)
959 glColorNode *line_color_node;
960 glColorNode *fill_color_node;
962 gboolean shadow_state;
963 gdouble shadow_x, shadow_y;
964 glColorNode *shadow_color_node;
965 gdouble shadow_opacity;
966 guint shadow_line_color;
967 guint shadow_fill_color;
969 gl_debug (DEBUG_PRINT, "START");
971 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
972 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
974 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
975 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
976 line_color = gl_color_node_expand (line_color_node, record);
977 fill_color = gl_color_node_expand (fill_color_node, record);
978 gl_color_node_free (&line_color_node);
979 gl_color_node_free (&fill_color_node);
981 shadow_state = gl_label_object_get_shadow_state (GL_LABEL_OBJECT (object));
982 gl_label_object_get_shadow_offset (GL_LABEL_OBJECT (object), &shadow_x, &shadow_y);
983 shadow_color_node = gl_label_object_get_shadow_color (GL_LABEL_OBJECT (object));
984 if (shadow_color_node->field_flag)
986 shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT;
988 shadow_opacity = gl_label_object_get_shadow_opacity (GL_LABEL_OBJECT (object));
989 shadow_line_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, line_color);
990 shadow_fill_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, fill_color);
991 gl_color_node_free (&shadow_color_node);
995 /* Draw fill shadow */
996 create_rectangle_path (pi->pc, shadow_x, shadow_y, w, h);
997 gnome_print_setrgbcolor (pi->pc,
998 GL_COLOR_F_RED (shadow_fill_color),
999 GL_COLOR_F_GREEN (shadow_fill_color),
1000 GL_COLOR_F_BLUE (shadow_fill_color));
1001 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_fill_color));
1002 gnome_print_fill (pi->pc);
1004 /* Draw outline shadow */
1005 create_rectangle_path (pi->pc, shadow_x, shadow_y, w, h);
1006 gnome_print_setrgbcolor (pi->pc,
1007 GL_COLOR_F_RED (shadow_line_color),
1008 GL_COLOR_F_GREEN (shadow_line_color),
1009 GL_COLOR_F_BLUE (shadow_line_color));
1010 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_line_color));
1011 gnome_print_setlinewidth (pi->pc, line_width);
1012 gnome_print_stroke (pi->pc);
1015 /* Paint fill color */
1016 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
1017 gnome_print_setrgbcolor (pi->pc,
1018 GL_COLOR_F_RED (fill_color),
1019 GL_COLOR_F_GREEN (fill_color),
1020 GL_COLOR_F_BLUE (fill_color));
1021 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
1022 gnome_print_fill (pi->pc);
1025 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
1026 gnome_print_setrgbcolor (pi->pc,
1027 GL_COLOR_F_RED (line_color),
1028 GL_COLOR_F_GREEN (line_color),
1029 GL_COLOR_F_BLUE (line_color));
1030 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
1031 gnome_print_setlinewidth (pi->pc, line_width);
1032 gnome_print_stroke (pi->pc);
1034 gl_debug (DEBUG_PRINT, "END");
1037 /*---------------------------------------------------------------------------*/
1038 /* PRIVATE. Draw line object. */
1039 /*---------------------------------------------------------------------------*/
1041 draw_line_object (PrintInfo *pi,
1042 glLabelLine *object,
1043 glMergeRecord *record)
1048 glColorNode *line_color_node;
1049 gboolean shadow_state;
1050 gdouble shadow_x, shadow_y;
1051 glColorNode *shadow_color_node;
1052 gdouble shadow_opacity;
1053 guint shadow_line_color;
1055 gl_debug (DEBUG_PRINT, "START");
1057 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1058 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1060 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1061 line_color = gl_color_node_expand (line_color_node, record);
1062 gl_color_node_free (&line_color_node);
1064 shadow_state = gl_label_object_get_shadow_state (GL_LABEL_OBJECT (object));
1065 gl_label_object_get_shadow_offset (GL_LABEL_OBJECT (object), &shadow_x, &shadow_y);
1066 shadow_color_node = gl_label_object_get_shadow_color (GL_LABEL_OBJECT (object));
1067 if (shadow_color_node->field_flag)
1069 shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT;
1071 shadow_opacity = gl_label_object_get_shadow_opacity (GL_LABEL_OBJECT (object));
1072 shadow_line_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, line_color);
1073 gl_color_node_free (&shadow_color_node);
1077 gnome_print_moveto (pi->pc, shadow_x, shadow_y);
1078 gnome_print_lineto (pi->pc, shadow_x + w, shadow_y + h);
1079 gnome_print_setrgbcolor (pi->pc,
1080 GL_COLOR_F_RED (shadow_line_color),
1081 GL_COLOR_F_GREEN (shadow_line_color),
1082 GL_COLOR_F_BLUE (shadow_line_color));
1083 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_line_color));
1084 gnome_print_setlinewidth (pi->pc, line_width);
1085 gnome_print_stroke (pi->pc);
1088 gnome_print_moveto (pi->pc, 0.0, 0.0);
1089 gnome_print_lineto (pi->pc, w, h);
1090 gnome_print_setrgbcolor (pi->pc,
1091 GL_COLOR_F_RED (line_color),
1092 GL_COLOR_F_GREEN (line_color),
1093 GL_COLOR_F_BLUE (line_color));
1094 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
1095 gnome_print_setlinewidth (pi->pc, line_width);
1096 gnome_print_stroke (pi->pc);
1098 gl_debug (DEBUG_PRINT, "END");
1101 /*---------------------------------------------------------------------------*/
1102 /* PRIVATE. Draw ellipse object. */
1103 /*---------------------------------------------------------------------------*/
1105 draw_ellipse_object (PrintInfo *pi,
1106 glLabelEllipse *object,
1107 glMergeRecord *record)
1109 gdouble x0, y0, rx, ry, w, h;
1111 glColorNode *line_color_node;
1112 glColorNode *fill_color_node;
1115 gboolean shadow_state;
1116 gdouble shadow_x, shadow_y;
1117 glColorNode *shadow_color_node;
1118 gdouble shadow_opacity;
1119 guint shadow_line_color;
1120 guint shadow_fill_color;
1122 gl_debug (DEBUG_PRINT, "START");
1124 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1125 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1127 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1128 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1129 line_color = gl_color_node_expand (line_color_node, record);
1130 fill_color = gl_color_node_expand (fill_color_node, record);
1131 gl_color_node_free (&line_color_node);
1132 gl_color_node_free (&fill_color_node);
1139 shadow_state = gl_label_object_get_shadow_state (GL_LABEL_OBJECT (object));
1140 gl_label_object_get_shadow_offset (GL_LABEL_OBJECT (object), &shadow_x, &shadow_y);
1141 shadow_color_node = gl_label_object_get_shadow_color (GL_LABEL_OBJECT (object));
1142 if (shadow_color_node->field_flag)
1144 shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT;
1146 shadow_opacity = gl_label_object_get_shadow_opacity (GL_LABEL_OBJECT (object));
1147 shadow_line_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, line_color);
1148 shadow_fill_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, fill_color);
1149 gl_color_node_free (&shadow_color_node);
1153 /* Draw fill shadow */
1154 create_ellipse_path (pi->pc, x0+shadow_x, y0+shadow_y, rx, ry);
1155 gnome_print_setrgbcolor (pi->pc,
1156 GL_COLOR_F_RED (shadow_fill_color),
1157 GL_COLOR_F_GREEN (shadow_fill_color),
1158 GL_COLOR_F_BLUE (shadow_fill_color));
1159 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_fill_color));
1160 gnome_print_fill (pi->pc);
1162 /* Draw outline shadow */
1163 create_ellipse_path (pi->pc, x0+shadow_x, y0+shadow_y, rx, ry);
1164 gnome_print_setrgbcolor (pi->pc,
1165 GL_COLOR_F_RED (shadow_line_color),
1166 GL_COLOR_F_GREEN (shadow_line_color),
1167 GL_COLOR_F_BLUE (shadow_line_color));
1168 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (shadow_line_color));
1169 gnome_print_setlinewidth (pi->pc, line_width);
1170 gnome_print_stroke (pi->pc);
1173 /* Paint fill color */
1174 create_ellipse_path (pi->pc, x0, y0, rx, ry);
1175 gnome_print_setrgbcolor (pi->pc,
1176 GL_COLOR_F_RED (fill_color),
1177 GL_COLOR_F_GREEN (fill_color),
1178 GL_COLOR_F_BLUE (fill_color));
1179 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
1180 gnome_print_fill (pi->pc);
1183 create_ellipse_path (pi->pc, x0, y0, rx, ry);
1184 gnome_print_setrgbcolor (pi->pc,
1185 GL_COLOR_F_RED (line_color),
1186 GL_COLOR_F_GREEN (line_color),
1187 GL_COLOR_F_BLUE (line_color));
1188 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
1189 gnome_print_setlinewidth (pi->pc, line_width);
1190 gnome_print_stroke (pi->pc);
1192 gl_debug (DEBUG_PRINT, "END");
1195 /*---------------------------------------------------------------------------*/
1196 /* PRIVATE. Draw image object. */
1197 /*---------------------------------------------------------------------------*/
1199 draw_image_object (PrintInfo *pi,
1200 glLabelImage *object,
1201 glMergeRecord *record)
1204 const GdkPixbuf *pixbuf;
1206 gint image_w, image_h, image_stride;
1207 gboolean image_alpha_flag;
1210 gl_debug (DEBUG_PRINT, "START");
1212 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1214 pixbuf = gl_label_image_get_pixbuf (object, record);
1215 image_data = gdk_pixbuf_get_pixels (pixbuf);
1216 image_w = gdk_pixbuf_get_width (pixbuf);
1217 image_h = gdk_pixbuf_get_height (pixbuf);
1218 image_stride = gdk_pixbuf_get_rowstride(pixbuf);
1219 image_alpha_flag = gdk_pixbuf_get_has_alpha(pixbuf);
1221 gnome_print_gsave (pi->pc);
1222 gnome_print_translate (pi->pc, 0.0, h);
1223 gnome_print_scale (pi->pc, w, -h);
1224 if (image_alpha_flag) {
1225 #ifndef NO_ALPHA_HACK
1226 guchar *image_data2;
1228 image_data2 = get_pixels_as_rgb (pixbuf);
1229 ret = gnome_print_rgbimage (pi->pc, image_data2,
1230 image_w, image_h, image_stride);
1231 g_free (image_data2);
1233 ret = gnome_print_rgbaimage (pi->pc, image_data,
1234 image_w, image_h, image_stride);
1237 ret = gnome_print_rgbimage (pi->pc, image_data,
1238 image_w, image_h, image_stride);
1240 gnome_print_grestore (pi->pc);
1242 gl_debug (DEBUG_PRINT, "END");
1245 /*---------------------------------------------------------------------------*/
1246 /* PRIVATE. Draw box object. */
1247 /*---------------------------------------------------------------------------*/
1249 draw_barcode_object (PrintInfo *pi,
1250 glLabelBarcode *object,
1251 glMergeRecord *record)
1254 glBarcodeLine *line;
1255 glBarcodeChar *bchar;
1259 gchar *text, *cstring;
1260 glTextNode *text_node;
1263 gboolean checksum_flag;
1265 glColorNode *color_node;
1266 guint format_digits;
1269 gl_debug (DEBUG_PRINT, "START");
1271 text_node = gl_label_barcode_get_data (object);
1272 gl_label_barcode_get_props (object,
1273 &id, &text_flag, &checksum_flag, &format_digits);
1275 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1276 color = gl_color_node_expand (color_node, record);
1277 gl_color_node_free (&color_node);
1279 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1281 text = gl_text_node_expand (text_node, record);
1282 gbc = gl_barcode_new (id, text_flag, checksum_flag, w, h, text);
1284 gl_text_node_free (&text_node);
1289 font = gnome_font_find_closest_from_weight_slant (
1290 (guchar *)GL_BARCODE_FONT_FAMILY,
1291 GL_BARCODE_FONT_WEIGHT,
1293 gnome_print_setfont (pi->pc, font);
1295 gnome_print_setrgbcolor (pi->pc,
1296 GL_COLOR_F_RED (color),
1297 GL_COLOR_F_GREEN (color),
1298 GL_COLOR_F_BLUE (color));
1299 gnome_print_setopacity (pi->pc,
1300 GL_COLOR_F_ALPHA (color));
1302 y_offset = 12.0 - fabs (gnome_font_get_descender (font));
1303 gnome_print_moveto (pi->pc, 0.0, y_offset);
1305 gnome_print_gsave (pi->pc);
1306 gnome_print_scale (pi->pc, 1.0, -1.0);
1307 gnome_print_show (pi->pc, (guchar *)_("Invalid barcode data"));
1308 gnome_print_grestore (pi->pc);
1312 for (li = gbc->lines; li != NULL; li = li->next) {
1313 line = (glBarcodeLine *) li->data;
1315 gnome_print_moveto (pi->pc, line->x, line->y);
1316 gnome_print_lineto (pi->pc, line->x, line->y + line->length);
1317 gnome_print_setrgbcolor (pi->pc,
1318 GL_COLOR_F_RED (color),
1319 GL_COLOR_F_GREEN (color),
1320 GL_COLOR_F_BLUE (color));
1321 gnome_print_setopacity (pi->pc,
1322 GL_COLOR_F_ALPHA (color));
1323 gnome_print_setlinewidth (pi->pc, line->width);
1324 gnome_print_stroke (pi->pc);
1327 for (li = gbc->chars; li != NULL; li = li->next) {
1328 bchar = (glBarcodeChar *) li->data;
1330 font = gnome_font_find_closest_from_weight_slant (
1331 (guchar *)GL_BARCODE_FONT_FAMILY,
1332 GL_BARCODE_FONT_WEIGHT,
1333 FALSE, bchar->fsize);
1334 gnome_print_setfont (pi->pc, font);
1336 gnome_print_setrgbcolor (pi->pc,
1337 GL_COLOR_F_RED (color),
1338 GL_COLOR_F_GREEN (color),
1339 GL_COLOR_F_BLUE (color));
1340 gnome_print_setopacity (pi->pc,
1341 GL_COLOR_F_ALPHA (color));
1344 bchar->fsize - fabs (gnome_font_get_descender (font));
1346 gnome_print_moveto (pi->pc, bchar->x, bchar->y+y_offset);
1348 cstring = g_strdup_printf ("%c", bchar->c);
1349 gnome_print_gsave (pi->pc);
1350 gnome_print_scale (pi->pc, 1.0, -1.0);
1351 gnome_print_show (pi->pc, (guchar *)cstring);
1352 gnome_print_grestore (pi->pc);
1357 gl_barcode_free (&gbc);
1361 gl_debug (DEBUG_PRINT, "END");
1364 /*---------------------------------------------------------------------------*/
1365 /* PRIVATE. Draw outline. */
1366 /*---------------------------------------------------------------------------*/
1368 draw_outline (PrintInfo *pi,
1371 const glTemplateLabelType *label_type;
1375 gl_debug (DEBUG_PRINT, "START");
1377 label_type = gl_template_get_first_label_type (pi->template);
1379 gnome_print_setrgbcolor (pi->pc, 0.0, 0.0, 0.0);
1380 gnome_print_setopacity (pi->pc, 1.0);
1381 gnome_print_setlinewidth (pi->pc, 0.25);
1383 switch (label_type->shape) {
1385 case GL_TEMPLATE_SHAPE_RECT:
1386 gl_label_get_size (label, &w, &h);
1387 r = label_type->size.rect.r;
1389 /* simple rectangle */
1390 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
1392 /* rectangle with rounded corners */
1393 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
1396 gnome_print_stroke (pi->pc);
1399 case GL_TEMPLATE_SHAPE_ROUND:
1401 r1 = label_type->size.round.r;
1402 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1403 gnome_print_stroke (pi->pc);
1406 case GL_TEMPLATE_SHAPE_CD:
1407 if ((label_type->size.cd.h == 0) && (label_type->size.cd.w == 0)) {
1408 /* CD style, round label w/ concentric round hole */
1409 r1 = label_type->size.cd.r1;
1410 r2 = label_type->size.cd.r2;
1411 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1412 gnome_print_stroke (pi->pc);
1413 create_ellipse_path (pi->pc, r1, r1, r2, r2);
1414 gnome_print_stroke (pi->pc);
1416 /* Business Card CD style, clipped round label w/ hole */
1417 gl_label_get_size (label, &w, &h);
1418 r1 = label_type->size.cd.r1;
1419 r2 = label_type->size.cd.r2;
1420 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1421 gnome_print_stroke (pi->pc);
1422 create_ellipse_path (pi->pc, w/2, h/2, r2, r2);
1423 gnome_print_stroke (pi->pc);
1428 g_message ("Unknown template label style");
1432 gl_debug (DEBUG_PRINT, "END");
1435 /*---------------------------------------------------------------------------*/
1436 /* PRIVATE. Clip to outline. */
1437 /*---------------------------------------------------------------------------*/
1439 clip_to_outline (PrintInfo *pi,
1442 const glTemplateLabelType *label_type;
1445 gdouble waste, x_waste, y_waste;
1447 gl_debug (DEBUG_PRINT, "START");
1449 label_type = gl_template_get_first_label_type (pi->template);
1451 switch (label_type->shape) {
1453 case GL_TEMPLATE_SHAPE_RECT:
1454 gl_label_get_size (label, &w, &h);
1455 r = label_type->size.rect.r;
1456 x_waste = label_type->size.rect.x_waste;
1457 y_waste = label_type->size.rect.y_waste;
1459 /* simple rectangle */
1460 create_rectangle_path (pi->pc,
1462 w+2*x_waste, h+2*y_waste);
1464 /* rectangle with rounded corners */
1465 create_rounded_rectangle_path (pi->pc,
1467 w+2*x_waste, h+2*y_waste, r);
1469 gnome_print_clip (pi->pc);
1472 case GL_TEMPLATE_SHAPE_ROUND:
1473 r1 = label_type->size.round.r;
1474 waste = label_type->size.round.waste;
1475 create_ellipse_path (pi->pc, r1, r1, r1+waste, r1+waste);
1476 gnome_print_clip (pi->pc);
1479 case GL_TEMPLATE_SHAPE_CD:
1480 waste = label_type->size.cd.waste;
1481 if ((label_type->size.cd.h == 0) && (label_type->size.cd.w == 0)) {
1482 /* CD style, round label w/ concentric round hole */
1483 r1 = label_type->size.cd.r1;
1484 create_ellipse_path (pi->pc, r1, r1, r1+waste, r1+waste);
1486 /* Business Card CD style, clipped round label w/ hole */
1487 gl_label_get_size (label, &w, &h);
1488 r1 = label_type->size.cd.r1;
1489 create_clipped_circle_path (pi->pc,
1491 w+2*waste, h+2*waste,
1494 gnome_print_clip (pi->pc);
1498 g_message ("Unknown template label style");
1502 gl_debug (DEBUG_PRINT, "END");
1505 /*---------------------------------------------------------------------------*/
1506 /* PRIVATE. Clip punchouts. (Save some ink by not printing in CD holes) */
1508 /* Ideally this would be done in clip_to_outline, but I am not sure how to */
1509 /* invert the region for gnome_print_clip, so instead, I will just draw */
1510 /* a white circle on top of everything else. */
1511 /*---------------------------------------------------------------------------*/
1513 clip_punchouts (PrintInfo *pi,
1516 const glTemplateLabelType *label_type;
1520 gl_debug (DEBUG_PRINT, "START");
1522 label_type = gl_template_get_first_label_type (pi->template);
1524 switch (label_type->shape) {
1526 case GL_TEMPLATE_SHAPE_RECT:
1527 case GL_TEMPLATE_SHAPE_ROUND:
1530 case GL_TEMPLATE_SHAPE_CD:
1531 gl_label_get_size (label, &w, &h);
1532 waste = label_type->size.cd.waste;
1533 r2 = label_type->size.cd.r2;
1534 create_ellipse_path (pi->pc, w/2, h/2, r2-waste, r2-waste);
1535 gnome_print_setrgbcolor (pi->pc, 1.0, 1.0, 1.0);
1536 gnome_print_setopacity (pi->pc, 1.0);
1537 gnome_print_fill (pi->pc);
1541 g_message ("Unknown template label style");
1545 gl_debug (DEBUG_PRINT, "END");
1548 /*---------------------------------------------------------------------------*/
1549 /* PRIVATE. Path creation utilities. */
1550 /*---------------------------------------------------------------------------*/
1552 create_rectangle_path (GnomePrintContext *pc,
1558 gl_debug (DEBUG_PRINT, "START");
1560 gnome_print_newpath (pc);
1561 gnome_print_moveto (pc, x0, y0);
1562 gnome_print_lineto (pc, x0 + w, y0);
1563 gnome_print_lineto (pc, x0 + w, y0 + h);
1564 gnome_print_lineto (pc, x0, y0 + h);
1565 gnome_print_lineto (pc, x0, y0);
1566 gnome_print_closepath (pc);
1568 gl_debug (DEBUG_PRINT, "END");
1572 create_ellipse_path (GnomePrintContext *pc,
1581 gl_debug (DEBUG_PRINT, "START");
1583 gnome_print_newpath (pc);
1584 gnome_print_moveto (pc, x0 + rx, y0);
1585 for (i_theta = ARC_FINE; i_theta <= 360; i_theta += ARC_FINE) {
1586 x = x0 + rx * cos (i_theta * G_PI / 180.0);
1587 y = y0 + ry * sin (i_theta * G_PI / 180.0);
1588 gnome_print_lineto (pc, x, y);
1590 gnome_print_closepath (pc);
1592 gl_debug (DEBUG_PRINT, "END");
1596 create_rounded_rectangle_path (GnomePrintContext *pc,
1606 gl_debug (DEBUG_PRINT, "START");
1608 gnome_print_newpath (pc);
1610 gnome_print_moveto (pc, x0 + r, y0);
1611 for (i_theta = ARC_COURSE; i_theta <= 90; i_theta += ARC_COURSE) {
1612 x = x0 + r - r * sin (i_theta * G_PI / 180.0);
1613 y = y0 + r - r * cos (i_theta * G_PI / 180.0);
1614 gnome_print_lineto (pc, x, y);
1616 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1617 x = x0 + r - r * cos (i_theta * G_PI / 180.0);
1618 y = y0 + (h - r) + r * sin (i_theta * G_PI / 180.0);
1619 gnome_print_lineto (pc, x, y);
1621 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1622 x = x0 + (w - r) + r * sin (i_theta * G_PI / 180.0);
1623 y = y0 + (h - r) + r * cos (i_theta * G_PI / 180.0);
1624 gnome_print_lineto (pc, x, y);
1626 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1627 x = x0 + (w - r) + r * cos (i_theta * G_PI / 180.0);
1628 y = y0 + r - r * sin (i_theta * G_PI / 180.0);
1629 gnome_print_lineto (pc, x, y);
1631 gnome_print_lineto (pc, x0 + r, y0);
1633 gnome_print_closepath (pc);
1635 gl_debug (DEBUG_PRINT, "END");
1639 create_clipped_circle_path (GnomePrintContext *pc,
1647 gdouble theta1, theta2;
1650 gl_debug (DEBUG_PRINT, "START");
1652 theta1 = (180.0/G_PI) * acos (w / (2.0*r));
1653 theta2 = (180.0/G_PI) * asin (h / (2.0*r));
1655 gnome_print_newpath (pc);
1657 x = x0 + r * cos (theta1 * G_PI / 180.0);
1658 y = y0 + r * sin (theta1 * G_PI / 180.0);
1659 gnome_print_moveto (pc, x, y);
1661 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1662 x = x0 + r * cos (i_theta * G_PI / 180.0);
1663 y = y0 + r * sin (i_theta * G_PI / 180.0);
1664 gnome_print_lineto (pc, x, y);
1667 x = x0 + r * cos (theta2 * G_PI / 180.0);
1668 y = y0 + r * sin (theta2 * G_PI / 180.0);
1669 gnome_print_lineto (pc, x, y);
1671 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1672 x = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1673 y = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1674 gnome_print_lineto (pc, x, y);
1677 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1678 x = x0 + r * cos (i_theta * G_PI / 180.0);
1679 y = y0 + r * sin (i_theta * G_PI / 180.0);
1680 gnome_print_lineto (pc, x, y);
1683 x = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1684 y = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1685 gnome_print_lineto (pc, x, y);
1687 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1688 x = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1689 y = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1690 gnome_print_lineto (pc, x, y);
1693 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1694 x = x0 + r * cos (i_theta * G_PI / 180.0);
1695 y = y0 + r * sin (i_theta * G_PI / 180.0);
1696 gnome_print_lineto (pc, x, y);
1699 x = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1700 y = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1701 gnome_print_lineto (pc, x, y);
1703 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1704 x = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1705 y = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1706 gnome_print_lineto (pc, x, y);
1709 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1710 x = x0 + r * cos (i_theta * G_PI / 180.0);
1711 y = y0 + r * sin (i_theta * G_PI / 180.0);
1712 gnome_print_lineto (pc, x, y);
1715 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1716 x = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1717 y = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1718 gnome_print_lineto (pc, x, y);
1721 x = x0 + r * cos (theta1 * G_PI / 180.0);
1722 y = y0 + r * sin (theta1 * G_PI / 180.0);
1723 gnome_print_lineto (pc, x, y);
1725 gnome_print_closepath (pc);
1727 gl_debug (DEBUG_PRINT, "END");
1730 #ifndef NO_ALPHA_HACK
1731 /*---------------------------------------------------------------------------*/
1732 /* PRIVATE. Extract a copy of rgba pixels, removing alpha by compositing */
1733 /* with a white background. */
1735 /* This is currently needed due to the lousy job gnome-print does in */
1736 /* rendering images with alpha channels to PS. This sacrafices the ability */
1737 /* to do compositing of images with other items in the background. */
1738 /*---------------------------------------------------------------------------*/
1740 get_pixels_as_rgb (const GdkPixbuf *pixbuf)
1742 gint bits_per_sample, channels;
1744 gint width, height, rowstride;
1746 guchar *buf_src, *buf_dest;
1747 guchar *p_src, *p_dest;
1750 gdouble alpha, beta;
1752 gl_debug (DEBUG_PRINT, "START");
1754 g_return_val_if_fail (pixbuf && GDK_IS_PIXBUF (pixbuf), NULL);
1756 /* extract pixels and parameters from pixbuf. */
1757 buf_src = gdk_pixbuf_get_pixels (pixbuf);
1758 bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
1759 channels = gdk_pixbuf_get_n_channels (pixbuf);
1760 has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
1761 width = gdk_pixbuf_get_width (pixbuf);
1762 height = gdk_pixbuf_get_height (pixbuf);
1763 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1765 /* validate assumptions about pixbuf. */
1766 g_return_val_if_fail (buf_src, NULL);
1767 g_return_val_if_fail (bits_per_sample == 8, NULL);
1768 g_return_val_if_fail (channels == 4, NULL);
1769 g_return_val_if_fail (has_alpha, NULL);
1770 g_return_val_if_fail (width > 0, NULL);
1771 g_return_val_if_fail (height > 0, NULL);
1772 g_return_val_if_fail (rowstride > 0, NULL);
1774 /* Allocate a destination buffer */
1775 bytes = height * rowstride;
1776 gl_debug (DEBUG_PRINT, "bytes = %d", bytes);
1777 buf_dest = g_try_malloc (bytes);
1781 gl_debug (DEBUG_PRINT, "buf_dest = %x", buf_dest);
1783 /* Copy pixels, transforming rgba to rgb by compositing with a white bg. */
1786 for ( iy=0; iy < height; iy++ ) {
1788 p_src = buf_src + iy*rowstride;
1789 p_dest = buf_dest + iy*rowstride;
1791 for ( ix=0; ix < width; ix++ ) {
1801 *p_dest++ = (guchar) (alpha*r + beta*255 + 0.5);
1802 *p_dest++ = (guchar) (alpha*g + beta*255 + 0.5);
1803 *p_dest++ = (guchar) (alpha*b + beta*255 + 0.5);
1809 gl_debug (DEBUG_PRINT, "START");