2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * print.c: Print module
6 * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "label-text.h"
32 #include "label-box.h"
33 #include "label-line.h"
34 #include "label-ellipse.h"
35 #include "label-image.h"
36 #include "label-barcode.h"
43 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
44 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
46 /*=========================================================================*/
48 /*=========================================================================*/
50 typedef struct _PrintInfo {
51 /* gnome print context */
52 GnomePrintContext *pc;
54 /* gnome print configuration */
55 GnomePrintConfig *config;
57 /* gLabels Template */
59 gboolean label_rotate_flag;
70 /*=========================================================================*/
71 /* Private function prototypes. */
72 /*=========================================================================*/
73 static PrintInfo *print_info_new (GnomePrintJob *job,
76 static void print_info_free (PrintInfo **pi);
79 static void print_page_begin (PrintInfo *pi);
81 static void print_page_end (PrintInfo *pi);
83 static void print_label (PrintInfo *pi,
87 glMergeRecord *record,
88 gboolean outline_flag,
89 gboolean reverse_flag);
92 static void draw_label (PrintInfo *pi,
94 glMergeRecord *record);
97 static void draw_object (PrintInfo *pi,
98 glLabelObject *object,
99 glMergeRecord *record);
101 static void draw_text_object (PrintInfo *pi,
103 glMergeRecord *record);
105 static void draw_box_object (PrintInfo *pi,
108 static void draw_line_object (PrintInfo *pi,
109 glLabelLine *object);
111 static void draw_ellipse_object (PrintInfo *pi,
112 glLabelEllipse *object);
114 static void draw_image_object (PrintInfo *pi,
115 glLabelImage *object,
116 glMergeRecord *record);
118 static void draw_barcode_object (PrintInfo *pi,
119 glLabelBarcode *object,
120 glMergeRecord *record);
123 static void draw_outline (PrintInfo *pi,
126 static void clip_to_outline (PrintInfo *pi,
129 static void clip_punchouts (PrintInfo *pi,
133 static void create_rectangle_path (GnomePrintContext *pc,
139 static void create_ellipse_path (GnomePrintContext *pc,
145 static void create_rounded_rectangle_path (GnomePrintContext *pc,
152 static void create_clipped_circle_path (GnomePrintContext *pc,
160 /*****************************************************************************/
161 /* Simple (no merge data) print command. */
162 /*****************************************************************************/
164 gl_print_simple (GnomePrintJob *job,
169 gboolean outline_flag,
170 gboolean reverse_flag)
173 gint i_sheet, i_label;
174 glTemplateOrigin *origins;
176 gl_debug (DEBUG_PRINT, "START");
178 pi = print_info_new (job, label);
180 origins = gl_template_get_origins (pi->template);
182 for (i_sheet = 0; i_sheet < n_sheets; i_sheet++) {
184 print_page_begin (pi);
186 for (i_label = first - 1; i_label < last; i_label++) {
188 print_label (pi, label,
189 origins[i_label].x, origins[i_label].y,
190 NULL, outline_flag, reverse_flag);
199 print_info_free (&pi);
201 gl_debug (DEBUG_PRINT, "END");
204 /*****************************************************************************/
205 /* Merge print command (collated copies) */
206 /*****************************************************************************/
208 gl_print_merge_collated (GnomePrintJob *job,
212 gboolean outline_flag,
213 gboolean reverse_flag)
216 const GList *record_list;
218 gint i_sheet, i_label, n_labels_per_page, i_copy;
219 glMergeRecord *record;
221 glTemplateOrigin *origins;
223 gl_debug (DEBUG_PRINT, "START");
225 merge = gl_label_get_merge (label);
226 record_list = gl_merge_get_record_list (merge);
228 pi = print_info_new (job, label);
230 n_labels_per_page = gl_template_get_n_labels (pi->template);
231 origins = gl_template_get_origins (pi->template);
236 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
237 record = (glMergeRecord *)p->data;
239 if ( record->select_flag ) {
240 for (i_copy = 0; i_copy < n_copies; i_copy++) {
242 if ((i_label == 0) || (i_sheet == 0)) {
244 print_page_begin (pi);
247 print_label (pi, label,
251 outline_flag, reverse_flag);
253 i_label = (i_label + 1) % n_labels_per_page;
267 print_info_free (&pi);
269 gl_debug (DEBUG_PRINT, "END");
272 /*****************************************************************************/
273 /* Merge print command (uncollated copies) */
274 /*****************************************************************************/
276 gl_print_merge_uncollated (GnomePrintJob *job,
280 gboolean outline_flag,
281 gboolean reverse_flag)
284 const GList *record_list;
286 gint i_sheet, i_label, n_labels_per_page, i_copy;
287 glMergeRecord *record;
289 glTemplateOrigin *origins;
291 gl_debug (DEBUG_PRINT, "START");
293 merge = gl_label_get_merge (label);
294 record_list = gl_merge_get_record_list (merge);
296 pi = print_info_new (job, label);
298 n_labels_per_page = gl_template_get_n_labels (pi->template);
299 origins = gl_template_get_origins (pi->template);
304 for (i_copy = 0; i_copy < n_copies; i_copy++) {
306 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
307 record = (glMergeRecord *)p->data;
309 if ( record->select_flag ) {
312 if ((i_label == 0) || (i_sheet == 0)) {
314 print_page_begin (pi);
317 print_label (pi, label,
321 outline_flag, reverse_flag);
323 i_label = (i_label + 1) % n_labels_per_page;
337 print_info_free (&pi);
339 gl_debug (DEBUG_PRINT, "END");
342 /*****************************************************************************/
343 /* Batch print. Call appropriate function above. */
344 /*****************************************************************************/
346 gl_print_batch (GnomePrintJob *job,
350 gboolean outline_flag,
351 gboolean reverse_flag)
355 glTemplate *template;
357 gl_debug (DEBUG_PRINT, "START");
359 merge = gl_label_get_merge (label);
360 template = gl_label_get_template (label);
362 if ( merge == NULL ) {
363 n_per_page = gl_template_get_n_labels(template);
365 gl_print_simple (job, label, n_sheets, 1, n_per_page,
366 outline_flag, reverse_flag);
368 gl_print_merge_collated (job, label, n_copies, 1,
369 outline_flag, reverse_flag);
371 gl_template_free (&template);
373 g_object_unref (G_OBJECT(merge));
375 gl_debug (DEBUG_PRINT, "END");
378 /*---------------------------------------------------------------------------*/
379 /* PRIVATE. new print info structure */
380 /*---------------------------------------------------------------------------*/
382 print_info_new (GnomePrintJob *job,
385 PrintInfo *pi = g_new0 (PrintInfo, 1);
386 glTemplate *template;
388 gl_debug (DEBUG_PRINT, "START");
390 g_return_val_if_fail (job && GNOME_IS_PRINT_JOB (job), NULL);
391 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
393 template = gl_label_get_template (label);
395 g_return_val_if_fail (template, NULL);
396 g_return_val_if_fail (template->page_size, NULL);
397 g_return_val_if_fail (template->page_width > 0, NULL);
398 g_return_val_if_fail (template->page_height > 0, NULL);
400 pi->pc = gnome_print_job_get_context (job);
401 pi->config = gnome_print_job_get_config (job);
403 gl_debug (DEBUG_PRINT,
404 "setting page size = \"%s\"", template->page_size);
406 gnome_print_config_set_length (pi->config,
407 GNOME_PRINT_KEY_PAPER_WIDTH,
408 template->page_width,
409 GNOME_PRINT_PS_UNIT);
410 gnome_print_config_set_length (pi->config,
411 GNOME_PRINT_KEY_PAPER_HEIGHT,
412 template->page_height,
413 GNOME_PRINT_PS_UNIT);
415 pi->page_width = template->page_width;
416 pi->page_height = template->page_height;
418 pi->template = template;
419 pi->label_rotate_flag = gl_label_get_rotate_flag (label);
423 gl_debug (DEBUG_PRINT, "END");
428 /*---------------------------------------------------------------------------*/
429 /* PRIVATE. free print info structure */
430 /*---------------------------------------------------------------------------*/
432 print_info_free (PrintInfo **pi)
434 gl_debug (DEBUG_PRINT, "START");
436 gl_template_free (&(*pi)->template);
438 gnome_print_context_close ((*pi)->pc);
443 gl_debug (DEBUG_PRINT, "END");
446 /*---------------------------------------------------------------------------*/
447 /* PRIVATE. Begin a new page. */
448 /*---------------------------------------------------------------------------*/
450 print_page_begin (PrintInfo *pi)
454 gl_debug (DEBUG_PRINT, "START");
458 str = g_strdup_printf ("sheet%02d", pi->sheet);
459 gnome_print_beginpage (pi->pc, str);
462 /* Translate and scale, so that our origin is at the upper left. */
463 gnome_print_translate (pi->pc, 0.0, pi->page_height);
464 gnome_print_scale (pi->pc, 1.0, -1.0);
466 gl_debug (DEBUG_PRINT, "END");
469 /*---------------------------------------------------------------------------*/
470 /* PRIVATE. End a page. */
471 /*---------------------------------------------------------------------------*/
473 print_page_end (PrintInfo *pi)
475 gl_debug (DEBUG_PRINT, "START");
477 gnome_print_showpage (pi->pc);
479 gl_debug (DEBUG_PRINT, "END");
482 /*---------------------------------------------------------------------------*/
483 /* PRIVATE. Print i'th label. */
484 /*---------------------------------------------------------------------------*/
486 print_label (PrintInfo *pi,
490 glMergeRecord *record,
491 gboolean outline_flag,
492 gboolean reverse_flag)
494 gdouble width, height;
495 glTemplate *template;
497 gl_debug (DEBUG_PRINT, "START");
499 template = gl_label_get_template (label);
501 gl_label_get_size (label, &width, &height);
503 gnome_print_gsave (pi->pc);
505 /* Transform coordinate system to be relative to upper corner */
506 /* of the current label */
507 gnome_print_translate (pi->pc, x, y);
508 if (gl_label_get_rotate_flag (label)) {
509 gl_debug (DEBUG_PRINT, "Rotate flag set");
510 gnome_print_rotate (pi->pc, -90.0);
511 gnome_print_translate (pi->pc, -width, 0.0);
513 if ( reverse_flag ) {
514 gnome_print_translate (pi->pc, width, 0.0);
515 gnome_print_scale (pi->pc, -1.0, 1.0);
518 clip_to_outline (pi, label);
519 draw_label (pi, label, record);
521 draw_outline (pi, label);
523 clip_punchouts (pi, label);
525 gnome_print_grestore (pi->pc);
527 gl_template_free (&template);
529 gl_debug (DEBUG_PRINT, "END");
532 /*---------------------------------------------------------------------------*/
533 /* PRIVATE. Draw label. */
534 /*---------------------------------------------------------------------------*/
536 draw_label (PrintInfo *pi,
538 glMergeRecord *record)
541 glLabelObject *object;
543 gl_debug (DEBUG_PRINT, "START");
545 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
546 object = (glLabelObject *) p_obj->data;
548 draw_object (pi, object, record);
551 gl_debug (DEBUG_PRINT, "END");
554 /*---------------------------------------------------------------------------*/
555 /* PRIVATE. Draw object. */
556 /*---------------------------------------------------------------------------*/
558 draw_object (PrintInfo *pi,
559 glLabelObject *object,
560 glMergeRecord *record)
565 gl_debug (DEBUG_PRINT, "START");
567 gl_label_object_get_position (object, &x0, &y0);
568 gl_label_object_get_affine (object, affine);
570 gnome_print_gsave (pi->pc);
572 gnome_print_translate (pi->pc, x0, y0);
573 gnome_print_concat (pi->pc, affine);
575 if (GL_IS_LABEL_TEXT(object)) {
576 draw_text_object (pi, GL_LABEL_TEXT(object), record);
577 } else if (GL_IS_LABEL_BOX(object)) {
578 draw_box_object (pi, GL_LABEL_BOX(object));
579 } else if (GL_IS_LABEL_LINE(object)) {
580 draw_line_object (pi, GL_LABEL_LINE(object));
581 } else if (GL_IS_LABEL_ELLIPSE(object)) {
582 draw_ellipse_object (pi, GL_LABEL_ELLIPSE(object));
583 } else if (GL_IS_LABEL_IMAGE(object)) {
584 draw_image_object (pi, GL_LABEL_IMAGE(object), record);
585 } else if (GL_IS_LABEL_BARCODE(object)) {
586 draw_barcode_object (pi, GL_LABEL_BARCODE(object), record);
589 gnome_print_grestore (pi->pc);
591 gl_debug (DEBUG_PRINT, "END");
594 /*---------------------------------------------------------------------------*/
595 /* PRIVATE. Draw text object. */
596 /*---------------------------------------------------------------------------*/
598 draw_text_object (PrintInfo *pi,
600 glMergeRecord *record)
605 gdouble x_offset, y_offset, w, object_w, object_h;
610 GnomeFontWeight font_weight;
611 gboolean font_italic_flag;
613 GtkJustification just;
614 GnomeGlyphList *glyphlist;
619 gl_debug (DEBUG_PRINT, "START");
621 gl_label_object_get_size (GL_LABEL_OBJECT(object), &object_w, &object_h);
622 lines = gl_label_text_get_lines (object);
623 gl_label_text_get_props (object,
624 &font_family, &font_size, &font_weight,
628 font = gnome_font_find_closest_from_weight_slant (
633 gnome_print_setfont (pi->pc, font);
635 gnome_print_setrgbcolor (pi->pc,
636 GL_COLOR_F_RED (color),
637 GL_COLOR_F_GREEN (color),
638 GL_COLOR_F_BLUE (color));
639 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (color));
641 text = gl_text_node_lines_expand (lines, record);
642 line = g_strsplit (text, "\n", -1);
645 art_affine_identity (affine);
647 for (i = 0; line[i] != NULL; i++) {
649 glyphlist = gnome_glyphlist_from_text_dumb (font, color,
653 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
657 case GTK_JUSTIFY_LEFT:
658 x_offset = GL_LABEL_TEXT_MARGIN;
660 case GTK_JUSTIFY_CENTER:
661 x_offset = (object_w - GL_LABEL_TEXT_MARGIN - w) / 2.0;
663 case GTK_JUSTIFY_RIGHT:
664 x_offset = object_w - GL_LABEL_TEXT_MARGIN - w;
668 break; /* shouldn't happen */
671 y_offset = GL_LABEL_TEXT_MARGIN + (i + 1) * font_size
672 + gnome_font_get_descender (font);
674 gnome_print_moveto (pi->pc, x_offset, y_offset);
676 gnome_print_gsave (pi->pc);
677 gnome_print_scale (pi->pc, 1.0, -1.0);
678 gnome_print_show (pi->pc, line[i]);
679 gnome_print_grestore (pi->pc);
684 gl_text_node_lines_free (&lines);
685 g_free (font_family);
687 gl_debug (DEBUG_PRINT, "END");
690 /*---------------------------------------------------------------------------*/
691 /* PRIVATE. Draw box object. */
692 /*---------------------------------------------------------------------------*/
694 draw_box_object (PrintInfo *pi,
699 guint line_color, fill_color;
701 gl_debug (DEBUG_PRINT, "START");
703 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
704 line_width = gl_label_box_get_line_width (object);
705 line_color = gl_label_box_get_line_color (object);
706 fill_color = gl_label_box_get_fill_color (object);
708 /* Paint fill color */
709 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
710 gnome_print_setrgbcolor (pi->pc,
711 GL_COLOR_F_RED (fill_color),
712 GL_COLOR_F_GREEN (fill_color),
713 GL_COLOR_F_BLUE (fill_color));
714 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
715 gnome_print_fill (pi->pc);
718 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
719 gnome_print_setrgbcolor (pi->pc,
720 GL_COLOR_F_RED (line_color),
721 GL_COLOR_F_GREEN (line_color),
722 GL_COLOR_F_BLUE (line_color));
723 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
724 gnome_print_setlinewidth (pi->pc, line_width);
725 gnome_print_stroke (pi->pc);
727 gl_debug (DEBUG_PRINT, "END");
730 /*---------------------------------------------------------------------------*/
731 /* PRIVATE. Draw line object. */
732 /*---------------------------------------------------------------------------*/
734 draw_line_object (PrintInfo *pi,
741 gl_debug (DEBUG_PRINT, "START");
743 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
744 line_width = gl_label_line_get_line_width (object);
745 line_color = gl_label_line_get_line_color (object);
747 gnome_print_moveto (pi->pc, 0.0, 0.0);
748 gnome_print_lineto (pi->pc, w, h);
749 gnome_print_setrgbcolor (pi->pc,
750 GL_COLOR_F_RED (line_color),
751 GL_COLOR_F_GREEN (line_color),
752 GL_COLOR_F_BLUE (line_color));
753 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
754 gnome_print_setlinewidth (pi->pc, line_width);
755 gnome_print_stroke (pi->pc);
757 gl_debug (DEBUG_PRINT, "END");
760 /*---------------------------------------------------------------------------*/
761 /* PRIVATE. Draw ellipse object. */
762 /*---------------------------------------------------------------------------*/
764 draw_ellipse_object (PrintInfo *pi,
765 glLabelEllipse *object)
767 gdouble x0, y0, rx, ry, w, h;
769 guint line_color, fill_color;
771 gl_debug (DEBUG_PRINT, "START");
773 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
774 line_width = gl_label_ellipse_get_line_width (object);
775 line_color = gl_label_ellipse_get_line_color (object);
776 fill_color = gl_label_ellipse_get_fill_color (object);
783 /* Paint fill color */
784 create_ellipse_path (pi->pc, x0, y0, rx, ry);
785 gnome_print_setrgbcolor (pi->pc,
786 GL_COLOR_F_RED (fill_color),
787 GL_COLOR_F_GREEN (fill_color),
788 GL_COLOR_F_BLUE (fill_color));
789 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
790 gnome_print_fill (pi->pc);
793 create_ellipse_path (pi->pc, x0, y0, rx, ry);
794 gnome_print_setrgbcolor (pi->pc,
795 GL_COLOR_F_RED (line_color),
796 GL_COLOR_F_GREEN (line_color),
797 GL_COLOR_F_BLUE (line_color));
798 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
799 gnome_print_setlinewidth (pi->pc, line_width);
800 gnome_print_stroke (pi->pc);
802 gl_debug (DEBUG_PRINT, "END");
805 /*---------------------------------------------------------------------------*/
806 /* PRIVATE. Draw image object. */
807 /*---------------------------------------------------------------------------*/
809 draw_image_object (PrintInfo *pi,
810 glLabelImage *object,
811 glMergeRecord *record)
814 const GdkPixbuf *pixbuf;
816 gint image_w, image_h, image_stride;
817 gboolean image_alpha_flag;
820 gl_debug (DEBUG_PRINT, "START");
822 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
824 pixbuf = gl_label_image_get_pixbuf (object, record);
825 image_data = gdk_pixbuf_get_pixels (pixbuf);
826 image_w = gdk_pixbuf_get_width (pixbuf);
827 image_h = gdk_pixbuf_get_height (pixbuf);
828 image_stride = gdk_pixbuf_get_rowstride(pixbuf);
829 image_alpha_flag = gdk_pixbuf_get_has_alpha(pixbuf);
831 gnome_print_gsave (pi->pc);
832 gnome_print_translate (pi->pc, 0.0, h);
833 gnome_print_scale (pi->pc, w, -h);
834 if (image_alpha_flag) {
835 ret = gnome_print_rgbaimage (pi->pc, image_data,
836 image_w, image_h, image_stride);
837 gl_debug (DEBUG_PRINT, "Ret a = %d", ret);
839 ret = gnome_print_rgbimage (pi->pc, image_data,
840 image_w, image_h, image_stride);
841 gl_debug (DEBUG_PRINT, "Ret = %d", ret);
843 gnome_print_grestore (pi->pc);
845 gl_debug (DEBUG_PRINT, "END");
848 /*---------------------------------------------------------------------------*/
849 /* PRIVATE. Draw box object. */
850 /*---------------------------------------------------------------------------*/
852 draw_barcode_object (PrintInfo *pi,
853 glLabelBarcode *object,
854 glMergeRecord *record)
858 glBarcodeChar *bchar;
862 gchar *text, *cstring;
863 glTextNode *text_node;
864 glBarcodeStyle style;
866 gboolean checksum_flag;
870 gl_debug (DEBUG_PRINT, "START");
872 text_node = gl_label_barcode_get_data (object);
873 gl_label_barcode_get_props (object,
874 &style, &text_flag, &checksum_flag, &color);
875 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
877 text = gl_text_node_expand (text_node, record);
878 gbc = gl_barcode_new (style, text_flag, checksum_flag, w, h, text);
880 gl_text_node_free (&text_node);
884 font = gnome_font_find_closest_from_weight_slant (
885 GL_BARCODE_FONT_FAMILY,
886 GL_BARCODE_FONT_WEIGHT,
888 gnome_print_setfont (pi->pc, font);
890 gnome_print_setrgbcolor (pi->pc,
891 GL_COLOR_F_RED (color),
892 GL_COLOR_F_GREEN (color),
893 GL_COLOR_F_BLUE (color));
894 gnome_print_setopacity (pi->pc,
895 GL_COLOR_F_ALPHA (color));
897 y_offset = 12.0 - gnome_font_get_descender (font);
898 gnome_print_moveto (pi->pc, 0.0, y_offset);
900 gnome_print_gsave (pi->pc);
901 gnome_print_scale (pi->pc, 1.0, -1.0);
902 gnome_print_show (pi->pc, _("Invalid barcode"));
903 gnome_print_grestore (pi->pc);
907 for (li = gbc->lines; li != NULL; li = li->next) {
908 line = (glBarcodeLine *) li->data;
910 gnome_print_moveto (pi->pc, line->x, line->y);
911 gnome_print_lineto (pi->pc, line->x, line->y + line->length);
912 gnome_print_setrgbcolor (pi->pc,
913 GL_COLOR_F_RED (color),
914 GL_COLOR_F_GREEN (color),
915 GL_COLOR_F_BLUE (color));
916 gnome_print_setopacity (pi->pc,
917 GL_COLOR_F_ALPHA (color));
918 gnome_print_setlinewidth (pi->pc, line->width);
919 gnome_print_stroke (pi->pc);
922 for (li = gbc->chars; li != NULL; li = li->next) {
923 bchar = (glBarcodeChar *) li->data;
925 font = gnome_font_find_closest_from_weight_slant (
926 GL_BARCODE_FONT_FAMILY,
927 GL_BARCODE_FONT_WEIGHT,
928 FALSE, bchar->fsize);
929 gnome_print_setfont (pi->pc, font);
931 gnome_print_setrgbcolor (pi->pc,
932 GL_COLOR_F_RED (color),
933 GL_COLOR_F_GREEN (color),
934 GL_COLOR_F_BLUE (color));
935 gnome_print_setopacity (pi->pc,
936 GL_COLOR_F_ALPHA (color));
939 bchar->y + bchar->fsize -
940 gnome_font_get_descender (font);
941 gnome_print_moveto (pi->pc, bchar->x, y_offset);
943 cstring = g_strdup_printf ("%c", bchar->c);
944 gnome_print_gsave (pi->pc);
945 gnome_print_scale (pi->pc, 1.0, -1.0);
946 gnome_print_show (pi->pc, cstring);
947 gnome_print_grestore (pi->pc);
952 gl_barcode_free (&gbc);
956 gl_debug (DEBUG_PRINT, "END");
959 /*---------------------------------------------------------------------------*/
960 /* PRIVATE. Draw outline. */
961 /*---------------------------------------------------------------------------*/
963 draw_outline (PrintInfo *pi,
968 glTemplate *template;
970 gl_debug (DEBUG_PRINT, "START");
972 template = gl_label_get_template (label);
974 gnome_print_setrgbcolor (pi->pc, 0.25, 0.25, 0.25);
975 gnome_print_setopacity (pi->pc, 1.0);
976 gnome_print_setlinewidth (pi->pc, 0.25);
978 switch (template->label.style) {
980 case GL_TEMPLATE_STYLE_RECT:
981 gl_label_get_size (label, &w, &h);
982 r = template->label.rect.r;
984 /* simple rectangle */
985 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
987 /* rectangle with rounded corners */
988 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
991 gnome_print_stroke (pi->pc);
994 case GL_TEMPLATE_STYLE_ROUND:
996 r1 = template->label.round.r;
997 create_ellipse_path (pi->pc, r1, r1, r1, r1);
998 gnome_print_stroke (pi->pc);
1001 case GL_TEMPLATE_STYLE_CD:
1002 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
1003 /* CD style, round label w/ concentric round hole */
1004 r1 = template->label.cd.r1;
1005 r2 = template->label.cd.r2;
1006 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1007 gnome_print_stroke (pi->pc);
1008 create_ellipse_path (pi->pc, r1, r1, r2, r2);
1009 gnome_print_stroke (pi->pc);
1011 /* Business Card CD style, clipped round label w/ hole */
1012 gl_label_get_size (label, &w, &h);
1013 r1 = template->label.cd.r1;
1014 r2 = template->label.cd.r2;
1015 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1016 gnome_print_stroke (pi->pc);
1017 create_ellipse_path (pi->pc, w/2, h/2, r2, r2);
1018 gnome_print_stroke (pi->pc);
1023 g_warning ("Unknown template label style");
1027 gl_template_free (&template);
1029 gl_debug (DEBUG_PRINT, "END");
1032 /*---------------------------------------------------------------------------*/
1033 /* PRIVATE. Clip to outline. */
1034 /*---------------------------------------------------------------------------*/
1036 clip_to_outline (PrintInfo *pi,
1042 glTemplate *template;
1044 gl_debug (DEBUG_PRINT, "START");
1046 template = gl_label_get_template (label);
1048 switch (template->label.style) {
1050 case GL_TEMPLATE_STYLE_RECT:
1051 gl_label_get_size (label, &w, &h);
1052 r = template->label.rect.r;
1053 waste = template->label.rect.waste;
1055 /* simple rectangle */
1056 create_rectangle_path (pi->pc, -waste, -waste, w+waste, h+waste);
1058 /* rectangle with rounded corners */
1059 create_rounded_rectangle_path (pi->pc, -waste, -waste,
1060 w+waste, h+waste, r);
1062 gnome_print_clip (pi->pc);
1065 case GL_TEMPLATE_STYLE_ROUND:
1066 r1 = template->label.round.r;
1067 waste = template->label.round.waste;
1068 create_ellipse_path (pi->pc, r1, r1, r1+waste, r1+waste);
1069 gnome_print_clip (pi->pc);
1072 case GL_TEMPLATE_STYLE_CD:
1073 waste = template->label.cd.waste;
1074 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
1075 /* CD style, round label w/ concentric round hole */
1076 r1 = template->label.cd.r1;
1077 create_ellipse_path (pi->pc, r1, r1, r1+waste, r1+waste);
1079 /* Business Card CD style, clipped round label w/ hole */
1080 gl_label_get_size (label, &w, &h);
1081 r1 = template->label.cd.r1;
1082 create_clipped_circle_path (pi->pc,
1084 w+2*waste, h+2*waste,
1087 gnome_print_clip (pi->pc);
1091 g_warning ("Unknown template label style");
1095 gl_template_free (&template);
1097 gl_debug (DEBUG_PRINT, "END");
1100 /*---------------------------------------------------------------------------*/
1101 /* PRIVATE. Clip punchouts. (Save some ink by not printing in CD holes) */
1103 /* Ideally this would be done in clip_to_outline, but I am not sure how to */
1104 /* invert the region for gnome_print_clip, so instead, I will just draw */
1105 /* a white circle on top of everything else. */
1106 /*---------------------------------------------------------------------------*/
1108 clip_punchouts (PrintInfo *pi,
1113 glTemplate *template;
1115 gl_debug (DEBUG_PRINT, "START");
1117 template = gl_label_get_template (label);
1119 switch (template->label.style) {
1121 case GL_TEMPLATE_STYLE_RECT:
1122 case GL_TEMPLATE_STYLE_ROUND:
1125 case GL_TEMPLATE_STYLE_CD:
1126 gl_label_get_size (label, &w, &h);
1127 waste = template->label.cd.waste;
1128 r2 = template->label.cd.r2;
1129 create_ellipse_path (pi->pc, w/2, h/2, r2-waste, r2-waste);
1130 gnome_print_setrgbcolor (pi->pc, 1.0, 1.0, 1.0);
1131 gnome_print_setopacity (pi->pc, 1.0);
1132 gnome_print_fill (pi->pc);
1136 g_warning ("Unknown template label style");
1140 gl_template_free (&template);
1142 gl_debug (DEBUG_PRINT, "END");
1145 /*---------------------------------------------------------------------------*/
1146 /* PRIVATE. Path creation utilities. */
1147 /*---------------------------------------------------------------------------*/
1149 create_rectangle_path (GnomePrintContext *pc,
1155 gl_debug (DEBUG_PRINT, "START");
1157 gnome_print_newpath (pc);
1158 gnome_print_moveto (pc, x0, y0);
1159 gnome_print_lineto (pc, x0 + w, y0);
1160 gnome_print_lineto (pc, x0 + w, y0 + h);
1161 gnome_print_lineto (pc, x0, y0 + h);
1162 gnome_print_lineto (pc, x0, y0);
1163 gnome_print_closepath (pc);
1165 gl_debug (DEBUG_PRINT, "END");
1169 create_ellipse_path (GnomePrintContext *pc,
1178 gl_debug (DEBUG_PRINT, "START");
1180 gnome_print_newpath (pc);
1181 gnome_print_moveto (pc, x0 + rx, y0);
1182 for (i_theta = ARC_FINE; i_theta <= 360; i_theta += ARC_FINE) {
1183 x = x0 + rx * cos (i_theta * G_PI / 180.0);
1184 y = y0 + ry * sin (i_theta * G_PI / 180.0);
1185 gnome_print_lineto (pc, x, y);
1187 gnome_print_closepath (pc);
1189 gl_debug (DEBUG_PRINT, "END");
1193 create_rounded_rectangle_path (GnomePrintContext *pc,
1203 gl_debug (DEBUG_PRINT, "START");
1205 gnome_print_newpath (pc);
1207 gnome_print_moveto (pc, x0 + r, y0);
1208 for (i_theta = ARC_COURSE; i_theta <= 90; i_theta += ARC_COURSE) {
1209 x = x0 + r - r * sin (i_theta * G_PI / 180.0);
1210 y = y0 + r - r * cos (i_theta * G_PI / 180.0);
1211 gnome_print_lineto (pc, x, y);
1213 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1214 x = x0 + r - r * cos (i_theta * G_PI / 180.0);
1215 y = y0 + (h - r) + r * sin (i_theta * G_PI / 180.0);
1216 gnome_print_lineto (pc, x, y);
1218 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1219 x = x0 + (w - r) + r * sin (i_theta * G_PI / 180.0);
1220 y = y0 + (h - r) + r * cos (i_theta * G_PI / 180.0);
1221 gnome_print_lineto (pc, x, y);
1223 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1224 x = x0 + (w - r) + r * cos (i_theta * G_PI / 180.0);
1225 y = y0 + r - r * sin (i_theta * G_PI / 180.0);
1226 gnome_print_lineto (pc, x, y);
1228 gnome_print_lineto (pc, x0 + r, y0);
1230 gnome_print_closepath (pc);
1232 gl_debug (DEBUG_PRINT, "END");
1236 create_clipped_circle_path (GnomePrintContext *pc,
1244 gdouble theta1, theta2;
1247 gl_debug (DEBUG_PRINT, "START");
1249 theta1 = (180.0/G_PI) * acos (w / (2.0*r));
1250 theta2 = (180.0/G_PI) * asin (h / (2.0*r));
1252 gnome_print_newpath (pc);
1254 x = x0 + r * cos (theta1 * G_PI / 180.0);
1255 y = y0 + r * sin (theta1 * G_PI / 180.0);
1256 gnome_print_moveto (pc, x, y);
1258 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1259 x = x0 + r * cos (i_theta * G_PI / 180.0);
1260 y = y0 + r * sin (i_theta * G_PI / 180.0);
1261 gnome_print_lineto (pc, x, y);
1264 x = x0 + r * cos (theta2 * G_PI / 180.0);
1265 y = y0 + r * sin (theta2 * G_PI / 180.0);
1266 gnome_print_lineto (pc, x, y);
1268 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1269 x = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1270 y = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1271 gnome_print_lineto (pc, x, y);
1274 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1275 x = x0 + r * cos (i_theta * G_PI / 180.0);
1276 y = y0 + r * sin (i_theta * G_PI / 180.0);
1277 gnome_print_lineto (pc, x, y);
1280 x = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1281 y = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1282 gnome_print_lineto (pc, x, y);
1284 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1285 x = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1286 y = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1287 gnome_print_lineto (pc, x, y);
1290 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1291 x = x0 + r * cos (i_theta * G_PI / 180.0);
1292 y = y0 + r * sin (i_theta * G_PI / 180.0);
1293 gnome_print_lineto (pc, x, y);
1296 x = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1297 y = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1298 gnome_print_lineto (pc, x, y);
1300 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1301 x = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1302 y = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1303 gnome_print_lineto (pc, x, y);
1306 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1307 x = x0 + r * cos (i_theta * G_PI / 180.0);
1308 y = y0 + r * sin (i_theta * G_PI / 180.0);
1309 gnome_print_lineto (pc, x, y);
1312 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1313 x = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1314 y = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1315 gnome_print_lineto (pc, x, y);
1318 x = x0 + r * cos (theta1 * G_PI / 180.0);
1319 y = y0 + r * sin (theta1 * G_PI / 180.0);
1320 gnome_print_lineto (pc, x, y);
1322 gnome_print_closepath (pc);
1324 gl_debug (DEBUG_PRINT, "END");