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,
130 static void create_rectangle_path (GnomePrintContext *pc,
136 static void create_ellipse_path (GnomePrintContext *pc,
142 static void create_rounded_rectangle_path (GnomePrintContext *pc,
149 static void create_clipped_circle_path (GnomePrintContext *pc,
157 /*****************************************************************************/
158 /* Simple (no merge data) print command. */
159 /*****************************************************************************/
161 gl_print_simple (GnomePrintJob *job,
166 gboolean outline_flag,
167 gboolean reverse_flag)
170 gint i_sheet, i_label;
171 glTemplateOrigin *origins;
173 gl_debug (DEBUG_PRINT, "START");
175 pi = print_info_new (job, label);
177 origins = gl_template_get_origins (pi->template);
179 for (i_sheet = 0; i_sheet < n_sheets; i_sheet++) {
181 print_page_begin (pi);
183 for (i_label = first - 1; i_label < last; i_label++) {
185 print_label (pi, label,
186 origins[i_label].x, origins[i_label].y,
187 NULL, outline_flag, reverse_flag);
196 print_info_free (&pi);
198 gl_debug (DEBUG_PRINT, "END");
201 /*****************************************************************************/
202 /* Merge print command (collated copies) */
203 /*****************************************************************************/
205 gl_print_merge_collated (GnomePrintJob *job,
209 gboolean outline_flag,
210 gboolean reverse_flag)
213 const GList *record_list;
215 gint i_sheet, i_label, n_labels_per_page, i_copy;
216 glMergeRecord *record;
218 glTemplateOrigin *origins;
220 gl_debug (DEBUG_PRINT, "START");
222 merge = gl_label_get_merge (label);
223 record_list = gl_merge_get_record_list (merge);
225 pi = print_info_new (job, label);
227 n_labels_per_page = gl_template_get_n_labels (pi->template);
228 origins = gl_template_get_origins (pi->template);
233 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
234 record = (glMergeRecord *)p->data;
236 if ( record->select_flag ) {
237 for (i_copy = 0; i_copy < n_copies; i_copy++) {
239 if ((i_label == 0) || (i_sheet == 0)) {
241 print_page_begin (pi);
244 print_label (pi, label,
248 outline_flag, reverse_flag);
250 i_label = (i_label + 1) % n_labels_per_page;
264 print_info_free (&pi);
266 gl_debug (DEBUG_PRINT, "END");
269 /*****************************************************************************/
270 /* Merge print command (uncollated copies) */
271 /*****************************************************************************/
273 gl_print_merge_uncollated (GnomePrintJob *job,
277 gboolean outline_flag,
278 gboolean reverse_flag)
281 const GList *record_list;
283 gint i_sheet, i_label, n_labels_per_page, i_copy;
284 glMergeRecord *record;
286 glTemplateOrigin *origins;
288 gl_debug (DEBUG_PRINT, "START");
290 merge = gl_label_get_merge (label);
291 record_list = gl_merge_get_record_list (merge);
293 pi = print_info_new (job, label);
295 n_labels_per_page = gl_template_get_n_labels (pi->template);
296 origins = gl_template_get_origins (pi->template);
301 for (i_copy = 0; i_copy < n_copies; i_copy++) {
303 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
304 record = (glMergeRecord *)p->data;
306 if ( record->select_flag ) {
309 if ((i_label == 0) || (i_sheet == 0)) {
311 print_page_begin (pi);
314 print_label (pi, label,
318 outline_flag, reverse_flag);
320 i_label = (i_label + 1) % n_labels_per_page;
334 print_info_free (&pi);
336 gl_debug (DEBUG_PRINT, "END");
339 /*****************************************************************************/
340 /* Batch print. Call appropriate function above. */
341 /*****************************************************************************/
343 gl_print_batch (GnomePrintJob *job,
347 gboolean outline_flag,
348 gboolean reverse_flag)
352 glTemplate *template;
354 gl_debug (DEBUG_PRINT, "START");
356 merge = gl_label_get_merge (label);
357 template = gl_label_get_template (label);
359 if ( merge == NULL ) {
360 n_per_page = gl_template_get_n_labels(template);
362 gl_print_simple (job, label, n_sheets, 1, n_per_page,
363 outline_flag, reverse_flag);
365 gl_print_merge_collated (job, label, n_copies, 1,
366 outline_flag, reverse_flag);
368 gl_template_free (&template);
370 g_object_unref (G_OBJECT(merge));
372 gl_debug (DEBUG_PRINT, "END");
375 /*---------------------------------------------------------------------------*/
376 /* PRIVATE. new print info structure */
377 /*---------------------------------------------------------------------------*/
379 print_info_new (GnomePrintJob *job,
382 PrintInfo *pi = g_new0 (PrintInfo, 1);
383 glTemplate *template;
385 gl_debug (DEBUG_PRINT, "START");
387 g_return_val_if_fail (job && GNOME_IS_PRINT_JOB (job), NULL);
388 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
390 template = gl_label_get_template (label);
392 g_return_val_if_fail (template, NULL);
393 g_return_val_if_fail (template->page_size, NULL);
394 g_return_val_if_fail (template->page_width > 0, NULL);
395 g_return_val_if_fail (template->page_height > 0, NULL);
397 pi->pc = gnome_print_job_get_context (job);
398 pi->config = gnome_print_job_get_config (job);
400 gl_debug (DEBUG_PRINT,
401 "setting page size = \"%s\"", template->page_size);
403 gnome_print_config_set_length (pi->config,
404 GNOME_PRINT_KEY_PAPER_WIDTH,
405 template->page_width,
406 GNOME_PRINT_PS_UNIT);
407 gnome_print_config_set_length (pi->config,
408 GNOME_PRINT_KEY_PAPER_HEIGHT,
409 template->page_height,
410 GNOME_PRINT_PS_UNIT);
412 pi->page_width = template->page_width;
413 pi->page_height = template->page_height;
415 pi->template = template;
416 pi->label_rotate_flag = gl_label_get_rotate_flag (label);
420 gl_debug (DEBUG_PRINT, "END");
425 /*---------------------------------------------------------------------------*/
426 /* PRIVATE. free print info structure */
427 /*---------------------------------------------------------------------------*/
429 print_info_free (PrintInfo **pi)
431 gl_debug (DEBUG_PRINT, "START");
433 gl_template_free (&(*pi)->template);
435 gnome_print_context_close ((*pi)->pc);
440 gl_debug (DEBUG_PRINT, "END");
443 /*---------------------------------------------------------------------------*/
444 /* PRIVATE. Begin a new page. */
445 /*---------------------------------------------------------------------------*/
447 print_page_begin (PrintInfo *pi)
451 gl_debug (DEBUG_PRINT, "START");
455 str = g_strdup_printf ("sheet%02d", pi->sheet);
456 gnome_print_beginpage (pi->pc, str);
459 /* Translate and scale, so that our origin is at the upper left. */
460 gnome_print_translate (pi->pc, 0.0, pi->page_height);
461 gnome_print_scale (pi->pc, 1.0, -1.0);
463 gl_debug (DEBUG_PRINT, "END");
466 /*---------------------------------------------------------------------------*/
467 /* PRIVATE. End a page. */
468 /*---------------------------------------------------------------------------*/
470 print_page_end (PrintInfo *pi)
472 gl_debug (DEBUG_PRINT, "START");
474 gnome_print_showpage (pi->pc);
476 gl_debug (DEBUG_PRINT, "END");
479 /*---------------------------------------------------------------------------*/
480 /* PRIVATE. Print i'th label. */
481 /*---------------------------------------------------------------------------*/
483 print_label (PrintInfo *pi,
487 glMergeRecord *record,
488 gboolean outline_flag,
489 gboolean reverse_flag)
491 gdouble width, height;
492 glTemplate *template;
494 gl_debug (DEBUG_PRINT, "START");
496 template = gl_label_get_template (label);
498 gl_label_get_size (label, &width, &height);
500 gnome_print_gsave (pi->pc);
502 /* Transform coordinate system to be relative to upper corner */
503 /* of the current label */
504 gnome_print_translate (pi->pc, x, y);
505 if (gl_label_get_rotate_flag (label)) {
506 gl_debug (DEBUG_PRINT, "Rotate flag set");
507 gnome_print_rotate (pi->pc, -90.0);
508 gnome_print_translate (pi->pc, -width, 0.0);
510 if ( reverse_flag ) {
511 gnome_print_translate (pi->pc, width, 0.0);
512 gnome_print_scale (pi->pc, -1.0, 1.0);
515 draw_outline (pi, label);
517 clip_to_outline (pi, label);
518 draw_label (pi, label, record);
520 gnome_print_grestore (pi->pc);
522 gl_template_free (&template);
524 gl_debug (DEBUG_PRINT, "END");
527 /*---------------------------------------------------------------------------*/
528 /* PRIVATE. Draw label. */
529 /*---------------------------------------------------------------------------*/
531 draw_label (PrintInfo *pi,
533 glMergeRecord *record)
536 glLabelObject *object;
538 gl_debug (DEBUG_PRINT, "START");
540 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
541 object = (glLabelObject *) p_obj->data;
543 draw_object (pi, object, record);
546 gl_debug (DEBUG_PRINT, "END");
549 /*---------------------------------------------------------------------------*/
550 /* PRIVATE. Draw object. */
551 /*---------------------------------------------------------------------------*/
553 draw_object (PrintInfo *pi,
554 glLabelObject *object,
555 glMergeRecord *record)
560 gl_debug (DEBUG_PRINT, "START");
562 gl_label_object_get_position (object, &x0, &y0);
563 gl_label_object_get_affine (object, affine);
565 gnome_print_gsave (pi->pc);
567 gnome_print_translate (pi->pc, x0, y0);
568 gnome_print_concat (pi->pc, affine);
570 if (GL_IS_LABEL_TEXT(object)) {
571 draw_text_object (pi, GL_LABEL_TEXT(object), record);
572 } else if (GL_IS_LABEL_BOX(object)) {
573 draw_box_object (pi, GL_LABEL_BOX(object));
574 } else if (GL_IS_LABEL_LINE(object)) {
575 draw_line_object (pi, GL_LABEL_LINE(object));
576 } else if (GL_IS_LABEL_ELLIPSE(object)) {
577 draw_ellipse_object (pi, GL_LABEL_ELLIPSE(object));
578 } else if (GL_IS_LABEL_IMAGE(object)) {
579 draw_image_object (pi, GL_LABEL_IMAGE(object), record);
580 } else if (GL_IS_LABEL_BARCODE(object)) {
581 draw_barcode_object (pi, GL_LABEL_BARCODE(object), record);
584 gnome_print_grestore (pi->pc);
586 gl_debug (DEBUG_PRINT, "END");
589 /*---------------------------------------------------------------------------*/
590 /* PRIVATE. Draw text object. */
591 /*---------------------------------------------------------------------------*/
593 draw_text_object (PrintInfo *pi,
595 glMergeRecord *record)
600 gdouble x_offset, y_offset, w, object_w, object_h;
605 GnomeFontWeight font_weight;
606 gboolean font_italic_flag;
608 GtkJustification just;
609 GnomeGlyphList *glyphlist;
614 gl_debug (DEBUG_PRINT, "START");
616 gl_label_object_get_size (GL_LABEL_OBJECT(object), &object_w, &object_h);
617 lines = gl_label_text_get_lines (object);
618 gl_label_text_get_props (object,
619 &font_family, &font_size, &font_weight,
623 font = gnome_font_find_closest_from_weight_slant (
628 gnome_print_setfont (pi->pc, font);
630 gnome_print_setrgbcolor (pi->pc,
631 GL_COLOR_F_RED (color),
632 GL_COLOR_F_GREEN (color),
633 GL_COLOR_F_BLUE (color));
634 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (color));
636 text = gl_text_node_lines_expand (lines, record);
637 line = g_strsplit (text, "\n", -1);
640 art_affine_identity (affine);
642 for (i = 0; line[i] != NULL; i++) {
644 glyphlist = gnome_glyphlist_from_text_dumb (font, color,
648 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
652 case GTK_JUSTIFY_LEFT:
653 x_offset = GL_LABEL_TEXT_MARGIN;
655 case GTK_JUSTIFY_CENTER:
656 x_offset = (object_w - GL_LABEL_TEXT_MARGIN - w) / 2.0;
658 case GTK_JUSTIFY_RIGHT:
659 x_offset = object_w - GL_LABEL_TEXT_MARGIN - w;
663 break; /* shouldn't happen */
666 y_offset = GL_LABEL_TEXT_MARGIN + (i + 1) * font_size
667 + gnome_font_get_descender (font);
669 gnome_print_moveto (pi->pc, x_offset, y_offset);
671 gnome_print_gsave (pi->pc);
672 gnome_print_scale (pi->pc, 1.0, -1.0);
673 gnome_print_show (pi->pc, line[i]);
674 gnome_print_grestore (pi->pc);
679 gl_text_node_lines_free (&lines);
680 g_free (font_family);
682 gl_debug (DEBUG_PRINT, "END");
685 /*---------------------------------------------------------------------------*/
686 /* PRIVATE. Draw box object. */
687 /*---------------------------------------------------------------------------*/
689 draw_box_object (PrintInfo *pi,
694 guint line_color, fill_color;
696 gl_debug (DEBUG_PRINT, "START");
698 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
699 line_width = gl_label_box_get_line_width (object);
700 line_color = gl_label_box_get_line_color (object);
701 fill_color = gl_label_box_get_fill_color (object);
703 /* Paint fill color */
704 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
705 gnome_print_setrgbcolor (pi->pc,
706 GL_COLOR_F_RED (fill_color),
707 GL_COLOR_F_GREEN (fill_color),
708 GL_COLOR_F_BLUE (fill_color));
709 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
710 gnome_print_fill (pi->pc);
713 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
714 gnome_print_setrgbcolor (pi->pc,
715 GL_COLOR_F_RED (line_color),
716 GL_COLOR_F_GREEN (line_color),
717 GL_COLOR_F_BLUE (line_color));
718 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
719 gnome_print_setlinewidth (pi->pc, line_width);
720 gnome_print_stroke (pi->pc);
722 gl_debug (DEBUG_PRINT, "END");
725 /*---------------------------------------------------------------------------*/
726 /* PRIVATE. Draw line object. */
727 /*---------------------------------------------------------------------------*/
729 draw_line_object (PrintInfo *pi,
736 gl_debug (DEBUG_PRINT, "START");
738 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
739 line_width = gl_label_line_get_line_width (object);
740 line_color = gl_label_line_get_line_color (object);
742 gnome_print_moveto (pi->pc, 0.0, 0.0);
743 gnome_print_lineto (pi->pc, w, h);
744 gnome_print_setrgbcolor (pi->pc,
745 GL_COLOR_F_RED (line_color),
746 GL_COLOR_F_GREEN (line_color),
747 GL_COLOR_F_BLUE (line_color));
748 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
749 gnome_print_setlinewidth (pi->pc, line_width);
750 gnome_print_stroke (pi->pc);
752 gl_debug (DEBUG_PRINT, "END");
755 /*---------------------------------------------------------------------------*/
756 /* PRIVATE. Draw ellipse object. */
757 /*---------------------------------------------------------------------------*/
759 draw_ellipse_object (PrintInfo *pi,
760 glLabelEllipse *object)
762 gdouble x0, y0, rx, ry, w, h;
764 guint line_color, fill_color;
766 gl_debug (DEBUG_PRINT, "START");
768 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
769 line_width = gl_label_ellipse_get_line_width (object);
770 line_color = gl_label_ellipse_get_line_color (object);
771 fill_color = gl_label_ellipse_get_fill_color (object);
778 /* Paint fill color */
779 create_ellipse_path (pi->pc, x0, y0, rx, ry);
780 gnome_print_setrgbcolor (pi->pc,
781 GL_COLOR_F_RED (fill_color),
782 GL_COLOR_F_GREEN (fill_color),
783 GL_COLOR_F_BLUE (fill_color));
784 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
785 gnome_print_fill (pi->pc);
788 create_ellipse_path (pi->pc, x0, y0, rx, ry);
789 gnome_print_setrgbcolor (pi->pc,
790 GL_COLOR_F_RED (line_color),
791 GL_COLOR_F_GREEN (line_color),
792 GL_COLOR_F_BLUE (line_color));
793 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
794 gnome_print_setlinewidth (pi->pc, line_width);
795 gnome_print_stroke (pi->pc);
797 gl_debug (DEBUG_PRINT, "END");
800 /*---------------------------------------------------------------------------*/
801 /* PRIVATE. Draw image object. */
802 /*---------------------------------------------------------------------------*/
804 draw_image_object (PrintInfo *pi,
805 glLabelImage *object,
806 glMergeRecord *record)
809 const GdkPixbuf *pixbuf;
811 gint image_w, image_h, image_stride;
812 gboolean image_alpha_flag;
815 gl_debug (DEBUG_PRINT, "START");
817 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
819 pixbuf = gl_label_image_get_pixbuf (object, record);
820 image_data = gdk_pixbuf_get_pixels (pixbuf);
821 image_w = gdk_pixbuf_get_width (pixbuf);
822 image_h = gdk_pixbuf_get_height (pixbuf);
823 image_stride = gdk_pixbuf_get_rowstride(pixbuf);
824 image_alpha_flag = gdk_pixbuf_get_has_alpha(pixbuf);
826 gnome_print_gsave (pi->pc);
827 gnome_print_translate (pi->pc, 0.0, h);
828 gnome_print_scale (pi->pc, w, -h);
829 if (image_alpha_flag) {
830 ret = gnome_print_rgbaimage (pi->pc, image_data,
831 image_w, image_h, image_stride);
832 gl_debug (DEBUG_PRINT, "Ret a = %d", ret);
834 ret = gnome_print_rgbimage (pi->pc, image_data,
835 image_w, image_h, image_stride);
836 gl_debug (DEBUG_PRINT, "Ret = %d", ret);
838 gnome_print_grestore (pi->pc);
840 gl_debug (DEBUG_PRINT, "END");
843 /*---------------------------------------------------------------------------*/
844 /* PRIVATE. Draw box object. */
845 /*---------------------------------------------------------------------------*/
847 draw_barcode_object (PrintInfo *pi,
848 glLabelBarcode *object,
849 glMergeRecord *record)
853 glBarcodeChar *bchar;
857 gchar *text, *cstring;
858 glTextNode *text_node;
859 glBarcodeStyle style;
861 gboolean checksum_flag;
865 gl_debug (DEBUG_PRINT, "START");
867 text_node = gl_label_barcode_get_data (object);
868 gl_label_barcode_get_props (object,
869 &style, &text_flag, &checksum_flag, &color);
870 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
872 text = gl_text_node_expand (text_node, record);
873 gbc = gl_barcode_new (style, text_flag, checksum_flag, w, h, text);
875 gl_text_node_free (&text_node);
879 font = gnome_font_find_closest_from_weight_slant (
880 GL_BARCODE_FONT_FAMILY,
881 GL_BARCODE_FONT_WEIGHT,
883 gnome_print_setfont (pi->pc, font);
885 gnome_print_setrgbcolor (pi->pc,
886 GL_COLOR_F_RED (color),
887 GL_COLOR_F_GREEN (color),
888 GL_COLOR_F_BLUE (color));
889 gnome_print_setopacity (pi->pc,
890 GL_COLOR_F_ALPHA (color));
892 y_offset = 12.0 - gnome_font_get_descender (font);
893 gnome_print_moveto (pi->pc, 0.0, y_offset);
895 gnome_print_gsave (pi->pc);
896 gnome_print_scale (pi->pc, 1.0, -1.0);
897 gnome_print_show (pi->pc, _("Invalid barcode"));
898 gnome_print_grestore (pi->pc);
902 for (li = gbc->lines; li != NULL; li = li->next) {
903 line = (glBarcodeLine *) li->data;
905 gnome_print_moveto (pi->pc, line->x, line->y);
906 gnome_print_lineto (pi->pc, line->x, line->y + line->length);
907 gnome_print_setrgbcolor (pi->pc,
908 GL_COLOR_F_RED (color),
909 GL_COLOR_F_GREEN (color),
910 GL_COLOR_F_BLUE (color));
911 gnome_print_setopacity (pi->pc,
912 GL_COLOR_F_ALPHA (color));
913 gnome_print_setlinewidth (pi->pc, line->width);
914 gnome_print_stroke (pi->pc);
917 for (li = gbc->chars; li != NULL; li = li->next) {
918 bchar = (glBarcodeChar *) li->data;
920 font = gnome_font_find_closest_from_weight_slant (
921 GL_BARCODE_FONT_FAMILY,
922 GL_BARCODE_FONT_WEIGHT,
923 FALSE, bchar->fsize);
924 gnome_print_setfont (pi->pc, font);
926 gnome_print_setrgbcolor (pi->pc,
927 GL_COLOR_F_RED (color),
928 GL_COLOR_F_GREEN (color),
929 GL_COLOR_F_BLUE (color));
930 gnome_print_setopacity (pi->pc,
931 GL_COLOR_F_ALPHA (color));
934 bchar->y + bchar->fsize -
935 gnome_font_get_descender (font);
936 gnome_print_moveto (pi->pc, bchar->x, y_offset);
938 cstring = g_strdup_printf ("%c", bchar->c);
939 gnome_print_gsave (pi->pc);
940 gnome_print_scale (pi->pc, 1.0, -1.0);
941 gnome_print_show (pi->pc, cstring);
942 gnome_print_grestore (pi->pc);
947 gl_barcode_free (&gbc);
951 gl_debug (DEBUG_PRINT, "END");
954 /*---------------------------------------------------------------------------*/
955 /* PRIVATE. Draw outline. */
956 /*---------------------------------------------------------------------------*/
958 draw_outline (PrintInfo *pi,
963 glTemplate *template;
965 gl_debug (DEBUG_PRINT, "START");
967 template = gl_label_get_template (label);
969 gnome_print_setrgbcolor (pi->pc, 0.25, 0.25, 0.25);
970 gnome_print_setopacity (pi->pc, 1.0);
971 gnome_print_setlinewidth (pi->pc, 0.25);
973 switch (template->label.style) {
975 case GL_TEMPLATE_STYLE_RECT:
976 gl_label_get_size (label, &w, &h);
977 r = template->label.rect.r;
979 /* simple rectangle */
980 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
982 /* rectangle with rounded corners */
983 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
986 gnome_print_stroke (pi->pc);
989 case GL_TEMPLATE_STYLE_ROUND:
991 r1 = template->label.round.r;
992 create_ellipse_path (pi->pc, r1, r1, r1, r1);
993 gnome_print_stroke (pi->pc);
996 case GL_TEMPLATE_STYLE_CD:
997 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
998 /* CD style, round label w/ concentric round hole */
999 r1 = template->label.cd.r1;
1000 r2 = template->label.cd.r2;
1001 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1002 gnome_print_stroke (pi->pc);
1003 create_ellipse_path (pi->pc, r1, r1, r2, r2);
1004 gnome_print_stroke (pi->pc);
1006 /* Business Card CD style, clipped round label w/ hole */
1007 gl_label_get_size (label, &w, &h);
1008 r1 = template->label.cd.r1;
1009 r2 = template->label.cd.r2;
1010 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1011 gnome_print_stroke (pi->pc);
1012 create_ellipse_path (pi->pc, w/2, h/2, r2, r2);
1013 gnome_print_stroke (pi->pc);
1018 g_warning ("Unknown template label style");
1022 gl_template_free (&template);
1024 gl_debug (DEBUG_PRINT, "END");
1027 /*---------------------------------------------------------------------------*/
1028 /* PRIVATE. Clip to outline. */
1029 /*---------------------------------------------------------------------------*/
1031 clip_to_outline (PrintInfo *pi,
1036 glTemplate *template;
1038 gl_debug (DEBUG_PRINT, "START");
1040 template = gl_label_get_template (label);
1042 switch (template->label.style) {
1044 case GL_TEMPLATE_STYLE_RECT:
1045 gl_label_get_size (label, &w, &h);
1046 r = template->label.rect.r;
1048 /* simple rectangle */
1049 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
1051 /* rectangle with rounded corners */
1052 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
1055 gnome_print_clip (pi->pc);
1058 case GL_TEMPLATE_STYLE_ROUND:
1059 r1 = template->label.round.r;
1060 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1061 gnome_print_clip (pi->pc);
1064 case GL_TEMPLATE_STYLE_CD:
1065 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
1066 /* CD style, round label w/ concentric round hole */
1067 r1 = template->label.cd.r1;
1068 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1069 gnome_print_clip (pi->pc);
1071 /* Business Card CD style, clipped round label w/ hole */
1072 gl_label_get_size (label, &w, &h);
1073 r1 = template->label.cd.r1;
1074 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1075 gnome_print_clip (pi->pc);
1080 g_warning ("Unknown template label style");
1084 gl_template_free (&template);
1086 gl_debug (DEBUG_PRINT, "END");
1089 /*---------------------------------------------------------------------------*/
1090 /* PRIVATE. Path creation utilities. */
1091 /*---------------------------------------------------------------------------*/
1093 create_rectangle_path (GnomePrintContext *pc,
1099 gl_debug (DEBUG_PRINT, "START");
1101 gnome_print_newpath (pc);
1102 gnome_print_moveto (pc, x0, y0);
1103 gnome_print_lineto (pc, x0 + w, y0);
1104 gnome_print_lineto (pc, x0 + w, y0 + h);
1105 gnome_print_lineto (pc, x0, y0 + h);
1106 gnome_print_lineto (pc, x0, y0);
1107 gnome_print_closepath (pc);
1109 gl_debug (DEBUG_PRINT, "END");
1113 create_ellipse_path (GnomePrintContext *pc,
1122 gl_debug (DEBUG_PRINT, "START");
1124 gnome_print_newpath (pc);
1125 gnome_print_moveto (pc, x0 + rx, y0);
1126 for (i_theta = ARC_FINE; i_theta <= 360; i_theta += ARC_FINE) {
1127 x = x0 + rx * cos (i_theta * G_PI / 180.0);
1128 y = y0 + ry * sin (i_theta * G_PI / 180.0);
1129 gnome_print_lineto (pc, x, y);
1131 gnome_print_closepath (pc);
1133 gl_debug (DEBUG_PRINT, "END");
1137 create_rounded_rectangle_path (GnomePrintContext *pc,
1147 gl_debug (DEBUG_PRINT, "START");
1149 gnome_print_newpath (pc);
1151 gnome_print_moveto (pc, x0 + r, y0);
1152 for (i_theta = ARC_COURSE; i_theta <= 90; i_theta += ARC_COURSE) {
1153 x = x0 + r - r * sin (i_theta * G_PI / 180.0);
1154 y = y0 + r - r * cos (i_theta * G_PI / 180.0);
1155 gnome_print_lineto (pc, x, y);
1157 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1158 x = x0 + r - r * cos (i_theta * G_PI / 180.0);
1159 y = y0 + (h - r) + r * sin (i_theta * G_PI / 180.0);
1160 gnome_print_lineto (pc, x, y);
1162 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1163 x = x0 + (w - r) + r * sin (i_theta * G_PI / 180.0);
1164 y = y0 + (h - r) + r * cos (i_theta * G_PI / 180.0);
1165 gnome_print_lineto (pc, x, y);
1167 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1168 x = x0 + (w - r) + r * cos (i_theta * G_PI / 180.0);
1169 y = y0 + r - r * sin (i_theta * G_PI / 180.0);
1170 gnome_print_lineto (pc, x, y);
1172 gnome_print_lineto (pc, x0 + r, y0);
1174 gnome_print_closepath (pc);
1176 gl_debug (DEBUG_PRINT, "END");
1180 create_clipped_circle_path (GnomePrintContext *pc,
1188 gdouble theta1, theta2;
1191 gl_debug (DEBUG_PRINT, "START");
1193 theta1 = (180.0/G_PI) * acos (w / (2.0*r));
1194 theta2 = (180.0/G_PI) * asin (h / (2.0*r));
1196 gnome_print_newpath (pc);
1198 x = x0 + r * cos (theta1 * G_PI / 180.0);
1199 y = y0 + r * sin (theta1 * G_PI / 180.0);
1200 gnome_print_moveto (pc, x, y);
1202 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1203 x = x0 + r * cos (i_theta * G_PI / 180.0);
1204 y = y0 + r * sin (i_theta * G_PI / 180.0);
1205 gnome_print_lineto (pc, x, y);
1208 x = x0 + r * cos (theta2 * G_PI / 180.0);
1209 y = y0 + r * sin (theta2 * G_PI / 180.0);
1210 gnome_print_lineto (pc, x, y);
1212 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1213 x = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1214 y = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1215 gnome_print_lineto (pc, x, y);
1218 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1219 x = x0 + r * cos (i_theta * G_PI / 180.0);
1220 y = y0 + r * sin (i_theta * G_PI / 180.0);
1221 gnome_print_lineto (pc, x, y);
1224 x = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1225 y = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1226 gnome_print_lineto (pc, x, y);
1228 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1229 x = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1230 y = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1231 gnome_print_lineto (pc, x, y);
1234 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1235 x = x0 + r * cos (i_theta * G_PI / 180.0);
1236 y = y0 + r * sin (i_theta * G_PI / 180.0);
1237 gnome_print_lineto (pc, x, y);
1240 x = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1241 y = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1242 gnome_print_lineto (pc, x, y);
1244 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1245 x = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1246 y = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1247 gnome_print_lineto (pc, x, y);
1250 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1251 x = x0 + r * cos (i_theta * G_PI / 180.0);
1252 y = y0 + r * sin (i_theta * G_PI / 180.0);
1253 gnome_print_lineto (pc, x, y);
1256 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1257 x = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1258 y = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1259 gnome_print_lineto (pc, x, y);
1262 x = x0 + r * cos (theta1 * G_PI / 180.0);
1263 y = y0 + r * sin (theta1 * G_PI / 180.0);
1264 gnome_print_lineto (pc, x, y);
1266 gnome_print_closepath (pc);
1268 gl_debug (DEBUG_PRINT, "END");