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
28 #include <libgnomeprint/gnome-print-paper.h>
29 #include <libgnomeprintui/gnome-printer-dialog.h>
33 #include "label-text.h"
34 #include "label-box.h"
35 #include "label-line.h"
36 #include "label-ellipse.h"
37 #include "label-image.h"
38 #include "label-barcode.h"
45 #define GL_PRINT_DEFAULT_PAPER "US Letter"
47 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
48 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
50 /*=========================================================================*/
52 /*=========================================================================*/
54 typedef struct _PrintInfo {
55 /* gnome print context */
56 GnomePrintContext *pc;
58 /* gnome print configuration */
59 GnomePrintConfig *config;
61 /* gLabels Template */
63 gboolean label_rotate_flag;
74 /*=========================================================================*/
75 /* Private function prototypes. */
76 /*=========================================================================*/
77 static PrintInfo *print_info_new (GnomePrintMaster *master,
80 static void print_info_free (PrintInfo **pi);
83 static void print_page_begin (PrintInfo *pi);
85 static void print_page_end (PrintInfo *pi);
87 static void print_label (PrintInfo *pi,
91 glMergeRecord *record,
92 gboolean outline_flag,
93 gboolean reverse_flag);
96 static void draw_label (PrintInfo *pi,
98 glMergeRecord *record);
101 static void draw_object (PrintInfo *pi,
102 glLabelObject *object,
103 glMergeRecord *record);
105 static void draw_text_object (PrintInfo *pi,
107 glMergeRecord *record);
109 static void draw_box_object (PrintInfo *pi,
112 static void draw_line_object (PrintInfo *pi,
113 glLabelLine *object);
115 static void draw_ellipse_object (PrintInfo *pi,
116 glLabelEllipse *object);
118 static void draw_image_object (PrintInfo *pi,
119 glLabelImage *object,
120 glMergeRecord *record);
122 static void draw_barcode_object (PrintInfo *pi,
123 glLabelBarcode *object,
124 glMergeRecord *record);
127 static void draw_outline (PrintInfo *pi,
130 static void clip_to_outline (PrintInfo *pi,
134 static void create_rectangle_path (GnomePrintContext *pc,
140 static void create_ellipse_path (GnomePrintContext *pc,
146 static void create_rounded_rectangle_path (GnomePrintContext *pc,
153 static void create_clipped_circle_path (GnomePrintContext *pc,
161 /*****************************************************************************/
162 /* Simple (no merge data) print command. */
163 /*****************************************************************************/
165 gl_print_simple (GnomePrintMaster *master,
170 gboolean outline_flag,
171 gboolean reverse_flag)
174 gint i_sheet, i_label;
175 glTemplateOrigin *origins;
177 gl_debug (DEBUG_PRINT, "START");
179 pi = print_info_new (master, label);
181 origins = gl_template_get_origins (pi->template);
183 for (i_sheet = 0; i_sheet < n_sheets; i_sheet++) {
185 print_page_begin (pi);
187 for (i_label = first - 1; i_label < last; i_label++) {
189 print_label (pi, label,
190 origins[i_label].x, origins[i_label].y,
191 NULL, outline_flag, reverse_flag);
200 print_info_free (&pi);
202 gl_debug (DEBUG_PRINT, "END");
205 /*****************************************************************************/
206 /* Merge print command (collated copies) */
207 /*****************************************************************************/
209 gl_print_merge_collated (GnomePrintMaster *master,
213 gboolean outline_flag,
214 gboolean reverse_flag)
217 const GList *record_list;
219 gint i_sheet, i_label, n_labels_per_page, i_copy;
220 glMergeRecord *record;
222 glTemplateOrigin *origins;
224 gl_debug (DEBUG_PRINT, "START");
226 merge = gl_label_get_merge (label);
227 record_list = gl_merge_get_record_list (merge);
229 pi = print_info_new (master, label);
231 n_labels_per_page = gl_template_get_n_labels (pi->template);
232 origins = gl_template_get_origins (pi->template);
237 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
238 record = (glMergeRecord *)p->data;
240 if ( record->select_flag ) {
241 for (i_copy = 0; i_copy < n_copies; i_copy++) {
243 if ((i_label == 0) || (i_sheet == 0)) {
245 print_page_begin (pi);
248 print_label (pi, label,
252 outline_flag, reverse_flag);
254 i_label = (i_label + 1) % n_labels_per_page;
268 print_info_free (&pi);
270 gl_debug (DEBUG_PRINT, "END");
273 /*****************************************************************************/
274 /* Merge print command (uncollated copies) */
275 /*****************************************************************************/
277 gl_print_merge_uncollated (GnomePrintMaster *master,
281 gboolean outline_flag,
282 gboolean reverse_flag)
285 const GList *record_list;
287 gint i_sheet, i_label, n_labels_per_page, i_copy;
288 glMergeRecord *record;
290 glTemplateOrigin *origins;
292 gl_debug (DEBUG_PRINT, "START");
294 merge = gl_label_get_merge (label);
295 record_list = gl_merge_get_record_list (merge);
297 pi = print_info_new (master, label);
299 n_labels_per_page = gl_template_get_n_labels (pi->template);
300 origins = gl_template_get_origins (pi->template);
305 for (i_copy = 0; i_copy < n_copies; i_copy++) {
307 for ( p=(GList *)record_list; p!=NULL; p=p->next ) {
308 record = (glMergeRecord *)p->data;
310 if ( record->select_flag ) {
313 if ((i_label == 0) || (i_sheet == 0)) {
315 print_page_begin (pi);
318 print_label (pi, label,
322 outline_flag, reverse_flag);
324 i_label = (i_label + 1) % n_labels_per_page;
338 print_info_free (&pi);
340 gl_debug (DEBUG_PRINT, "END");
343 /*****************************************************************************/
344 /* Batch print. Call appropriate function above. */
345 /*****************************************************************************/
347 gl_print_batch (GnomePrintMaster *master,
351 gboolean outline_flag,
352 gboolean reverse_flag)
356 glTemplate *template;
358 gl_debug (DEBUG_PRINT, "START");
360 merge = gl_label_get_merge (label);
361 template = gl_label_get_template (label);
363 if ( merge == NULL ) {
364 n_per_page = gl_template_get_n_labels(template);
366 gl_print_simple (master, label, n_sheets, 1, n_per_page,
367 outline_flag, reverse_flag);
369 gl_print_merge_collated (master, label, n_copies, 1,
370 outline_flag, reverse_flag);
372 gl_template_free (&template);
374 g_object_unref (G_OBJECT(merge));
376 gl_debug (DEBUG_PRINT, "END");
379 /*---------------------------------------------------------------------------*/
380 /* PRIVATE. new print info structure */
381 /*---------------------------------------------------------------------------*/
383 print_info_new (GnomePrintMaster *master,
386 PrintInfo *pi = g_new0 (PrintInfo, 1);
387 glTemplate *template;
389 gl_debug (DEBUG_PRINT, "START");
391 template = gl_label_get_template (label);
393 if (template == NULL) {
394 g_warning ("Label has no template");
398 pi->pc = gnome_print_master_get_context (master);
399 pi->config = gnome_print_master_get_config (master);
401 if ((template != NULL) && (template->page_size != NULL)) {
403 gl_debug (DEBUG_PRINT,
404 "setting page size = \"%s\"", template->page_size);
406 /* Currently cannot set page size directly from name, */
407 /* since we must set Ids not Names and there is no */
408 /* way to do the reverse lookup of Id from Name. */
409 /* Sometimes they are the same, but not always */
410 /* (e.g. for the name "US Letter" id="USLetter" */
411 /* So we always use the "Custom" Id. */
412 gnome_print_config_set (pi->config,
413 GNOME_PRINT_KEY_PAPER_SIZE,
415 gnome_print_config_set_length (pi->config,
416 GNOME_PRINT_KEY_PAPER_WIDTH,
417 template->page_width,
418 GNOME_PRINT_PS_UNIT);
419 gnome_print_config_set_length (pi->config,
420 GNOME_PRINT_KEY_PAPER_HEIGHT,
421 template->page_height,
422 GNOME_PRINT_PS_UNIT);
424 g_warning ("Cannot determine correct page size.");
425 gnome_print_config_set (pi->config,
426 GNOME_PRINT_KEY_PAPER_SIZE,
427 GL_PRINT_DEFAULT_PAPER);
429 pi->page_width = template->page_width;
430 pi->page_height = template->page_height;
432 pi->template = template;
433 pi->label_rotate_flag = gl_label_get_rotate_flag (label);
437 gl_debug (DEBUG_PRINT, "END");
442 /*---------------------------------------------------------------------------*/
443 /* PRIVATE. free print info structure */
444 /*---------------------------------------------------------------------------*/
446 print_info_free (PrintInfo **pi)
448 gl_debug (DEBUG_PRINT, "START");
450 gl_template_free (&(*pi)->template);
452 gnome_print_context_close ((*pi)->pc);
457 gl_debug (DEBUG_PRINT, "END");
460 /*---------------------------------------------------------------------------*/
461 /* PRIVATE. Begin a new page. */
462 /*---------------------------------------------------------------------------*/
464 print_page_begin (PrintInfo *pi)
468 gl_debug (DEBUG_PRINT, "START");
472 str = g_strdup_printf ("sheet%02d", pi->sheet);
473 gnome_print_beginpage (pi->pc, str);
476 /* Translate and scale, so that our origin is at the upper left. */
477 gnome_print_translate (pi->pc, 0.0, pi->page_height);
478 gnome_print_scale (pi->pc, 1.0, -1.0);
480 gl_debug (DEBUG_PRINT, "END");
483 /*---------------------------------------------------------------------------*/
484 /* PRIVATE. End a page. */
485 /*---------------------------------------------------------------------------*/
487 print_page_end (PrintInfo *pi)
489 gl_debug (DEBUG_PRINT, "START");
491 gnome_print_showpage (pi->pc);
493 gl_debug (DEBUG_PRINT, "END");
496 /*---------------------------------------------------------------------------*/
497 /* PRIVATE. Print i'th label. */
498 /*---------------------------------------------------------------------------*/
500 print_label (PrintInfo *pi,
504 glMergeRecord *record,
505 gboolean outline_flag,
506 gboolean reverse_flag)
508 gdouble width, height;
509 glTemplate *template;
511 gl_debug (DEBUG_PRINT, "START");
513 template = gl_label_get_template (label);
515 gl_label_get_size (label, &width, &height);
517 gnome_print_gsave (pi->pc);
519 /* Transform coordinate system to be relative to upper corner */
520 /* of the current label */
521 gnome_print_translate (pi->pc, x, y);
522 if (gl_label_get_rotate_flag (label)) {
523 gl_debug (DEBUG_PRINT, "Rotate flag set");
524 gnome_print_rotate (pi->pc, -90.0);
525 gnome_print_translate (pi->pc, -width, 0.0);
527 if ( reverse_flag ) {
528 gnome_print_translate (pi->pc, width, 0.0);
529 gnome_print_scale (pi->pc, -1.0, 1.0);
532 draw_outline (pi, label);
534 clip_to_outline (pi, label);
535 draw_label (pi, label, record);
537 gnome_print_grestore (pi->pc);
539 gl_template_free (&template);
541 gl_debug (DEBUG_PRINT, "END");
544 /*---------------------------------------------------------------------------*/
545 /* PRIVATE. Draw label. */
546 /*---------------------------------------------------------------------------*/
548 draw_label (PrintInfo *pi,
550 glMergeRecord *record)
553 glLabelObject *object;
555 gl_debug (DEBUG_PRINT, "START");
557 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
558 object = (glLabelObject *) p_obj->data;
560 draw_object (pi, object, record);
563 gl_debug (DEBUG_PRINT, "END");
566 /*---------------------------------------------------------------------------*/
567 /* PRIVATE. Draw object. */
568 /*---------------------------------------------------------------------------*/
570 draw_object (PrintInfo *pi,
571 glLabelObject *object,
572 glMergeRecord *record)
577 gl_debug (DEBUG_PRINT, "START");
579 gl_label_object_get_position (object, &x0, &y0);
580 gl_label_object_get_affine (object, affine);
582 gnome_print_gsave (pi->pc);
584 gnome_print_translate (pi->pc, x0, y0);
585 gnome_print_concat (pi->pc, affine);
587 if (GL_IS_LABEL_TEXT(object)) {
588 draw_text_object (pi, GL_LABEL_TEXT(object), record);
589 } else if (GL_IS_LABEL_BOX(object)) {
590 draw_box_object (pi, GL_LABEL_BOX(object));
591 } else if (GL_IS_LABEL_LINE(object)) {
592 draw_line_object (pi, GL_LABEL_LINE(object));
593 } else if (GL_IS_LABEL_ELLIPSE(object)) {
594 draw_ellipse_object (pi, GL_LABEL_ELLIPSE(object));
595 } else if (GL_IS_LABEL_IMAGE(object)) {
596 draw_image_object (pi, GL_LABEL_IMAGE(object), record);
597 } else if (GL_IS_LABEL_BARCODE(object)) {
598 draw_barcode_object (pi, GL_LABEL_BARCODE(object), record);
601 gnome_print_grestore (pi->pc);
603 gl_debug (DEBUG_PRINT, "END");
606 /*---------------------------------------------------------------------------*/
607 /* PRIVATE. Draw text object. */
608 /*---------------------------------------------------------------------------*/
610 draw_text_object (PrintInfo *pi,
612 glMergeRecord *record)
617 gdouble x_offset, y_offset, w, object_w, object_h;
622 GnomeFontWeight font_weight;
623 gboolean font_italic_flag;
625 GtkJustification just;
626 GnomeGlyphList *glyphlist;
631 gl_debug (DEBUG_PRINT, "START");
633 gl_label_object_get_size (GL_LABEL_OBJECT(object), &object_w, &object_h);
634 lines = gl_label_text_get_lines (object);
635 gl_label_text_get_props (object,
636 &font_family, &font_size, &font_weight,
640 font = gnome_font_find_closest_from_weight_slant (
645 gnome_print_setfont (pi->pc, font);
647 gnome_print_setrgbcolor (pi->pc,
648 GL_COLOR_F_RED (color),
649 GL_COLOR_F_GREEN (color),
650 GL_COLOR_F_BLUE (color));
651 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (color));
653 text = gl_text_node_lines_expand (lines, record);
654 line = g_strsplit (text, "\n", -1);
657 art_affine_identity (affine);
659 for (i = 0; line[i] != NULL; i++) {
661 glyphlist = gnome_glyphlist_from_text_dumb (font, color,
665 gnome_glyphlist_bbox (glyphlist, affine, 0, &bbox);
669 case GTK_JUSTIFY_LEFT:
672 case GTK_JUSTIFY_CENTER:
673 x_offset = (object_w - w) / 2.0;
675 case GTK_JUSTIFY_RIGHT:
676 x_offset = object_w - w;
680 break; /* shouldn't happen */
683 y_offset = (i + 1) * font_size
684 + gnome_font_get_descender (font);
686 gnome_print_moveto (pi->pc, x_offset, y_offset);
688 gnome_print_gsave (pi->pc);
689 gnome_print_scale (pi->pc, 1.0, -1.0);
690 gnome_print_show (pi->pc, line[i]);
691 gnome_print_grestore (pi->pc);
696 gl_text_node_lines_free (&lines);
697 g_free (font_family);
699 gl_debug (DEBUG_PRINT, "END");
702 /*---------------------------------------------------------------------------*/
703 /* PRIVATE. Draw box object. */
704 /*---------------------------------------------------------------------------*/
706 draw_box_object (PrintInfo *pi,
711 guint line_color, fill_color;
713 gl_debug (DEBUG_PRINT, "START");
715 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
716 line_width = gl_label_box_get_line_width (object);
717 line_color = gl_label_box_get_line_color (object);
718 fill_color = gl_label_box_get_fill_color (object);
720 /* Paint fill color */
721 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
722 gnome_print_setrgbcolor (pi->pc,
723 GL_COLOR_F_RED (fill_color),
724 GL_COLOR_F_GREEN (fill_color),
725 GL_COLOR_F_BLUE (fill_color));
726 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
727 gnome_print_fill (pi->pc);
730 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
731 gnome_print_setrgbcolor (pi->pc,
732 GL_COLOR_F_RED (line_color),
733 GL_COLOR_F_GREEN (line_color),
734 GL_COLOR_F_BLUE (line_color));
735 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
736 gnome_print_setlinewidth (pi->pc, line_width);
737 gnome_print_stroke (pi->pc);
739 gl_debug (DEBUG_PRINT, "END");
742 /*---------------------------------------------------------------------------*/
743 /* PRIVATE. Draw line object. */
744 /*---------------------------------------------------------------------------*/
746 draw_line_object (PrintInfo *pi,
753 gl_debug (DEBUG_PRINT, "START");
755 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
756 line_width = gl_label_line_get_line_width (object);
757 line_color = gl_label_line_get_line_color (object);
759 gnome_print_moveto (pi->pc, 0.0, 0.0);
760 gnome_print_lineto (pi->pc, w, h);
761 gnome_print_setrgbcolor (pi->pc,
762 GL_COLOR_F_RED (line_color),
763 GL_COLOR_F_GREEN (line_color),
764 GL_COLOR_F_BLUE (line_color));
765 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
766 gnome_print_setlinewidth (pi->pc, line_width);
767 gnome_print_stroke (pi->pc);
769 gl_debug (DEBUG_PRINT, "END");
772 /*---------------------------------------------------------------------------*/
773 /* PRIVATE. Draw ellipse object. */
774 /*---------------------------------------------------------------------------*/
776 draw_ellipse_object (PrintInfo *pi,
777 glLabelEllipse *object)
779 gdouble x0, y0, rx, ry, w, h;
781 guint line_color, fill_color;
783 gl_debug (DEBUG_PRINT, "START");
785 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
786 line_width = gl_label_ellipse_get_line_width (object);
787 line_color = gl_label_ellipse_get_line_color (object);
788 fill_color = gl_label_ellipse_get_fill_color (object);
795 /* Paint fill color */
796 create_ellipse_path (pi->pc, x0, y0, rx, ry);
797 gnome_print_setrgbcolor (pi->pc,
798 GL_COLOR_F_RED (fill_color),
799 GL_COLOR_F_GREEN (fill_color),
800 GL_COLOR_F_BLUE (fill_color));
801 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (fill_color));
802 gnome_print_fill (pi->pc);
805 create_ellipse_path (pi->pc, x0, y0, rx, ry);
806 gnome_print_setrgbcolor (pi->pc,
807 GL_COLOR_F_RED (line_color),
808 GL_COLOR_F_GREEN (line_color),
809 GL_COLOR_F_BLUE (line_color));
810 gnome_print_setopacity (pi->pc, GL_COLOR_F_ALPHA (line_color));
811 gnome_print_setlinewidth (pi->pc, line_width);
812 gnome_print_stroke (pi->pc);
814 gl_debug (DEBUG_PRINT, "END");
817 /*---------------------------------------------------------------------------*/
818 /* PRIVATE. Draw image object. */
819 /*---------------------------------------------------------------------------*/
821 draw_image_object (PrintInfo *pi,
822 glLabelImage *object,
823 glMergeRecord *record)
826 const GdkPixbuf *pixbuf;
828 gint image_w, image_h, image_stride;
829 gboolean image_alpha_flag;
832 gl_debug (DEBUG_PRINT, "START");
834 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
836 pixbuf = gl_label_image_get_pixbuf (object, record);
837 image_data = gdk_pixbuf_get_pixels (pixbuf);
838 image_w = gdk_pixbuf_get_width (pixbuf);
839 image_h = gdk_pixbuf_get_height (pixbuf);
840 image_stride = gdk_pixbuf_get_rowstride(pixbuf);
841 image_alpha_flag = gdk_pixbuf_get_has_alpha(pixbuf);
843 gnome_print_gsave (pi->pc);
844 gnome_print_translate (pi->pc, 0.0, h);
845 gnome_print_scale (pi->pc, w, -h);
846 if (image_alpha_flag) {
847 ret = gnome_print_rgbaimage (pi->pc, image_data,
848 image_w, image_h, image_stride);
849 gl_debug (DEBUG_PRINT, "Ret a = %d", ret);
851 ret = gnome_print_rgbimage (pi->pc, image_data,
852 image_w, image_h, image_stride);
853 gl_debug (DEBUG_PRINT, "Ret = %d", ret);
855 gnome_print_grestore (pi->pc);
857 gl_debug (DEBUG_PRINT, "END");
860 /*---------------------------------------------------------------------------*/
861 /* PRIVATE. Draw box object. */
862 /*---------------------------------------------------------------------------*/
864 draw_barcode_object (PrintInfo *pi,
865 glLabelBarcode *object,
866 glMergeRecord *record)
870 glBarcodeChar *bchar;
874 gchar *text, *cstring;
875 glTextNode *text_node;
876 glBarcodeStyle style;
881 gl_debug (DEBUG_PRINT, "START");
883 text_node = gl_label_barcode_get_data (object);
884 gl_label_barcode_get_props (object,
885 &style, &text_flag, &color, &scale);
887 text = gl_text_node_expand (text_node, record);
888 gbc = gl_barcode_new (style, text_flag, scale, text);
890 gl_text_node_free (&text_node);
894 font = gnome_font_find_closest_from_weight_slant (
895 GL_BARCODE_FONT_FAMILY,
896 GL_BARCODE_FONT_WEIGHT,
898 gnome_print_setfont (pi->pc, font);
900 gnome_print_setrgbcolor (pi->pc,
901 GL_COLOR_F_RED (color),
902 GL_COLOR_F_GREEN (color),
903 GL_COLOR_F_BLUE (color));
904 gnome_print_setopacity (pi->pc,
905 GL_COLOR_F_ALPHA (color));
907 y_offset = 12.0 - gnome_font_get_descender (font);
908 gnome_print_moveto (pi->pc, 0.0, y_offset);
910 gnome_print_gsave (pi->pc);
911 gnome_print_scale (pi->pc, 1.0, -1.0);
912 gnome_print_show (pi->pc, _("Invalid barcode"));
913 gnome_print_grestore (pi->pc);
917 for (li = gbc->lines; li != NULL; li = li->next) {
918 line = (glBarcodeLine *) li->data;
920 gnome_print_moveto (pi->pc, line->x, line->y);
921 gnome_print_lineto (pi->pc, line->x, line->y + line->length);
922 gnome_print_setrgbcolor (pi->pc,
923 GL_COLOR_F_RED (color),
924 GL_COLOR_F_GREEN (color),
925 GL_COLOR_F_BLUE (color));
926 gnome_print_setopacity (pi->pc,
927 GL_COLOR_F_ALPHA (color));
928 gnome_print_setlinewidth (pi->pc, line->width);
929 gnome_print_stroke (pi->pc);
932 for (li = gbc->chars; li != NULL; li = li->next) {
933 bchar = (glBarcodeChar *) li->data;
935 font = gnome_font_find_closest_from_weight_slant (
936 GL_BARCODE_FONT_FAMILY,
937 GL_BARCODE_FONT_WEIGHT,
938 FALSE, bchar->fsize);
939 gnome_print_setfont (pi->pc, font);
941 gnome_print_setrgbcolor (pi->pc,
942 GL_COLOR_F_RED (color),
943 GL_COLOR_F_GREEN (color),
944 GL_COLOR_F_BLUE (color));
945 gnome_print_setopacity (pi->pc,
946 GL_COLOR_F_ALPHA (color));
949 bchar->y + bchar->fsize -
950 gnome_font_get_descender (font);
951 gnome_print_moveto (pi->pc, bchar->x, y_offset);
953 cstring = g_strdup_printf ("%c", bchar->c);
954 gnome_print_gsave (pi->pc);
955 gnome_print_scale (pi->pc, 1.0, -1.0);
956 gnome_print_show (pi->pc, cstring);
957 gnome_print_grestore (pi->pc);
962 gl_barcode_free (&gbc);
966 gl_debug (DEBUG_PRINT, "END");
969 /*---------------------------------------------------------------------------*/
970 /* PRIVATE. Draw outline. */
971 /*---------------------------------------------------------------------------*/
973 draw_outline (PrintInfo *pi,
978 glTemplate *template;
980 gl_debug (DEBUG_PRINT, "START");
982 template = gl_label_get_template (label);
984 gnome_print_setrgbcolor (pi->pc, 0.25, 0.25, 0.25);
985 gnome_print_setopacity (pi->pc, 1.0);
986 gnome_print_setlinewidth (pi->pc, 0.25);
988 switch (template->label.style) {
990 case GL_TEMPLATE_STYLE_RECT:
991 gl_label_get_size (label, &w, &h);
992 r = template->label.rect.r;
994 /* simple rectangle */
995 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
997 /* rectangle with rounded corners */
998 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
1001 gnome_print_stroke (pi->pc);
1004 case GL_TEMPLATE_STYLE_ROUND:
1006 r1 = template->label.round.r;
1007 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1008 gnome_print_stroke (pi->pc);
1011 case GL_TEMPLATE_STYLE_CD:
1012 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
1013 /* CD style, round label w/ concentric round hole */
1014 r1 = template->label.cd.r1;
1015 r2 = template->label.cd.r2;
1016 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1017 gnome_print_stroke (pi->pc);
1018 create_ellipse_path (pi->pc, r1, r1, r2, r2);
1019 gnome_print_stroke (pi->pc);
1021 /* Business Card CD style, clipped round label w/ hole */
1022 gl_label_get_size (label, &w, &h);
1023 r1 = template->label.cd.r1;
1024 r2 = template->label.cd.r2;
1025 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1026 gnome_print_stroke (pi->pc);
1027 create_ellipse_path (pi->pc, w/2, h/2, r2, r2);
1028 gnome_print_stroke (pi->pc);
1033 g_warning ("Unknown template label style");
1037 gl_template_free (&template);
1039 gl_debug (DEBUG_PRINT, "END");
1042 /*---------------------------------------------------------------------------*/
1043 /* PRIVATE. Clip to outline. */
1044 /*---------------------------------------------------------------------------*/
1046 clip_to_outline (PrintInfo *pi,
1051 glTemplate *template;
1053 gl_debug (DEBUG_PRINT, "START");
1055 template = gl_label_get_template (label);
1057 switch (template->label.style) {
1059 case GL_TEMPLATE_STYLE_RECT:
1060 gl_label_get_size (label, &w, &h);
1061 r = template->label.rect.r;
1063 /* simple rectangle */
1064 create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
1066 /* rectangle with rounded corners */
1067 create_rounded_rectangle_path (pi->pc, 0.0, 0.0,
1070 gnome_print_clip (pi->pc);
1073 case GL_TEMPLATE_STYLE_ROUND:
1074 r1 = template->label.round.r;
1075 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1076 gnome_print_clip (pi->pc);
1079 case GL_TEMPLATE_STYLE_CD:
1080 if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
1081 /* CD style, round label w/ concentric round hole */
1082 r1 = template->label.cd.r1;
1083 create_ellipse_path (pi->pc, r1, r1, r1, r1);
1084 gnome_print_clip (pi->pc);
1086 /* Business Card CD style, clipped round label w/ hole */
1087 gl_label_get_size (label, &w, &h);
1088 r1 = template->label.cd.r1;
1089 create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
1090 gnome_print_clip (pi->pc);
1095 g_warning ("Unknown template label style");
1099 gl_template_free (&template);
1101 gl_debug (DEBUG_PRINT, "END");
1104 /*---------------------------------------------------------------------------*/
1105 /* PRIVATE. Path creation utilities. */
1106 /*---------------------------------------------------------------------------*/
1108 create_rectangle_path (GnomePrintContext *pc,
1114 gl_debug (DEBUG_PRINT, "START");
1116 gnome_print_newpath (pc);
1117 gnome_print_moveto (pc, x0, y0);
1118 gnome_print_lineto (pc, x0 + w, y0);
1119 gnome_print_lineto (pc, x0 + w, y0 + h);
1120 gnome_print_lineto (pc, x0, y0 + h);
1121 gnome_print_lineto (pc, x0, y0);
1122 gnome_print_closepath (pc);
1124 gl_debug (DEBUG_PRINT, "END");
1128 create_ellipse_path (GnomePrintContext *pc,
1137 gl_debug (DEBUG_PRINT, "START");
1139 gnome_print_newpath (pc);
1140 gnome_print_moveto (pc, x0 + rx, y0);
1141 for (i_theta = ARC_FINE; i_theta <= 360; i_theta += ARC_FINE) {
1142 x = x0 + rx * cos (i_theta * G_PI / 180.0);
1143 y = y0 + ry * sin (i_theta * G_PI / 180.0);
1144 gnome_print_lineto (pc, x, y);
1146 gnome_print_closepath (pc);
1148 gl_debug (DEBUG_PRINT, "END");
1152 create_rounded_rectangle_path (GnomePrintContext *pc,
1162 gl_debug (DEBUG_PRINT, "START");
1164 gnome_print_newpath (pc);
1166 gnome_print_moveto (pc, x0 + r, y0);
1167 for (i_theta = ARC_COURSE; i_theta <= 90; i_theta += ARC_COURSE) {
1168 x = x0 + r - r * sin (i_theta * G_PI / 180.0);
1169 y = y0 + r - r * cos (i_theta * G_PI / 180.0);
1170 gnome_print_lineto (pc, x, y);
1172 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1173 x = x0 + r - r * cos (i_theta * G_PI / 180.0);
1174 y = y0 + (h - r) + r * sin (i_theta * G_PI / 180.0);
1175 gnome_print_lineto (pc, x, y);
1177 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1178 x = x0 + (w - r) + r * sin (i_theta * G_PI / 180.0);
1179 y = y0 + (h - r) + r * cos (i_theta * G_PI / 180.0);
1180 gnome_print_lineto (pc, x, y);
1182 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1183 x = x0 + (w - r) + r * cos (i_theta * G_PI / 180.0);
1184 y = y0 + r - r * sin (i_theta * G_PI / 180.0);
1185 gnome_print_lineto (pc, x, y);
1187 gnome_print_lineto (pc, x0 + r, y0);
1189 gnome_print_closepath (pc);
1191 gl_debug (DEBUG_PRINT, "END");
1195 create_clipped_circle_path (GnomePrintContext *pc,
1203 gdouble theta1, theta2;
1206 gl_debug (DEBUG_PRINT, "START");
1208 theta1 = (180.0/G_PI) * acos (w / (2.0*r));
1209 theta2 = (180.0/G_PI) * asin (h / (2.0*r));
1211 gnome_print_newpath (pc);
1213 x = x0 + r * cos (theta1 * G_PI / 180.0);
1214 y = y0 + r * sin (theta1 * G_PI / 180.0);
1215 gnome_print_moveto (pc, x, y);
1217 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1218 x = x0 + r * cos (i_theta * G_PI / 180.0);
1219 y = y0 + r * sin (i_theta * G_PI / 180.0);
1220 gnome_print_lineto (pc, x, y);
1223 x = x0 + r * cos (theta2 * G_PI / 180.0);
1224 y = y0 + r * sin (theta2 * G_PI / 180.0);
1225 gnome_print_lineto (pc, x, y);
1227 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1228 x = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1229 y = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1230 gnome_print_lineto (pc, x, y);
1233 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1234 x = x0 + r * cos (i_theta * G_PI / 180.0);
1235 y = y0 + r * sin (i_theta * G_PI / 180.0);
1236 gnome_print_lineto (pc, x, y);
1239 x = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1240 y = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1241 gnome_print_lineto (pc, x, y);
1243 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1244 x = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1245 y = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1246 gnome_print_lineto (pc, x, y);
1249 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1250 x = x0 + r * cos (i_theta * G_PI / 180.0);
1251 y = y0 + r * sin (i_theta * G_PI / 180.0);
1252 gnome_print_lineto (pc, x, y);
1255 x = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1256 y = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1257 gnome_print_lineto (pc, x, y);
1259 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1260 x = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1261 y = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1262 gnome_print_lineto (pc, x, y);
1265 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1266 x = x0 + r * cos (i_theta * G_PI / 180.0);
1267 y = y0 + r * sin (i_theta * G_PI / 180.0);
1268 gnome_print_lineto (pc, x, y);
1271 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1272 x = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1273 y = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1274 gnome_print_lineto (pc, x, y);
1277 x = x0 + r * cos (theta1 * G_PI / 180.0);
1278 y = y0 + r * sin (theta1 * G_PI / 180.0);
1279 gnome_print_lineto (pc, x, y);
1281 gnome_print_closepath (pc);
1283 gl_debug (DEBUG_PRINT, "END");