3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
30 #include <libglabels.h>
32 #include "cairo-label-path.h"
37 /*===========================================*/
38 /* Private macros and constants. */
39 /*===========================================*/
41 #define OUTLINE_RGB_ARGS 0.0, 0.0, 0.0
43 #define OUTLINE_WIDTH 0.25
45 #define TICK_OFFSET 2.25
46 #define TICK_LENGTH 18.0
49 /*=========================================================================*/
51 /*=========================================================================*/
53 typedef struct _PrintInfo {
56 /* gLabels Template */
57 const lglTemplate *template;
67 /*=========================================================================*/
68 /* Private function prototypes. */
69 /*=========================================================================*/
70 static PrintInfo *print_info_new (cairo_t *cr,
73 static void print_info_free (PrintInfo **pi);
75 static void print_crop_marks (PrintInfo *pi);
77 static void print_label (PrintInfo *pi,
81 glMergeRecord *record,
82 gboolean outline_flag,
83 gboolean reverse_flag);
86 static void draw_outline (PrintInfo *pi,
89 static void clip_to_outline (PrintInfo *pi,
93 /*****************************************************************************/
94 /* Print simple sheet (no merge data) command. */
95 /*****************************************************************************/
97 gl_print_simple_sheet (glLabel *label,
103 gboolean outline_flag,
104 gboolean reverse_flag,
105 gboolean crop_marks_flag)
108 const lglTemplateFrame *frame;
110 lglTemplateOrigin *origins;
112 gl_debug (DEBUG_PRINT, "START");
114 pi = print_info_new (cr, label);
116 frame = (lglTemplateFrame *)pi->template->frames->data;
117 origins = lgl_template_frame_get_origins (frame);
119 if (crop_marks_flag) {
120 print_crop_marks (pi);
123 for (i_label = first - 1; i_label < last; i_label++) {
125 print_label (pi, label,
126 origins[i_label].x, origins[i_label].y,
127 NULL, outline_flag, reverse_flag);
133 print_info_free (&pi);
135 gl_debug (DEBUG_PRINT, "END");
139 /*****************************************************************************/
140 /* Print collated merge sheet command */
141 /*****************************************************************************/
143 gl_print_collated_merge_sheet (glLabel *label,
148 gboolean outline_flag,
149 gboolean reverse_flag,
150 gboolean crop_marks_flag,
154 const GList *record_list;
156 const lglTemplateFrame *frame;
157 gint i_label, n_labels_per_page, i_copy;
158 glMergeRecord *record;
160 lglTemplateOrigin *origins;
162 gl_debug (DEBUG_PRINT, "START");
164 merge = gl_label_get_merge (label);
165 record_list = gl_merge_get_record_list (merge);
167 pi = print_info_new (cr, label);
168 frame = (lglTemplateFrame *)pi->template->frames->data;
170 n_labels_per_page = lgl_template_frame_get_n_labels (frame);
171 origins = lgl_template_frame_get_origins (frame);
173 if (crop_marks_flag) {
174 print_crop_marks (pi);
180 state->p_record = (GList *)record_list;
190 for ( p=(GList *)state->p_record; p!=NULL; p=p->next ) {
191 record = (glMergeRecord *)p->data;
193 if ( record->select_flag ) {
194 for (i_copy = state->i_copy; i_copy < n_copies; i_copy++) {
196 print_label (pi, label,
200 outline_flag, reverse_flag);
203 if (i_label == n_labels_per_page)
206 print_info_free (&pi);
208 state->i_copy = (i_copy+1) % n_copies;
209 if (state->i_copy == 0)
211 state->p_record = p->next;
225 print_info_free (&pi);
227 gl_debug (DEBUG_PRINT, "END");
231 /*****************************************************************************/
232 /* Print uncollated merge sheet command */
233 /*****************************************************************************/
235 gl_print_uncollated_merge_sheet (glLabel *label,
240 gboolean outline_flag,
241 gboolean reverse_flag,
242 gboolean crop_marks_flag,
246 const GList *record_list;
248 const lglTemplateFrame *frame;
249 gint i_label, n_labels_per_page, i_copy;
250 glMergeRecord *record;
252 lglTemplateOrigin *origins;
254 gl_debug (DEBUG_PRINT, "START");
256 merge = gl_label_get_merge (label);
257 record_list = gl_merge_get_record_list (merge);
259 pi = print_info_new (cr, label);
260 frame = (lglTemplateFrame *)pi->template->frames->data;
262 n_labels_per_page = lgl_template_frame_get_n_labels (frame);
263 origins = lgl_template_frame_get_origins (frame);
265 if (crop_marks_flag) {
266 print_crop_marks (pi);
272 state->p_record = (GList *)record_list;
281 for (i_copy = state->i_copy; i_copy < n_copies; i_copy++) {
283 for ( p=state->p_record; p!=NULL; p=p->next ) {
284 record = (glMergeRecord *)p->data;
286 if ( record->select_flag ) {
288 print_label (pi, label,
292 outline_flag, reverse_flag);
295 if (i_label == n_labels_per_page)
298 print_info_free (&pi);
300 state->p_record = p->next;
301 if (state->p_record == NULL)
303 state->p_record = (GList *)record_list;
304 state->i_copy = i_copy + 1;
308 state->i_copy = i_copy;
314 state->p_record = (GList *)record_list;
319 print_info_free (&pi);
321 gl_debug (DEBUG_PRINT, "END");
325 /*---------------------------------------------------------------------------*/
326 /* PRIVATE. new print info structure */
327 /*---------------------------------------------------------------------------*/
329 print_info_new (cairo_t *cr,
332 PrintInfo *pi = g_new0 (PrintInfo, 1);
333 const lglTemplate *template;
334 gboolean rotate_flag;
336 gl_debug (DEBUG_PRINT, "START");
338 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
340 template = gl_label_get_template (label);
341 rotate_flag = gl_label_get_rotate_flag (label);
343 g_return_val_if_fail (template, NULL);
344 g_return_val_if_fail (template->paper_id, NULL);
345 g_return_val_if_fail (template->page_width > 0, NULL);
346 g_return_val_if_fail (template->page_height > 0, NULL);
350 gl_debug (DEBUG_PRINT,
351 "setting page size = \"%s\"", template->paper_id);
353 pi->page_width = template->page_width;
354 pi->page_height = template->page_height;
356 pi->template = template;
357 pi->rotate_flag = rotate_flag;
359 gl_debug (DEBUG_PRINT, "END");
365 /*---------------------------------------------------------------------------*/
366 /* PRIVATE. free print info structure */
367 /*---------------------------------------------------------------------------*/
369 print_info_free (PrintInfo **pi)
371 gl_debug (DEBUG_PRINT, "START");
377 gl_debug (DEBUG_PRINT, "END");
381 /*---------------------------------------------------------------------------*/
382 /* PRIVATE. Print crop tick marks. */
383 /*---------------------------------------------------------------------------*/
385 print_crop_marks (PrintInfo *pi)
387 const lglTemplateFrame *frame;
388 gdouble w, h, page_w, page_h;
390 lglTemplateLayout *layout;
391 gdouble xmin, ymin, xmax, ymax, dx, dy;
392 gdouble x1, y1, x2, y2, x3, y3, x4, y4;
395 gl_debug (DEBUG_PRINT, "START");
397 frame = (lglTemplateFrame *)pi->template->frames->data;
399 lgl_template_frame_get_size (frame, &w, &h);
401 page_w = pi->page_width;
402 page_h = pi->page_height;
406 cairo_set_source_rgb (pi->cr, OUTLINE_RGB_ARGS);
407 cairo_set_line_width (pi->cr, OUTLINE_WIDTH);
409 for (p=frame->all.layouts; p != NULL; p=p->next) {
411 layout = (lglTemplateLayout *)p->data;
415 xmax = layout->x0 + layout->dx*(layout->nx - 1) + w;
416 ymax = layout->y0 + layout->dy*(layout->ny - 1) + h;
424 for (ix=0; ix < nx; ix++) {
429 y1 = MAX((ymin - TICK_OFFSET), 0.0);
430 y2 = MAX((y1 - TICK_LENGTH), 0.0);
432 y3 = MIN((ymax + TICK_OFFSET), page_h);
433 y4 = MIN((y3 + TICK_LENGTH), page_h);
435 cairo_move_to (pi->cr, x1, y1);
436 cairo_line_to (pi->cr, x1, y2);
437 cairo_stroke (pi->cr);
439 cairo_move_to (pi->cr, x2, y1);
440 cairo_line_to (pi->cr, x2, y2);
441 cairo_stroke (pi->cr);
443 cairo_move_to (pi->cr, x1, y3);
444 cairo_line_to (pi->cr, x1, y4);
445 cairo_stroke (pi->cr);
447 cairo_move_to (pi->cr, x2, y3);
448 cairo_line_to (pi->cr, x2, y4);
449 cairo_stroke (pi->cr);
453 for (iy=0; iy < ny; iy++) {
458 x1 = MAX((xmin - TICK_OFFSET), 0.0);
459 x2 = MAX((x1 - TICK_LENGTH), 0.0);
461 x3 = MIN((xmax + TICK_OFFSET), page_w);
462 x4 = MIN((x3 + TICK_LENGTH), page_w);
464 cairo_move_to (pi->cr, x1, y1);
465 cairo_line_to (pi->cr, x2, y1);
466 cairo_stroke (pi->cr);
468 cairo_move_to (pi->cr, x1, y2);
469 cairo_line_to (pi->cr, x2, y2);
470 cairo_stroke (pi->cr);
472 cairo_move_to (pi->cr, x3, y1);
473 cairo_line_to (pi->cr, x4, y1);
474 cairo_stroke (pi->cr);
476 cairo_move_to (pi->cr, x3, y2);
477 cairo_line_to (pi->cr, x4, y2);
478 cairo_stroke (pi->cr);
484 cairo_restore (pi->cr);
486 gl_debug (DEBUG_PRINT, "END");
490 /*---------------------------------------------------------------------------*/
491 /* PRIVATE. Print i'th label. */
492 /*---------------------------------------------------------------------------*/
494 print_label (PrintInfo *pi,
498 glMergeRecord *record,
499 gboolean outline_flag,
500 gboolean reverse_flag)
502 gdouble width, height;
504 gl_debug (DEBUG_PRINT, "START");
506 gl_label_get_size (label, &width, &height);
510 /* Transform coordinate system to be relative to upper corner */
511 /* of the current label */
512 cairo_translate (pi->cr, x, y);
516 clip_to_outline (pi, label);
520 /* Special transformations. */
521 if (pi->rotate_flag) {
522 gl_debug (DEBUG_PRINT, "Rotate flag set");
523 cairo_rotate (pi->cr, G_PI/2.0);
524 cairo_translate (pi->cr, 0.0, -height);
526 if ( reverse_flag ) {
527 cairo_translate (pi->cr, width, 0.0);
528 cairo_scale (pi->cr, -1.0, 1.0);
531 gl_label_draw (label, pi->cr, FALSE, record);
533 cairo_restore (pi->cr); /* From special transformations. */
535 cairo_restore (pi->cr); /* From clip to outline. */
538 draw_outline (pi, label);
541 cairo_restore (pi->cr); /* From translation. */
543 gl_debug (DEBUG_PRINT, "END");
547 /*---------------------------------------------------------------------------*/
548 /* PRIVATE. Draw outline. */
549 /*---------------------------------------------------------------------------*/
551 draw_outline (PrintInfo *pi,
554 gl_debug (DEBUG_PRINT, "START");
558 cairo_set_source_rgb (pi->cr, OUTLINE_RGB_ARGS);
559 cairo_set_line_width (pi->cr, OUTLINE_WIDTH);
561 gl_cairo_label_path (pi->cr, pi->template, FALSE, FALSE);
563 cairo_stroke (pi->cr);
565 cairo_restore (pi->cr);
567 gl_debug (DEBUG_PRINT, "END");
571 /*---------------------------------------------------------------------------*/
572 /* PRIVATE. Clip to outline. */
573 /*---------------------------------------------------------------------------*/
575 clip_to_outline (PrintInfo *pi,
578 gl_debug (DEBUG_PRINT, "START");
580 gl_cairo_label_path (pi->cr, pi->template, FALSE, TRUE);
582 cairo_set_fill_rule (pi->cr, CAIRO_FILL_RULE_EVEN_ODD);
585 gl_debug (DEBUG_PRINT, "END");
593 * Local Variables: -- emacs
595 * c-basic-offset: 8 -- emacs
596 * tab-width: 8 -- emacs
597 * indent-tabs-mode: nil -- emacs