3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of libglabels.
7 * libglabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser 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 * libglabels 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 Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with libglabels. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
29 #include <sys/types.h>
32 #include "libglabels-private.h"
37 /*===========================================*/
38 /* Private macros and constants. */
39 /*===========================================*/
41 /* Allowed error when comparing dimensions. (0.5pts ~= .007in ~= .2mm) */
44 /*===========================================*/
46 /*===========================================*/
49 /*===========================================*/
51 /*===========================================*/
54 /*===========================================*/
55 /* Local function prototypes */
56 /*===========================================*/
58 static gint compare_origins (gconstpointer a,
62 /*===========================================*/
64 /*===========================================*/
68 * @brand: Template brand
69 * @part: Template part name/number
70 * @description: Template descriptions
71 * @paper_id: Page size id
72 * @page_width: Page width in points, set to zero unless paper_id="Other"
73 * @page_height: Page height in points, set to zero unless paper_id="Other"
75 * Create a new template structure, with the given top-level attributes. The
76 * created template will have no initial categories, or frames associated with
77 * it. See lgl_template_add_category() and lgl_template_add_frame() to add
80 * Returns: pointer to a newly allocated #lglTemplate structure.
84 lgl_template_new (const gchar *brand,
86 const gchar *description,
87 const gchar *paper_id,
91 lglTemplate *template;
93 template = g_new0 (lglTemplate,1);
95 template->brand = g_strdup (brand);
96 template->part = g_strdup (part);
97 template->description = g_strdup (description);
98 template->paper_id = g_strdup (paper_id);
99 template->page_width = page_width;
100 template->page_height = page_height;
107 * lgl_template_new_from_equiv:
108 * @brand: Template brand
109 * @part: Template part name/number
110 * @equiv_part: Name of equivalent part to base template on
112 * Create a new template structure based on an existing template. The
113 * created template will be a duplicate of the original template, except with
114 * the new part name/number.
116 * Returns: pointer to a newly allocated #lglTemplate structure.
120 lgl_template_new_from_equiv (const gchar *brand,
122 const gchar *equiv_part)
124 lglTemplate *template = NULL;
126 if ( lgl_db_does_template_exist (brand, equiv_part) )
128 template = lgl_db_lookup_template_from_brand_part (brand, equiv_part);
130 g_free (template->part);
131 g_free (template->equiv_part);
133 template->part = g_strdup (part);
134 template->equiv_part = g_strdup (equiv_part);
138 g_message (_("Equivalent part (\"%s\") for \"%s\", not previously defined."),
147 * lgl_template_get_name:
148 * @template: Pointer to template structure to test
150 * This function returns the name of the given template. The name is the concetenation
151 * of the brand and part name/number.
153 * Returns: A pointer to a newly allocated name string. Should be freed with g_free().
157 lgl_template_get_name (const lglTemplate *template)
159 g_return_val_if_fail (template, NULL);
161 return g_strdup_printf ("%s %s", template->brand, template->part);
166 * lgl_template_do_templates_match:
167 * @template1: Pointer to 1st template structure to test
168 * @template2: Pointer to 2nd template structure to test
170 * This function tests if the given templates match. This is a simple test that only tests
171 * the brand and part name/number. It does not test if they are actually identical.
173 * Returns: TRUE if the two templates match.
177 lgl_template_do_templates_match (const lglTemplate *template1,
178 const lglTemplate *template2)
180 g_return_val_if_fail (template1, FALSE);
181 g_return_val_if_fail (template2, FALSE);
183 return (UTF8_EQUAL (template1->brand, template2->brand) &&
184 UTF8_EQUAL (template1->part, template2->part));
189 * lgl_template_does_brand_match:
190 * @template: Pointer to template structure to test
191 * @brand: Brand string
193 * This function tests if the brand of the template matches the given brand.
195 * Returns: TRUE if the template matches the given brand.
199 lgl_template_does_brand_match (const lglTemplate *template,
202 g_return_val_if_fail (template, FALSE);
204 /* NULL matches everything. */
210 return UTF8_EQUAL (template->brand, brand);
215 * lgl_template_does_page_size_match:
216 * @template: Pointer to template structure to test
217 * @paper_id: Page size ID string
219 * This function tests if the page size of the template matches the given ID.
221 * Returns: TRUE if the template matches the given page size ID.
225 lgl_template_does_page_size_match (const lglTemplate *template,
226 const gchar *paper_id)
228 g_return_val_if_fail (template, FALSE);
230 /* NULL matches everything. */
231 if (paper_id == NULL)
236 return ASCII_EQUAL(paper_id, template->paper_id);
241 * lgl_template_does_category_match:
242 * @template: Pointer to template structure to test
243 * @category_id: Category ID string
245 * This function tests if the given template belongs to the given category ID.
247 * Returns: TRUE if the template matches the given category ID.
251 lgl_template_does_category_match (const lglTemplate *template,
252 const gchar *category_id)
256 g_return_val_if_fail (template, FALSE);
258 /* NULL matches everything. */
259 if (category_id == NULL)
264 for ( p=template->category_ids; p != NULL; p=p->next )
266 if (ASCII_EQUAL(category_id, p->data))
277 * lgl_template_are_templates_identical:
278 * @template1: Pointer to 1st template structure to test
279 * @template2: Pointer to 2nd template structure to test
281 * This function tests if the given templates have identical size and layout properties.
283 * Returns: TRUE if the two templates are identical.
287 lgl_template_are_templates_identical (const lglTemplate *template1,
288 const lglTemplate *template2)
290 lglTemplateFrame *frame1;
291 lglTemplateFrame *frame2;
294 lglTemplateLayout *layout1;
295 lglTemplateLayout *layout2;
296 gboolean match_found;
299 if (!UTF8_EQUAL (template1->paper_id, template2->paper_id) ||
300 (template1->page_width != template2->page_width) ||
301 (template1->page_height != template2->page_height))
306 frame1 = (lglTemplateFrame *)template1->frames->data;
307 frame2 = (lglTemplateFrame *)template2->frames->data;
309 if ( frame1->shape != frame2->shape )
314 switch ( frame1->shape )
317 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
318 if ( (fabs(frame1->rect.w - frame2->rect.w) > EPSILON) ||
319 (fabs(frame1->rect.h - frame2->rect.h) > EPSILON) )
325 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
326 if ( (fabs(frame1->ellipse.w - frame2->ellipse.w) > EPSILON) ||
327 (fabs(frame1->ellipse.h - frame2->ellipse.h) > EPSILON) )
333 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
334 if ( fabs(frame1->round.r - frame2->round.r) > EPSILON )
340 case LGL_TEMPLATE_FRAME_SHAPE_CD:
341 if ( (fabs(frame1->cd.r1 - frame2->cd.r1) > EPSILON) ||
342 (fabs(frame1->cd.r2 - frame2->cd.r2) > EPSILON) )
348 for ( p1 = frame1->all.layouts; p1; p1 = p1->next )
350 layout1 = (lglTemplateLayout *)p1->data;
353 for ( p2 = frame2->all.layouts; p2 && !match_found; p2 = p2->next )
355 layout2 = (lglTemplateLayout *)p2->data;
357 if ( (layout1->nx == layout2->nx) &&
358 (layout1->ny == layout2->ny) &&
359 (fabs(layout1->x0 - layout2->x0) < EPSILON) &&
360 (fabs(layout1->y0 - layout2->y0) < EPSILON) &&
361 (fabs(layout1->dx - layout2->dx) < EPSILON) &&
362 (fabs(layout1->dy - layout2->dy) < EPSILON) )
379 * lgl_template_add_frame:
380 * @template: Pointer to template structure
381 * @frame: Pointer to frame structure
383 * This function adds the given frame structure to the template. Once added,
384 * the frame structure belongs to the given template; do not attempt to free
387 * Note: Currently glabels only supports a single frame per template.
391 lgl_template_add_frame (lglTemplate *template,
392 lglTemplateFrame *frame)
394 g_return_if_fail (template);
395 g_return_if_fail (frame);
397 template->frames = g_list_append (template->frames, frame);
402 * lgl_template_add_category:
403 * @template: Pointer to template structure
404 * @category_id: Category ID string
406 * This function adds the given category ID to a templates category list.
410 lgl_template_add_category (lglTemplate *template,
411 const gchar *category_id)
413 g_return_if_fail (template);
414 g_return_if_fail (category_id);
416 template->category_ids = g_list_append (template->category_ids,
417 g_strdup (category_id));
422 * lgl_template_frame_rect_new:
423 * @id: ID of frame. (This should currently always be "0").
424 * @w: width of frame in points.
425 * @h: height of frame in points.
426 * @r: radius of rounded corners in points. (Should be 0 for square corners.)
427 * @x_waste: Amount of overprint to allow in the horizontal direction.
428 * @y_waste: Amount of overprint to allow in the vertical direction.
430 * This function creates a new template frame for a rectangular label or card.
432 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
436 lgl_template_frame_rect_new (const gchar *id,
443 lglTemplateFrame *frame;
445 frame = g_new0 (lglTemplateFrame, 1);
447 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_RECT;
448 frame->rect.id = g_strdup (id);
453 frame->rect.x_waste = x_waste;
454 frame->rect.y_waste = y_waste;
461 * lgl_template_frame_ellipse_new:
462 * @id: ID of frame. (This should currently always be "0").
463 * @w: width of frame in points.
464 * @h: height of frame in points.
465 * @waste: Amount of overprint to allow in points.
467 * This function creates a new template frame for an elliptical label or card.
469 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
473 lgl_template_frame_ellipse_new (const gchar *id,
478 lglTemplateFrame *frame;
480 frame = g_new0 (lglTemplateFrame, 1);
482 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE;
483 frame->ellipse.id = g_strdup (id);
485 frame->ellipse.w = w;
486 frame->ellipse.h = h;
487 frame->ellipse.waste = waste;
494 * lgl_template_frame_round_new:
495 * @id: ID of frame. (This should currently always be "0").
496 * @r: radius of label in points.
497 * @waste: Amount of overprint to allow.
499 * This function creates a new template frame for a round label.
501 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
505 lgl_template_frame_round_new (const gchar *id,
509 lglTemplateFrame *frame;
511 frame = g_new0 (lglTemplateFrame, 1);
513 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ROUND;
514 frame->round.id = g_strdup (id);
517 frame->round.waste = waste;
524 * lgl_template_frame_cd_new:
525 * @id: ID of frame. (This should currently always be "0").
526 * @r1: outer radius of label in points.
527 * @r2: radius of center hole in points.
528 * @w: clip width of frame in points for business card CDs. Should be 0 for no clipping.
529 * @h: clip height of frame in points for business card CDs. Should be 0 for no clipping.
530 * @waste: Amount of overprint to allow.
532 * This function creates a new template frame for a CD/DVD label.
534 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
538 lgl_template_frame_cd_new (const gchar *id,
545 lglTemplateFrame *frame;
547 frame = g_new0 (lglTemplateFrame, 1);
549 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_CD;
550 frame->cd.id = g_strdup (id);
556 frame->cd.waste = waste;
563 * lgl_template_frame_get_size:
564 * @frame: #lglTemplateFrame structure to query
565 * @w: pointer to location to receive width of frame
566 * @h: pointer to location to receive height of frame
568 * Get size (width and height) of given #lglTemplateFrame in points.
572 lgl_template_frame_get_size (const lglTemplateFrame *frame,
576 g_return_if_fail (frame);
578 switch (frame->shape) {
579 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
583 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
584 *w = frame->ellipse.w;
585 *h = frame->ellipse.h;
587 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
588 *w = 2.0 * frame->round.r;
589 *h = 2.0 * frame->round.r;
591 case LGL_TEMPLATE_FRAME_SHAPE_CD:
592 if (frame->cd.w == 0.0) {
593 *w = 2.0 * frame->cd.r1;
597 if (frame->cd.h == 0.0) {
598 *h = 2.0 * frame->cd.r1;
612 * lgl_template_frame_get_n_labels:
613 * @frame: #lglTemplateFrame structure to query
615 * Get total number of labels per sheet corresponding to the given frame.
617 * Returns: number of labels per sheet.
621 lgl_template_frame_get_n_labels (const lglTemplateFrame *frame)
625 lglTemplateLayout *layout;
627 g_return_val_if_fail (frame, 0);
629 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
630 layout = (lglTemplateLayout *)p->data;
632 n_labels += layout->nx * layout->ny;
640 * lgl_template_frame_get_layout_description
641 * @frame: #lglTemplateFrame structure to query
643 * Get a description of the label layout including number of labels per sheet.
645 * Returns: a newly allocation description string.
649 lgl_template_frame_get_layout_description (const lglTemplateFrame *frame)
653 lglTemplateLayout *layout;
655 n_labels = lgl_template_frame_get_n_labels (frame);
657 if ( frame->all.layouts && (frame->all.layouts->next == NULL) )
659 layout = (lglTemplateLayout *)frame->all.layouts->data;
661 * Translators: 1st %d = number of labels across a page,
662 * 2nd %d = number of labels down a page,
663 * 3rd %d = total number of labels on a page (sheet).
665 string = g_strdup_printf (_("%d × %d (%d per sheet)"), layout->nx, layout->ny, n_labels);
669 /* Translators: %d is the total number of labels on a page (sheet). */
670 string = g_strdup_printf (_("%d per sheet"), n_labels);
678 * lgl_template_frame_get_size_description
679 * @frame: #lglTemplateFrame structure to query
682 * Get a description of the label size.
684 * Returns: a newly allocation description string.
688 lgl_template_frame_get_size_description (const lglTemplateFrame *frame,
691 const gchar *units_string;
692 gdouble units_per_point;
693 gchar *string = NULL;
695 units_string = lgl_units_get_name (units);
696 units_per_point = lgl_units_get_units_per_point (units);
698 switch (frame->shape) {
699 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
700 if ( units == LGL_UNITS_INCH ) {
703 xstr = lgl_str_format_fraction (frame->rect.w*units_per_point);
704 ystr = lgl_str_format_fraction (frame->rect.h*units_per_point);
705 string = g_strdup_printf ("%s × %s %s",
706 xstr, ystr, units_string);
710 string = g_strdup_printf ("%.5g × %.5g %s",
711 frame->rect.w*units_per_point,
712 frame->rect.h*units_per_point,
716 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
717 if ( units == LGL_UNITS_INCH ) {
720 xstr = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
721 ystr = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
722 string = g_strdup_printf ("%s × %s %s",
723 xstr, ystr, units_string);
727 string = g_strdup_printf ("%.5g × %.5g %s",
728 frame->ellipse.w*units_per_point,
729 frame->ellipse.h*units_per_point,
733 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
734 if ( units == LGL_UNITS_INCH ) {
737 dstr = lgl_str_format_fraction (2.0*frame->round.r*units_per_point);
738 string = g_strdup_printf ("%s %s %s",
743 string = g_strdup_printf ("%.5g %s %s",
744 2.0*frame->round.r*units_per_point,
749 case LGL_TEMPLATE_FRAME_SHAPE_CD:
750 if ( units == LGL_UNITS_INCH ) {
753 dstr = lgl_str_format_fraction (2.0*frame->cd.r1*units_per_point);
754 string = g_strdup_printf ("%s %s %s",
759 string = g_strdup_printf ("%.5g %s %s",
760 2.0*frame->cd.r1*units_per_point,
774 * lgl_template_frame_get_origins:
775 * @frame: #lglTemplateFrame structure to query
777 * Get an array of label origins for the given frame. These origins represent the
778 * upper left hand corner of each label on a page corresponding to the given frame.
779 * The origins will be ordered geometrically left to right and then top to bottom.
780 * The array should be freed using g_free().
782 * Returns: A newly allocated array of #lglTemplateOrigin structures.
786 lgl_template_frame_get_origins (const lglTemplateFrame *frame)
788 gint i_label, n_labels, ix, iy;
789 lglTemplateOrigin *origins;
791 lglTemplateLayout *layout;
793 g_return_val_if_fail (frame, NULL);
795 n_labels = lgl_template_frame_get_n_labels (frame);
796 origins = g_new0 (lglTemplateOrigin, n_labels);
799 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
800 layout = (lglTemplateLayout *)p->data;
802 for (iy = 0; iy < layout->ny; iy++) {
803 for (ix = 0; ix < layout->nx; ix++, i_label++) {
804 origins[i_label].x = ix*layout->dx + layout->x0;
805 origins[i_label].y = iy*layout->dy + layout->y0;
810 g_qsort_with_data (origins, n_labels, sizeof(lglTemplateOrigin),
811 compare_origins, NULL);
818 * lgl_template_frame_add_layout:
819 * @frame: Pointer to template frame to add layout to.
820 * @layout: Pointer to layout structure to add to frame.
822 * This function adds a layout structure to the given template frame.
826 lgl_template_frame_add_layout (lglTemplateFrame *frame,
827 lglTemplateLayout *layout)
829 g_return_if_fail (frame);
830 g_return_if_fail (layout);
832 frame->all.layouts = g_list_append (frame->all.layouts, layout);
837 * lgl_template_frame_add_markup:
838 * @frame: Pointer to template frame to add markup to.
839 * @markup: Pointer to markup structure to add to frame.
841 * This function adds a markup structure to the given template frame.
845 lgl_template_frame_add_markup (lglTemplateFrame *frame,
846 lglTemplateMarkup *markup)
848 g_return_if_fail (frame);
849 g_return_if_fail (markup);
851 frame->all.markups = g_list_append (frame->all.markups, markup);
856 * lgl_template_layout_new:
857 * @nx: Number of labels across.
858 * @ny: Number of labels down.
859 * @x0: X coordinate of the top-left corner of the top-left label in the layout in points.
860 * @y0: Y coordinate of the top-left corner of the top-left label in the layout in points.
861 * @dx: Horizontal pitch in points. This is the distance from left-edge to left-edge.
862 * @dy: Vertical pitch in points. This is the distance from top-edge to top-edge.
864 * This function creates a new layout structure with the given parameters.
866 * Returns: a newly allocated #lglTemplateLayout structure.
870 lgl_template_layout_new (gint nx,
877 lglTemplateLayout *layout;
879 layout = g_new0 (lglTemplateLayout, 1);
893 * lgl_template_markup_margin_new:
894 * @size: margin size in points.
896 * This function creates a new margin markup structure.
898 * Returns: a newly allocated #lglTemplateMarkup structure.
902 lgl_template_markup_margin_new (gdouble size)
904 lglTemplateMarkup *markup;
906 markup = g_new0 (lglTemplateMarkup, 1);
908 markup->type = LGL_TEMPLATE_MARKUP_MARGIN;
909 markup->margin.size = size;
916 * lgl_template_markup_line_new:
917 * @x1: x coordinate of first endpoint.
918 * @y1: y coordinate of first endpoint.
919 * @x2: x coordinate of second endpoint.
920 * @y2: y coordinate of second endpoint.
922 * This function creates a new line markup structure.
924 * Returns: a newly allocated #lglTemplateMarkup structure.
928 lgl_template_markup_line_new (gdouble x1,
933 lglTemplateMarkup *markup;
935 markup = g_new0 (lglTemplateMarkup, 1);
937 markup->type = LGL_TEMPLATE_MARKUP_LINE;
938 markup->line.x1 = x1;
939 markup->line.y1 = y1;
940 markup->line.x2 = x2;
941 markup->line.y2 = y2;
948 * lgl_template_markup_circle_new:
949 * @x0: x coordinate of center of circle.
950 * @y0: y coordinate of center of circle.
951 * @r: radius of circle.
953 * This function creates a new circle markup structure.
955 * Returns: a newly allocated #lglTemplateMarkup structure.
959 lgl_template_markup_circle_new (gdouble x0,
963 lglTemplateMarkup *markup;
965 markup = g_new0 (lglTemplateMarkup, 1);
967 markup->type = LGL_TEMPLATE_MARKUP_CIRCLE;
968 markup->circle.x0 = x0;
969 markup->circle.y0 = y0;
970 markup->circle.r = r;
977 * lgl_template_markup_rect_new:
978 * @x1: x coordinate of top-left corner of rectangle.
979 * @y1: y coordinate of top-left corner of rectangle.
980 * @w: width of rectangle.
981 * @h: height of rectangle.
982 * @r: radius of rounded corner.
984 * This function creates a new rectangle markup structure.
986 * Returns: a newly allocated #lglTemplateMarkup structure.
990 lgl_template_markup_rect_new (gdouble x1,
996 lglTemplateMarkup *markup;
998 markup = g_new0 (lglTemplateMarkup, 1);
1000 markup->type = LGL_TEMPLATE_MARKUP_RECT;
1001 markup->rect.x1 = x1;
1002 markup->rect.y1 = y1;
1012 * lgl_template_markup_ellipse_new:
1013 * @x1: x coordinate of top-left corner of ellipse.
1014 * @y1: y coordinate of top-left corner of ellipse.
1015 * @w: width of ellipse.
1016 * @h: height of ellipse.
1018 * This function creates a new ellipse markup structure.
1020 * Returns: a newly allocated #lglTemplateMarkup structure.
1024 lgl_template_markup_ellipse_new (gdouble x1,
1029 lglTemplateMarkup *markup;
1031 markup = g_new0 (lglTemplateMarkup, 1);
1033 markup->type = LGL_TEMPLATE_MARKUP_ELLIPSE;
1034 markup->ellipse.x1 = x1;
1035 markup->ellipse.y1 = y1;
1036 markup->ellipse.w = w;
1037 markup->ellipse.h = h;
1045 * @orig_template: Template to duplicate.
1047 * This function duplicates a template structure.
1049 * Returns: a newly allocated #lglTemplate structure.
1053 lgl_template_dup (const lglTemplate *orig_template)
1055 lglTemplate *template;
1057 lglTemplateFrame *frame;
1059 g_return_val_if_fail (orig_template, NULL);
1061 template = lgl_template_new (orig_template->brand,
1062 orig_template->part,
1063 orig_template->description,
1064 orig_template->paper_id,
1065 orig_template->page_width,
1066 orig_template->page_height);
1068 template->equiv_part = g_strdup (orig_template->equiv_part);
1069 template->product_url = g_strdup (orig_template->product_url);
1072 for ( p=orig_template->category_ids; p != NULL; p=p->next )
1074 lgl_template_add_category (template, p->data);
1077 for ( p=orig_template->frames; p != NULL; p=p->next )
1079 frame = (lglTemplateFrame *)p->data;
1081 lgl_template_add_frame (template, lgl_template_frame_dup (frame));
1089 * lgl_template_free:
1090 * @template: Template to free.
1092 * This function frees all memory associated with given template structure.
1096 lgl_template_free (lglTemplate *template)
1099 lglTemplateFrame *frame;
1101 if ( template != NULL ) {
1103 g_free (template->brand);
1104 template->brand = NULL;
1106 g_free (template->part);
1107 template->part = NULL;
1109 g_free (template->description);
1110 template->description = NULL;
1112 g_free (template->paper_id);
1113 template->paper_id = NULL;
1115 for ( p=template->category_ids; p != NULL; p=p->next ) {
1121 g_list_free (template->category_ids);
1122 template->category_ids = NULL;
1124 for ( p=template->frames; p != NULL; p=p->next ) {
1126 frame = (lglTemplateFrame *)p->data;
1128 lgl_template_frame_free (frame);
1131 g_list_free (template->frames);
1132 template->frames = NULL;
1142 * lgl_template_frame_dup:
1143 * @orig_frame: Frame to duplicate.
1145 * This function duplicates a template frame structure.
1147 * Returns: a newly allocated #lglTemplateFrame structure.
1151 lgl_template_frame_dup (const lglTemplateFrame *orig_frame)
1153 lglTemplateFrame *frame;
1155 lglTemplateLayout *layout;
1156 lglTemplateMarkup *markup;
1158 g_return_val_if_fail (orig_frame, NULL);
1160 switch (orig_frame->shape) {
1162 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
1164 lgl_template_frame_rect_new (orig_frame->all.id,
1168 orig_frame->rect.x_waste,
1169 orig_frame->rect.y_waste);
1172 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
1174 lgl_template_frame_ellipse_new (orig_frame->all.id,
1175 orig_frame->ellipse.w,
1176 orig_frame->ellipse.h,
1177 orig_frame->ellipse.waste);
1180 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
1182 lgl_template_frame_round_new (orig_frame->all.id,
1183 orig_frame->round.r,
1184 orig_frame->round.waste);
1187 case LGL_TEMPLATE_FRAME_SHAPE_CD:
1189 lgl_template_frame_cd_new (orig_frame->all.id,
1194 orig_frame->cd.waste);
1202 for ( p=orig_frame->all.layouts; p != NULL; p=p->next ) {
1204 layout = (lglTemplateLayout *)p->data;
1206 lgl_template_frame_add_layout (frame, lgl_template_layout_dup (layout));
1209 for ( p=orig_frame->all.markups; p != NULL; p=p->next ) {
1211 markup = (lglTemplateMarkup *)p->data;
1213 lgl_template_frame_add_markup (frame, lgl_template_markup_dup (markup));
1221 * lgl_template_frame_free:
1222 * @frame: Frame to free.
1224 * This function frees all memory associated with given template frame structure.
1228 lgl_template_frame_free (lglTemplateFrame *frame)
1231 lglTemplateLayout *layout;
1232 lglTemplateMarkup *markup;
1234 if ( frame != NULL ) {
1236 g_free (frame->all.id);
1237 frame->all.id = NULL;
1239 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
1241 layout = (lglTemplateLayout *)p->data;
1243 lgl_template_layout_free (layout);
1246 g_list_free (frame->all.layouts);
1247 frame->all.layouts = NULL;
1249 for ( p=frame->all.markups; p != NULL; p=p->next ) {
1251 markup = (lglTemplateMarkup *)p->data;
1253 lgl_template_markup_free (markup);
1256 g_list_free (frame->all.markups);
1257 frame->all.markups = NULL;
1267 * lgl_template_layout_dup:
1268 * @orig_layout: Layout to duplicate.
1270 * This function duplicates a template layout structure.
1272 * Returns: a newly allocated #lglTemplateLayout structure.
1276 lgl_template_layout_dup (const lglTemplateLayout *orig_layout)
1278 lglTemplateLayout *layout;
1280 g_return_val_if_fail (orig_layout, NULL);
1282 layout = g_new0 (lglTemplateLayout, 1);
1285 *layout = *orig_layout;
1292 * lgl_template_layout_free:
1293 * @layout: Layout to free.
1295 * This function frees all memory associated with given template layout structure.
1299 lgl_template_layout_free (lglTemplateLayout *layout)
1306 * lgl_template_markup_dup:
1307 * @orig_markup: Markup to duplicate.
1309 * This function duplicates a template markup structure.
1311 * Returns: a newly allocated #lglTemplateMarkup structure.
1315 lgl_template_markup_dup (const lglTemplateMarkup *orig_markup)
1317 lglTemplateMarkup *markup;
1319 g_return_val_if_fail (orig_markup, NULL);
1321 markup = g_new0 (lglTemplateMarkup, 1);
1323 *markup = *orig_markup;
1330 * lgl_template_markup_free:
1331 * @markup: Markup to free.
1333 * This function frees all memory associated with given template markup structure.
1337 lgl_template_markup_free (lglTemplateMarkup *markup)
1344 compare_origins (gconstpointer a,
1348 const lglTemplateOrigin *a_origin = a, *b_origin = b;
1350 if ( a_origin->y < b_origin->y ) {
1352 } else if ( a_origin->y > b_origin->y ) {
1355 if ( a_origin->x < b_origin->x ) {
1357 } else if ( a_origin->x > b_origin->x ) {
1360 return 0; /* hopefully 2 labels won't have the same origin */
1367 * lgl_template_print:
1368 * @template: template
1370 * Print template details (for debugging purposes).
1374 lgl_template_print (const lglTemplate *template)
1376 g_print ("---- %s( TEMPLATE=%p ) ----\n", __FUNCTION__, template);
1378 g_print("brand=\"%s\", part=\"%s\", description=\"%s\"\n",
1379 template->brand, template->part, template->description);
1381 g_print("paper_id=\"%s\", page_width=%g, page_height=%g\n",
1382 template->paper_id, template->page_width, template->page_height);
1391 * Local Variables: -- emacs
1393 * c-basic-offset: 8 -- emacs
1394 * tab-width: 8 -- emacs
1395 * indent-tabs-mode: nil -- emacs