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 aliases, categories, or frames
77 * associated with it. See lgl_template_add_alias(), lgl_template_add_category(),
78 * and lgl_template_add_frame() to add these.
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;
92 lglTemplateAlias *alias;
94 template = g_new0 (lglTemplate,1);
96 template->brand = g_strdup (brand);
97 template->part = g_strdup (part);
98 template->description = g_strdup (description);
99 template->paper_id = g_strdup (paper_id);
100 template->page_width = page_width;
101 template->page_height = page_height;
103 /* Always include primary name in alias list. */
104 template->aliases = NULL;
105 alias = lgl_template_alias_new (brand, part);
106 lgl_template_add_alias (template, alias);
113 * lgl_template_new_from_equiv:
114 * @brand: Template brand
115 * @part: Template part name/number
116 * @equiv_part: Name of equivalent part to base template on
118 * Create a new template structure based on an existing template. The
119 * created template will be a duplicate of the original template, except with
120 * the new part name/number.
122 * Returns: pointer to a newly allocated #lglTemplate structure.
126 lgl_template_new_from_equiv (const gchar *brand,
128 const gchar *equiv_part)
130 lglTemplate *template;
132 lglTemplateAlias *alias;
134 template = lgl_db_lookup_template_from_brand_part (brand, equiv_part);
137 g_free (template->part);
138 g_free (template->equiv_part);
140 template->part = g_strdup (part);
141 template->equiv_part = g_strdup (equiv_part);
143 for ( p_alias = template->aliases; p_alias != NULL; p_alias = p_alias->next )
145 alias = (lglTemplateAlias *)p_alias->data;
146 lgl_template_alias_free (alias);
148 g_list_free (template->aliases);
149 template->aliases = NULL;
151 alias = lgl_template_alias_new (brand, part);
152 lgl_template_add_alias (template, alias);
156 g_message (_("Equivalent part (\"%s\") for \"%s\", not previously defined."),
165 * lgl_template_get_name:
166 * @template: Pointer to template structure to test
168 * This function returns the name of the given template. The name is the concetenation
169 * of the brand and part name/number.
171 * Returns: A pointer to a newly allocated name string. Should be freed with g_free().
175 lgl_template_get_name (const lglTemplate *template)
177 g_return_val_if_fail (template, NULL);
179 return g_strdup_printf ("%s %s", template->brand, template->part);
184 * lgl_template_do_templates_match:
185 * @template1: Pointer to 1st template structure to test
186 * @template2: Pointer to 2nd template structure to test
188 * This function tests if the given templates match. This is a simple test that only tests
189 * the brand and part name/number. It does not test if they are actually identical.
191 * Returns: TRUE if the two templates match.
195 lgl_template_do_templates_match (const lglTemplate *template1,
196 const lglTemplate *template2)
198 g_return_val_if_fail (template1, FALSE);
199 g_return_val_if_fail (template2, FALSE);
201 return (UTF8_EQUAL (template1->brand, template2->brand) &&
202 UTF8_EQUAL (template1->part, template2->part));
207 * lgl_template_does_brand_match:
208 * @template: Pointer to template structure to test
209 * @brand: Brand string
211 * This function tests if the brand of the template matches the given brand.
213 * Returns: TRUE if the template matches the given brand.
217 lgl_template_does_brand_match (const lglTemplate *template,
220 g_return_val_if_fail (template, FALSE);
222 /* NULL matches everything. */
228 return UTF8_EQUAL (template->brand, brand);
233 * lgl_template_does_page_size_match:
234 * @template: Pointer to template structure to test
235 * @paper_id: Page size ID string
237 * This function tests if the page size of the template matches the given ID.
239 * Returns: TRUE if the template matches the given page size ID.
243 lgl_template_does_page_size_match (const lglTemplate *template,
244 const gchar *paper_id)
246 g_return_val_if_fail (template, FALSE);
248 /* NULL matches everything. */
249 if (paper_id == NULL)
254 return ASCII_EQUAL(paper_id, template->paper_id);
259 * lgl_template_does_category_match:
260 * @template: Pointer to template structure to test
261 * @category_id: Category ID string
263 * This function tests if the given template belongs to the given category ID.
265 * Returns: TRUE if the template matches the given category ID.
269 lgl_template_does_category_match (const lglTemplate *template,
270 const gchar *category_id)
274 g_return_val_if_fail (template, FALSE);
276 /* NULL matches everything. */
277 if (category_id == NULL)
282 for ( p=template->category_ids; p != NULL; p=p->next )
284 if (ASCII_EQUAL(category_id, p->data))
295 * lgl_template_are_templates_identical:
296 * @template1: Pointer to 1st template structure to test
297 * @template2: Pointer to 2nd template structure to test
299 * This function tests if the given templates have identical size and layout properties.
301 * Returns: TRUE if the two templates are identical.
305 lgl_template_are_templates_identical (const lglTemplate *template1,
306 const lglTemplate *template2)
308 lglTemplateFrame *frame1;
309 lglTemplateFrame *frame2;
312 lglTemplateLayout *layout1;
313 lglTemplateLayout *layout2;
314 gboolean match_found;
317 if (!UTF8_EQUAL (template1->paper_id, template2->paper_id) ||
318 (template1->page_width != template2->page_width) ||
319 (template1->page_height != template2->page_height))
324 frame1 = (lglTemplateFrame *)template1->frames->data;
325 frame2 = (lglTemplateFrame *)template2->frames->data;
327 if ( frame1->shape != frame2->shape )
332 switch ( frame1->shape )
335 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
336 if ( (fabs(frame1->rect.w - frame2->rect.w) > EPSILON) ||
337 (fabs(frame1->rect.h - frame2->rect.h) > EPSILON) )
343 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
344 if ( (fabs(frame1->ellipse.w - frame2->ellipse.w) > EPSILON) ||
345 (fabs(frame1->ellipse.h - frame2->ellipse.h) > EPSILON) )
351 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
352 if ( fabs(frame1->round.r - frame2->round.r) > EPSILON )
358 case LGL_TEMPLATE_FRAME_SHAPE_CD:
359 if ( (fabs(frame1->cd.r1 - frame2->cd.r1) > EPSILON) ||
360 (fabs(frame1->cd.r2 - frame2->cd.r2) > EPSILON) )
366 for ( p1 = frame1->all.layouts; p1; p1 = p1->next )
368 layout1 = (lglTemplateLayout *)p1->data;
371 for ( p2 = frame2->all.layouts; p2 && !match_found; p2 = p2->next )
373 layout2 = (lglTemplateLayout *)p2->data;
375 if ( (layout1->nx == layout2->nx) &&
376 (layout1->ny == layout2->ny) &&
377 (fabs(layout1->x0 - layout2->x0) < EPSILON) &&
378 (fabs(layout1->y0 - layout2->y0) < EPSILON) &&
379 (fabs(layout1->dx - layout2->dx) < EPSILON) &&
380 (fabs(layout1->dy - layout2->dy) < EPSILON) )
397 * lgl_template_alias_new:
398 * @brand: Alias brand
399 * @part: Alias part name/number
401 * Create a new template alias structure, with the given brand and part number.
403 * Returns: pointer to a newly allocated #lglTemplateAlias structure.
407 lgl_template_alias_new (const gchar *brand,
410 lglTemplateAlias *alias;
412 alias = g_new0 (lglTemplateAlias,1);
414 alias->brand = g_strdup (brand);
415 alias->part = g_strdup (part);
422 * lgl_template_add_alias:
423 * @template: Pointer to template structure
424 * @alias: Alias string
426 * This function adds the given alias to a templates list of aliases.
430 lgl_template_add_alias (lglTemplate *template,
431 lglTemplateAlias *alias)
433 g_return_if_fail (template);
434 g_return_if_fail (alias);
436 template->aliases = g_list_append (template->aliases, alias);
441 * lgl_template_add_frame:
442 * @template: Pointer to template structure
443 * @frame: Pointer to frame structure
445 * This function adds the given frame structure to the template. Once added,
446 * the frame structure belongs to the given template; do not attempt to free
449 * Note: Currently glabels only supports a single frame per template.
453 lgl_template_add_frame (lglTemplate *template,
454 lglTemplateFrame *frame)
456 g_return_if_fail (template);
457 g_return_if_fail (frame);
459 template->frames = g_list_append (template->frames, frame);
464 * lgl_template_add_category:
465 * @template: Pointer to template structure
466 * @category_id: Category ID string
468 * This function adds the given category ID to a templates category list.
472 lgl_template_add_category (lglTemplate *template,
473 const gchar *category_id)
475 g_return_if_fail (template);
476 g_return_if_fail (category_id);
478 template->category_ids = g_list_append (template->category_ids,
479 g_strdup (category_id));
484 * lgl_template_frame_rect_new:
485 * @id: ID of frame. (This should currently always be "0").
486 * @w: width of frame in points.
487 * @h: height of frame in points.
488 * @r: radius of rounded corners in points. (Should be 0 for square corners.)
489 * @x_waste: Amount of overprint to allow in the horizontal direction.
490 * @y_waste: Amount of overprint to allow in the vertical direction.
492 * This function creates a new template frame for a rectangular label or card.
494 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
498 lgl_template_frame_rect_new (const gchar *id,
505 lglTemplateFrame *frame;
507 frame = g_new0 (lglTemplateFrame, 1);
509 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_RECT;
510 frame->rect.id = g_strdup (id);
515 frame->rect.x_waste = x_waste;
516 frame->rect.y_waste = y_waste;
523 * lgl_template_frame_ellipse_new:
524 * @id: ID of frame. (This should currently always be "0").
525 * @w: width of frame in points.
526 * @h: height of frame in points.
527 * @waste: Amount of overprint to allow in points.
529 * This function creates a new template frame for an elliptical label or card.
531 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
535 lgl_template_frame_ellipse_new (const gchar *id,
540 lglTemplateFrame *frame;
542 frame = g_new0 (lglTemplateFrame, 1);
544 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE;
545 frame->ellipse.id = g_strdup (id);
547 frame->ellipse.w = w;
548 frame->ellipse.h = h;
549 frame->ellipse.waste = waste;
556 * lgl_template_frame_round_new:
557 * @id: ID of frame. (This should currently always be "0").
558 * @r: radius of label in points.
559 * @waste: Amount of overprint to allow.
561 * This function creates a new template frame for a round label.
563 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
567 lgl_template_frame_round_new (const gchar *id,
571 lglTemplateFrame *frame;
573 frame = g_new0 (lglTemplateFrame, 1);
575 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ROUND;
576 frame->round.id = g_strdup (id);
579 frame->round.waste = waste;
586 * lgl_template_frame_cd_new:
587 * @id: ID of frame. (This should currently always be "0").
588 * @r1: outer radius of label in points.
589 * @r2: radius of center hole in points.
590 * @w: clip width of frame in points for business card CDs. Should be 0 for no clipping.
591 * @h: clip height of frame in points for business card CDs. Should be 0 for no clipping.
592 * @waste: Amount of overprint to allow.
594 * This function creates a new template frame for a CD/DVD label.
596 * Returns: Pointer to newly allocated #lglTemplateFrame structure.
600 lgl_template_frame_cd_new (const gchar *id,
607 lglTemplateFrame *frame;
609 frame = g_new0 (lglTemplateFrame, 1);
611 frame->shape = LGL_TEMPLATE_FRAME_SHAPE_CD;
612 frame->cd.id = g_strdup (id);
618 frame->cd.waste = waste;
625 * lgl_template_frame_get_size:
626 * @frame: #lglTemplateFrame structure to query
627 * @w: pointer to location to receive width of frame
628 * @h: pointer to location to receive height of frame
630 * Get size (width and height) of given #lglTemplateFrame in points.
634 lgl_template_frame_get_size (const lglTemplateFrame *frame,
638 g_return_if_fail (frame);
640 switch (frame->shape) {
641 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
645 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
646 *w = frame->ellipse.w;
647 *h = frame->ellipse.h;
649 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
650 *w = 2.0 * frame->round.r;
651 *h = 2.0 * frame->round.r;
653 case LGL_TEMPLATE_FRAME_SHAPE_CD:
654 if (frame->cd.w == 0.0) {
655 *w = 2.0 * frame->cd.r1;
659 if (frame->cd.h == 0.0) {
660 *h = 2.0 * frame->cd.r1;
674 * lgl_template_frame_get_n_labels:
675 * @frame: #lglTemplateFrame structure to query
677 * Get total number of labels per sheet corresponding to the given frame.
679 * Returns: number of labels per sheet.
683 lgl_template_frame_get_n_labels (const lglTemplateFrame *frame)
687 lglTemplateLayout *layout;
689 g_return_val_if_fail (frame, 0);
691 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
692 layout = (lglTemplateLayout *)p->data;
694 n_labels += layout->nx * layout->ny;
702 * lgl_template_frame_get_layout_description
703 * @frame: #lglTemplateFrame structure to query
705 * Get a description of the label layout including number of labels per sheet.
707 * Returns: a newly allocation description string.
711 lgl_template_frame_get_layout_description (const lglTemplateFrame *frame)
715 lglTemplateLayout *layout;
717 n_labels = lgl_template_frame_get_n_labels (frame);
719 if ( frame->all.layouts && (frame->all.layouts->next == NULL) )
721 layout = (lglTemplateLayout *)frame->all.layouts->data;
722 string = g_strdup_printf ("%d × %d (%d %s)", layout->nx, layout->ny, n_labels, _("per sheet"));
726 string = g_strdup_printf (_("%d %s"), n_labels, _("per sheet"));
734 * lgl_template_frame_get_size_description
735 * @frame: #lglTemplateFrame structure to query
738 * Get a description of the label size.
740 * Returns: a newly allocation description string.
744 lgl_template_frame_get_size_description (const lglTemplateFrame *frame,
747 const gchar *units_string;
748 gdouble units_per_point;
749 gchar *string = NULL;
751 units_string = lgl_units_get_name (units);
752 units_per_point = lgl_units_get_units_per_point (units);
754 switch (frame->shape) {
755 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
756 if ( units == LGL_UNITS_INCH ) {
759 xstr = lgl_str_format_fraction (frame->rect.w*units_per_point);
760 ystr = lgl_str_format_fraction (frame->rect.h*units_per_point);
761 string = g_strdup_printf ("%s × %s %s",
762 xstr, ystr, units_string);
766 string = g_strdup_printf ("%.5g × %.5g %s",
767 frame->rect.w*units_per_point,
768 frame->rect.h*units_per_point,
772 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
773 if ( units == LGL_UNITS_INCH ) {
776 xstr = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
777 ystr = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
778 string = g_strdup_printf ("%s × %s %s",
779 xstr, ystr, units_string);
783 string = g_strdup_printf ("%.5g × %.5g %s",
784 frame->ellipse.w*units_per_point,
785 frame->ellipse.h*units_per_point,
789 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
790 if ( units == LGL_UNITS_INCH ) {
793 dstr = lgl_str_format_fraction (2.0*frame->round.r*units_per_point);
794 string = g_strdup_printf ("%s %s %s",
799 string = g_strdup_printf ("%.5g %s %s",
800 2.0*frame->round.r*units_per_point,
805 case LGL_TEMPLATE_FRAME_SHAPE_CD:
806 if ( units == LGL_UNITS_INCH ) {
809 dstr = lgl_str_format_fraction (2.0*frame->cd.r1*units_per_point);
810 string = g_strdup_printf ("%s %s %s",
815 string = g_strdup_printf ("%.5g %s %s",
816 2.0*frame->cd.r1*units_per_point,
830 * lgl_template_frame_get_origins:
831 * @frame: #lglTemplateFrame structure to query
833 * Get an array of label origins for the given frame. These origins represent the
834 * upper left hand corner of each label on a page corresponding to the given frame.
835 * The origins will be ordered geometrically left to right and then top to bottom.
836 * The array should be freed using g_free().
838 * Returns: A newly allocated array of #lglTemplateOrigin structures.
842 lgl_template_frame_get_origins (const lglTemplateFrame *frame)
844 gint i_label, n_labels, ix, iy;
845 lglTemplateOrigin *origins;
847 lglTemplateLayout *layout;
849 g_return_val_if_fail (frame, NULL);
851 n_labels = lgl_template_frame_get_n_labels (frame);
852 origins = g_new0 (lglTemplateOrigin, n_labels);
855 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
856 layout = (lglTemplateLayout *)p->data;
858 for (iy = 0; iy < layout->ny; iy++) {
859 for (ix = 0; ix < layout->nx; ix++, i_label++) {
860 origins[i_label].x = ix*layout->dx + layout->x0;
861 origins[i_label].y = iy*layout->dy + layout->y0;
866 g_qsort_with_data (origins, n_labels, sizeof(lglTemplateOrigin),
867 compare_origins, NULL);
874 * lgl_template_frame_add_layout:
875 * @frame: Pointer to template frame to add layout to.
876 * @layout: Pointer to layout structure to add to frame.
878 * This function adds a layout structure to the given template frame.
882 lgl_template_frame_add_layout (lglTemplateFrame *frame,
883 lglTemplateLayout *layout)
885 g_return_if_fail (frame);
886 g_return_if_fail (layout);
888 frame->all.layouts = g_list_append (frame->all.layouts, layout);
893 * lgl_template_frame_add_markup:
894 * @frame: Pointer to template frame to add markup to.
895 * @markup: Pointer to markup structure to add to frame.
897 * This function adds a markup structure to the given template frame.
901 lgl_template_frame_add_markup (lglTemplateFrame *frame,
902 lglTemplateMarkup *markup)
904 g_return_if_fail (frame);
905 g_return_if_fail (markup);
907 frame->all.markups = g_list_append (frame->all.markups, markup);
912 * lgl_template_layout_new:
913 * @nx: Number of labels across.
914 * @ny: Number of labels down.
915 * @x0: X coordinate of the top-left corner of the top-left label in the layout in points.
916 * @y0: Y coordinate of the top-left corner of the top-left label in the layout in points.
917 * @dx: Horizontal pitch in points. This is the distance from left-edge to left-edge.
918 * @dy: Vertical pitch in points. This is the distance from top-edge to top-edge.
920 * This function creates a new layout structure with the given parameters.
922 * Returns: a newly allocated #lglTemplateLayout structure.
926 lgl_template_layout_new (gint nx,
933 lglTemplateLayout *layout;
935 layout = g_new0 (lglTemplateLayout, 1);
949 * lgl_template_markup_margin_new:
950 * @size: margin size in points.
952 * This function creates a new margin markup structure.
954 * Returns: a newly allocated #lglTemplateMarkup structure.
958 lgl_template_markup_margin_new (gdouble size)
960 lglTemplateMarkup *markup;
962 markup = g_new0 (lglTemplateMarkup, 1);
964 markup->type = LGL_TEMPLATE_MARKUP_MARGIN;
965 markup->margin.size = size;
972 * lgl_template_markup_line_new:
973 * @x1: x coordinate of first endpoint.
974 * @y1: y coordinate of first endpoint.
975 * @x2: x coordinate of second endpoint.
976 * @y2: y coordinate of second endpoint.
978 * This function creates a new line markup structure.
980 * Returns: a newly allocated #lglTemplateMarkup structure.
984 lgl_template_markup_line_new (gdouble x1,
989 lglTemplateMarkup *markup;
991 markup = g_new0 (lglTemplateMarkup, 1);
993 markup->type = LGL_TEMPLATE_MARKUP_LINE;
994 markup->line.x1 = x1;
995 markup->line.y1 = y1;
996 markup->line.x2 = x2;
997 markup->line.y2 = y2;
1004 * lgl_template_markup_circle_new:
1005 * @x0: x coordinate of center of circle.
1006 * @y0: y coordinate of center of circle.
1007 * @r: radius of circle.
1009 * This function creates a new circle markup structure.
1011 * Returns: a newly allocated #lglTemplateMarkup structure.
1015 lgl_template_markup_circle_new (gdouble x0,
1019 lglTemplateMarkup *markup;
1021 markup = g_new0 (lglTemplateMarkup, 1);
1023 markup->type = LGL_TEMPLATE_MARKUP_CIRCLE;
1024 markup->circle.x0 = x0;
1025 markup->circle.y0 = y0;
1026 markup->circle.r = r;
1033 * lgl_template_markup_rect_new:
1034 * @x1: x coordinate of top-left corner of rectangle.
1035 * @y1: y coordinate of top-left corner of rectangle.
1036 * @w: width of rectangle.
1037 * @h: height of rectangle.
1038 * @r: radius of rounded corner.
1040 * This function creates a new rectangle markup structure.
1042 * Returns: a newly allocated #lglTemplateMarkup structure.
1046 lgl_template_markup_rect_new (gdouble x1,
1052 lglTemplateMarkup *markup;
1054 markup = g_new0 (lglTemplateMarkup, 1);
1056 markup->type = LGL_TEMPLATE_MARKUP_RECT;
1057 markup->rect.x1 = x1;
1058 markup->rect.y1 = y1;
1068 * lgl_template_markup_ellipse_new:
1069 * @x1: x coordinate of top-left corner of ellipse.
1070 * @y1: y coordinate of top-left corner of ellipse.
1071 * @w: width of ellipse.
1072 * @h: height of ellipse.
1074 * This function creates a new ellipse markup structure.
1076 * Returns: a newly allocated #lglTemplateMarkup structure.
1080 lgl_template_markup_ellipse_new (gdouble x1,
1085 lglTemplateMarkup *markup;
1087 markup = g_new0 (lglTemplateMarkup, 1);
1089 markup->type = LGL_TEMPLATE_MARKUP_ELLIPSE;
1090 markup->ellipse.x1 = x1;
1091 markup->ellipse.y1 = y1;
1092 markup->ellipse.w = w;
1093 markup->ellipse.h = h;
1101 * @orig_template: Template to duplicate.
1103 * This function duplicates a template structure.
1105 * Returns: a newly allocated #lglTemplate structure.
1109 lgl_template_dup (const lglTemplate *orig_template)
1111 lglTemplate *template;
1112 lglTemplateAlias *alias;
1114 lglTemplateFrame *frame;
1116 g_return_val_if_fail (orig_template, NULL);
1118 template = lgl_template_new (orig_template->brand,
1119 orig_template->part,
1120 orig_template->description,
1121 orig_template->paper_id,
1122 orig_template->page_width,
1123 orig_template->page_height);
1125 template->equiv_part = g_strdup (orig_template->equiv_part);
1126 template->product_url = g_strdup (orig_template->product_url);
1128 for ( p=orig_template->aliases; p != NULL; p=p->next )
1130 alias = (lglTemplateAlias *)p->data;
1132 if ( !(UTF8_EQUAL (template->brand, alias->brand) &&
1133 UTF8_EQUAL (template->part, alias->part)) )
1135 lgl_template_add_alias (template, lgl_template_alias_dup (alias));
1140 for ( p=orig_template->category_ids; p != NULL; p=p->next )
1142 lgl_template_add_category (template, p->data);
1145 for ( p=orig_template->frames; p != NULL; p=p->next )
1147 frame = (lglTemplateFrame *)p->data;
1149 lgl_template_add_frame (template, lgl_template_frame_dup (frame));
1157 * lgl_template_free:
1158 * @template: Template to free.
1160 * This function frees all memory associated with given template structure.
1164 lgl_template_free (lglTemplate *template)
1167 lglTemplateFrame *frame;
1169 if ( template != NULL ) {
1171 g_free (template->brand);
1172 template->brand = NULL;
1174 g_free (template->part);
1175 template->part = NULL;
1177 g_free (template->description);
1178 template->description = NULL;
1180 g_free (template->paper_id);
1181 template->paper_id = NULL;
1183 for ( p=template->aliases; p != NULL; p=p->next ) {
1185 lgl_template_alias_free (p->data);
1189 g_list_free (template->aliases);
1190 template->aliases = NULL;
1192 for ( p=template->category_ids; p != NULL; p=p->next ) {
1198 g_list_free (template->category_ids);
1199 template->category_ids = NULL;
1201 for ( p=template->frames; p != NULL; p=p->next ) {
1203 frame = (lglTemplateFrame *)p->data;
1205 lgl_template_frame_free (frame);
1208 g_list_free (template->frames);
1209 template->frames = NULL;
1219 * lgl_template_alias_dup:
1220 * @orig_alias: Alias to duplicate.
1222 * This function duplicates a template alias structure.
1224 * Returns: a newly allocated #lglTemplateAlias structure.
1228 lgl_template_alias_dup (const lglTemplateAlias *orig_alias)
1230 g_return_val_if_fail (orig_alias, NULL);
1232 return lgl_template_alias_new (orig_alias->brand, orig_alias->part);
1237 * lgl_template_alias_free:
1238 * @alias: Alias to free.
1240 * This function frees all memory associated with given template alias structure.
1244 lgl_template_alias_free (lglTemplateAlias *alias)
1247 if ( alias != NULL )
1249 g_free (alias->brand);
1250 alias->brand = NULL;
1252 g_free (alias->part);
1261 * lgl_template_frame_dup:
1262 * @orig_frame: Frame to duplicate.
1264 * This function duplicates a template frame structure.
1266 * Returns: a newly allocated #lglTemplateFrame structure.
1270 lgl_template_frame_dup (const lglTemplateFrame *orig_frame)
1272 lglTemplateFrame *frame;
1274 lglTemplateLayout *layout;
1275 lglTemplateMarkup *markup;
1277 g_return_val_if_fail (orig_frame, NULL);
1279 switch (orig_frame->shape) {
1281 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
1283 lgl_template_frame_rect_new (orig_frame->all.id,
1287 orig_frame->rect.x_waste,
1288 orig_frame->rect.y_waste);
1291 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
1293 lgl_template_frame_ellipse_new (orig_frame->all.id,
1294 orig_frame->ellipse.w,
1295 orig_frame->ellipse.h,
1296 orig_frame->ellipse.waste);
1299 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
1301 lgl_template_frame_round_new (orig_frame->all.id,
1302 orig_frame->round.r,
1303 orig_frame->round.waste);
1306 case LGL_TEMPLATE_FRAME_SHAPE_CD:
1308 lgl_template_frame_cd_new (orig_frame->all.id,
1313 orig_frame->cd.waste);
1321 for ( p=orig_frame->all.layouts; p != NULL; p=p->next ) {
1323 layout = (lglTemplateLayout *)p->data;
1325 lgl_template_frame_add_layout (frame, lgl_template_layout_dup (layout));
1328 for ( p=orig_frame->all.markups; p != NULL; p=p->next ) {
1330 markup = (lglTemplateMarkup *)p->data;
1332 lgl_template_frame_add_markup (frame, lgl_template_markup_dup (markup));
1340 * lgl_template_frame_free:
1341 * @frame: Frame to free.
1343 * This function frees all memory associated with given template frame structure.
1347 lgl_template_frame_free (lglTemplateFrame *frame)
1350 lglTemplateLayout *layout;
1351 lglTemplateMarkup *markup;
1353 if ( frame != NULL ) {
1355 g_free (frame->all.id);
1356 frame->all.id = NULL;
1358 for ( p=frame->all.layouts; p != NULL; p=p->next ) {
1360 layout = (lglTemplateLayout *)p->data;
1362 lgl_template_layout_free (layout);
1365 g_list_free (frame->all.layouts);
1366 frame->all.layouts = NULL;
1368 for ( p=frame->all.markups; p != NULL; p=p->next ) {
1370 markup = (lglTemplateMarkup *)p->data;
1372 lgl_template_markup_free (markup);
1375 g_list_free (frame->all.markups);
1376 frame->all.markups = NULL;
1386 * lgl_template_layout_dup:
1387 * @orig_layout: Layout to duplicate.
1389 * This function duplicates a template layout structure.
1391 * Returns: a newly allocated #lglTemplateLayout structure.
1395 lgl_template_layout_dup (const lglTemplateLayout *orig_layout)
1397 lglTemplateLayout *layout;
1399 g_return_val_if_fail (orig_layout, NULL);
1401 layout = g_new0 (lglTemplateLayout, 1);
1404 *layout = *orig_layout;
1411 * lgl_template_layout_free:
1412 * @layout: Layout to free.
1414 * This function frees all memory associated with given template layout structure.
1418 lgl_template_layout_free (lglTemplateLayout *layout)
1425 * lgl_template_markup_dup:
1426 * @orig_markup: Markup to duplicate.
1428 * This function duplicates a template markup structure.
1430 * Returns: a newly allocated #lglTemplateMarkup structure.
1434 lgl_template_markup_dup (const lglTemplateMarkup *orig_markup)
1436 lglTemplateMarkup *markup;
1438 g_return_val_if_fail (orig_markup, NULL);
1440 markup = g_new0 (lglTemplateMarkup, 1);
1442 *markup = *orig_markup;
1449 * lgl_template_markup_free:
1450 * @markup: Markup to free.
1452 * This function frees all memory associated with given template markup structure.
1456 lgl_template_markup_free (lglTemplateMarkup *markup)
1463 compare_origins (gconstpointer a,
1467 const lglTemplateOrigin *a_origin = a, *b_origin = b;
1469 if ( a_origin->y < b_origin->y ) {
1471 } else if ( a_origin->y > b_origin->y ) {
1474 if ( a_origin->x < b_origin->x ) {
1476 } else if ( a_origin->x > b_origin->x ) {
1479 return 0; /* hopefully 2 labels won't have the same origin */
1486 * lgl_template_print:
1487 * @template: template
1489 * Print template details (for debugging purposes).
1493 lgl_template_print (const lglTemplate *template)
1496 lglTemplateAlias *alias;
1498 g_print ("---- %s( TEMPLATE=%p ) ----\n", __FUNCTION__, template);
1500 g_print("brand=\"%s\", part=\"%s\", description=\"%s\"\n",
1501 template->brand, template->part, template->description);
1503 g_print("paper_id=\"%s\", page_width=%g, page_height=%g\n",
1504 template->paper_id, template->page_width, template->page_height);
1506 for (p=template->aliases; p!=NULL; p=p->next)
1508 alias = (lglTemplateAlias *)p->data;
1509 g_print("Alias: brand=\"%s\", part=\"%s\"\n", alias->brand, alias->part);
1520 * Local Variables: -- emacs
1522 * c-basic-offset: 8 -- emacs
1523 * tab-width: 8 -- emacs
1524 * indent-tabs-mode: nil -- emacs