]> git.sur5r.net Git - glabels/commitdiff
Restructured template module to ultimately support multiple layouts and markups.
authorJim Evins <evins@snaught.com>
Sun, 15 Sep 2002 23:38:00 +0000 (23:38 +0000)
committerJim Evins <evins@snaught.com>
Sun, 15 Sep 2002 23:38:00 +0000 (23:38 +0000)
git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@117 f5e0f49d-192f-0410-a22d-a8d8700d0965

12 files changed:
glabels2/src/Makefile.am
glabels2/src/label.c
glabels2/src/prefs.h
glabels2/src/print.c
glabels2/src/template.c
glabels2/src/template.h
glabels2/src/view.c
glabels2/src/wdgt-media-select.c
glabels2/src/wdgt-mini-preview.c
glabels2/src/wdgt-print-copies.c
glabels2/src/wdgt-print-merge.c
glabels2/src/wdgt-rotate-label.c

index 8099522d68c6027637426a181db36c14e920fe95..29d1a1b2d4735b68ba87d6e49dcc3706c000f512 100644 (file)
@@ -221,6 +221,8 @@ glabels_batch_SOURCES =             \
        merge-text.h                    \
        text-node.c                     \
        text-node.h                     \
+       prefs.c                         \
+       prefs.h                         \
        util.c                          \
        util.h                          \
        debug.c                         \
index e6dd71344667bea1e9b2b72e25350ce10de7fdc4..cd654d46c2321946d84b578a65f649f669084a9c 100644 (file)
@@ -34,6 +34,7 @@
 #include "label-barcode.h"
 #include "template.h"
 #include "marshal.h"
+#include "util.h"
 
 #include "debug.h"
 
@@ -444,25 +445,29 @@ gl_label_get_size (glLabel * label,
                return;
        }
 
-        switch (template->style) {
+        switch (template->label.style) {
 
         case GL_TEMPLATE_STYLE_RECT:
                 if (!label->private->rotate_flag) {
-                        *w = template->label_width;
-                        *h = template->label_height;
+                        *w = template->label.rect.w;
+                        *h = template->label.rect.h;
                 } else {
-                        *w = template->label_height;
-                        *h = template->label_width;
+                        *w = template->label.rect.h;
+                        *h = template->label.rect.w;
                 }
                 break;
 
         case GL_TEMPLATE_STYLE_ROUND:
+                *w = *h = 2.0 * template->label.round.r;
+                break;
+
         case GL_TEMPLATE_STYLE_CD:
-                *w = *h = 2.0 * template->label_radius;
+                *w = *h = 2.0 * template->label.cd.r1;
                 break;
 
         default:
-                g_warning ("Unknown template label style %d", template->style);
+                g_warning ("Unknown template label style %d",
+                          template->label.style);
                *w = *h = 0;
                break;
         }
index 6a0967be0b8db77924b73735983b614bdf060150..27fcd96d9728603e39cf7079a138ee746f021207 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef __PREFS_H__
 #define __PREFS_H__
 
+#include <gtk/gtk.h>
 #include <libgnomeprint/gnome-font.h>
 
 typedef struct _glPreferences glPreferences;
index a3a697980106d5ec98264cd0ae99d3311cf11c4f..5e0a7a8d69eae0e3408d0c807b7fb266d600195e 100644 (file)
@@ -66,7 +66,7 @@ typedef struct _PrintInfo {
 static PrintInfo *print_info_new (GnomePrintMaster * master, glLabel * label);
 static void print_info_free (PrintInfo ** pi);
 
-static void print_label (PrintInfo * pi, glLabel * label, gint i,
+static void print_label (PrintInfo * pi, glLabel * label, gdouble x, gdouble y,
                         glMergeRecord * record, gboolean outline_flag,
                         gboolean reverse_flag);
 
@@ -110,11 +110,14 @@ gl_print_simple (GnomePrintMaster * master,
        PrintInfo *pi;
        gint i_sheet, i_label;
        gchar *page_str = NULL;
+       glTemplateOrigin *origins;
 
        gl_debug (DEBUG_PRINT, "START");
 
        pi = print_info_new (master, label);
 
+       origins = gl_template_get_origins (pi->template);
+
        for (i_sheet = 0; i_sheet < n_sheets; i_sheet++) {
 
                page_str = g_strdup_printf ("sheet %d", i_sheet + 1);
@@ -123,14 +126,17 @@ gl_print_simple (GnomePrintMaster * master,
 
                for (i_label = first - 1; i_label < last; i_label++) {
 
-                       print_label (pi, label, i_label, NULL,
-                                    outline_flag, reverse_flag);
+                       print_label (pi, label,
+                                    origins[i_label].x, origins[i_label].y,
+                                    NULL, outline_flag, reverse_flag);
 
                }
 
                gnome_print_showpage (pi->pc);
        }
 
+       g_free (origins);
+
        print_info_free (&pi);
 
        gl_debug (DEBUG_PRINT, "END");
@@ -153,12 +159,14 @@ gl_print_merge_collated (GnomePrintMaster * master,
        gchar *str = NULL;
        glMergeRecord *record;
        GList *p;
+       glTemplateOrigin *origins;
 
        gl_debug (DEBUG_PRINT, "START");
 
        pi = print_info_new (master, label);
 
-       n_labels_per_page = (pi->template->nx) * (pi->template->ny);
+       n_labels_per_page = gl_template_get_n_labels (pi->template);
+       origins = gl_template_get_origins (pi->template);
 
        i_sheet = 0;
        i_label = first - 1;
@@ -176,7 +184,10 @@ gl_print_merge_collated (GnomePrintMaster * master,
                                        g_free (str);
                                }
 
-                               print_label (pi, label, i_label, record,
+                               print_label (pi, label,
+                                            origins[i_label].x,
+                                            origins[i_label].y,
+                                            record,
                                             outline_flag, reverse_flag);
 
                                i_label = (i_label + 1) % n_labels_per_page;
@@ -191,6 +202,8 @@ gl_print_merge_collated (GnomePrintMaster * master,
                gnome_print_showpage (pi->pc);
        }
 
+       g_free (origins);
+
        print_info_free (&pi);
 
        gl_debug (DEBUG_PRINT, "END");
@@ -213,12 +226,14 @@ gl_print_merge_uncollated (GnomePrintMaster * master,
        gchar *str = NULL;
        glMergeRecord *record;
        GList *p;
+       glTemplateOrigin *origins;
 
        gl_debug (DEBUG_PRINT, "START");
 
        pi = print_info_new (master, label);
 
-       n_labels_per_page = (pi->template->nx) * (pi->template->ny);
+       n_labels_per_page = gl_template_get_n_labels (pi->template);
+       origins = gl_template_get_origins (pi->template);
 
        i_sheet = 0;
        i_label = first - 1;
@@ -238,7 +253,10 @@ gl_print_merge_uncollated (GnomePrintMaster * master,
                                        g_free (str);
                                }
 
-                               print_label (pi, label, i_label, record,
+                               print_label (pi, label,
+                                            origins[i_label].x,
+                                            origins[i_label].y,
+                                            record,
                                             outline_flag, reverse_flag);
 
                                i_label = (i_label + 1) % n_labels_per_page;
@@ -253,6 +271,8 @@ gl_print_merge_uncollated (GnomePrintMaster * master,
                gnome_print_showpage (pi->pc);
        }
 
+       g_free (origins);
+
        print_info_free (&pi);
 
        gl_debug (DEBUG_PRINT, "END");
@@ -277,7 +297,7 @@ gl_print_batch (GnomePrintMaster * master, glLabel * label,
        template = gl_label_get_template (label);
 
        if ( merge->type == GL_MERGE_NONE ) {
-               n_per_page = (template->nx)*(template->ny);
+               n_per_page = gl_template_get_n_labels(template);
 
                gl_print_simple (master, label, n_sheets, 1, n_per_page,
                                 outline_flag, reverse_flag);
@@ -400,15 +420,15 @@ print_info_free (PrintInfo ** pi)
 /* PRIVATE.  Print i'th label.                                               */
 /*---------------------------------------------------------------------------*/
 static void
-print_label (PrintInfo * pi,
-            glLabel * label,
-            gint i_label,
-            glMergeRecord * record,
-            gboolean outline_flag,
-            gboolean reverse_flag)
+print_label (PrintInfo     *pi,
+            glLabel       *label,
+            gdouble        x,
+            gdouble        y,
+            glMergeRecord *record,
+            gboolean       outline_flag,
+            gboolean       reverse_flag)
 {
        gdouble a[6];
-       gint ix, iy;
        gdouble width, height;
        glTemplate *template;
 
@@ -418,16 +438,11 @@ print_label (PrintInfo * pi,
 
        gl_label_get_size (label, &width, &height);
 
-       ix = i_label % (template->nx);
-       iy = ((template->ny) - 1) - (i_label / (template->nx));
-
        gnome_print_gsave (pi->pc);
 
        /* Transform coordinate system to be relative to upper corner */
        /* of the current label */
-       gnome_print_translate (pi->pc,
-                              ix * (template->dx) + template->x0,
-                              iy * (template->dy) + template->y0);
+       gnome_print_translate (pi->pc, x, y);
        if (gl_label_get_rotate_flag (label)) {
                gl_debug (DEBUG_PRINT, "Rotate flag set");
                gnome_print_rotate (pi->pc, 90.0);
@@ -884,11 +899,11 @@ draw_outline (PrintInfo * pi,
        gnome_print_setopacity (pi->pc, 1.0);
        gnome_print_setlinewidth (pi->pc, 0.25);
 
-       switch (template->style) {
+       switch (template->label.style) {
 
        case GL_TEMPLATE_STYLE_RECT:
                gl_label_get_size (label, &w, &h);
-               r = template->label_round;
+               r = template->label.rect.r;
                if (r == 0.0) {
                        /* simple rectangle */
                        create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
@@ -902,15 +917,15 @@ draw_outline (PrintInfo * pi,
 
        case GL_TEMPLATE_STYLE_ROUND:
                /* Round style */
-               r1 = template->label_radius;
+               r1 = template->label.round.r;
                create_ellipse_path (pi->pc, r1, r1, r1, r1);
                gnome_print_stroke (pi->pc);
                break;
 
        case GL_TEMPLATE_STYLE_CD:
                /* CD style, round label w/ concentric round hole */
-               r1 = template->label_radius;
-               r2 = template->label_hole;
+               r1 = template->label.cd.r1;
+               r2 = template->label.cd.r2;
                create_ellipse_path (pi->pc, r1, r1, r1, r1);
                gnome_print_stroke (pi->pc);
                create_ellipse_path (pi->pc, r1, r1, r2, r2);
@@ -942,11 +957,11 @@ clip_to_outline (PrintInfo * pi,
 
        template = gl_label_get_template (label);
 
-       switch (template->style) {
+       switch (template->label.style) {
 
        case GL_TEMPLATE_STYLE_RECT:
                gl_label_get_size (label, &w, &h);
-               r = template->label_round;
+               r = template->label.rect.r;
                if (r == 0.0) {
                        /* simple rectangle */
                        create_rectangle_path (pi->pc, 0.0, 0.0, w, h);
@@ -959,8 +974,13 @@ clip_to_outline (PrintInfo * pi,
                break;
 
        case GL_TEMPLATE_STYLE_ROUND:
+               r1 = template->label.round.r;
+               create_ellipse_path (pi->pc, r1, r1, r1, r1);
+               gnome_print_clip (pi->pc);
+               break;
+
        case GL_TEMPLATE_STYLE_CD:
-               r1 = template->label_radius;
+               r1 = template->label.cd.r1;
                create_ellipse_path (pi->pc, r1, r1, r1, r1);
                gnome_print_clip (pi->pc);
                break;
index ef568edb279755e8281cb00e159ac3ed77ffc768..9e9946197c822b99d4d7b388c25b7a9d0bf146e1 100644 (file)
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <libgnomeprint/gnome-print-paper.h>
 
+#include "prefs.h"
+#include "util.h"
 #include "template.h"
 
 #include "debug.h"
@@ -49,25 +51,54 @@ static GList *templates = NULL;
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static glTemplate *template_full_page (const gchar *page_size);
-
-static GList *read_templates (void);
-
-static gchar *get_home_data_dir (void);
-static GList *read_template_files_from_dir (GList * templates,
-                                           const gchar * dirname);
-static GList *read_templates_from_file (GList * templates,
-                                       gchar * xml_filename);
-
-static void xml_parse_label (xmlNodePtr label_node, glTemplate * template);
-static void xml_parse_layout (xmlNodePtr layout_node, glTemplate * template);
-static void xml_parse_markup (xmlNodePtr markup_node, glTemplate * template);
-static void xml_parse_alias (xmlNodePtr alias_node, glTemplate * template);
-
-static void xml_add_label (glTemplate *template, xmlNodePtr root, xmlNsPtr ns);
-static void xml_add_layout (glTemplate *template, xmlNodePtr root, xmlNsPtr ns);
-static void xml_add_markup_margin (glTemplate *template, xmlNodePtr root, xmlNsPtr ns);
-static void xml_add_alias (gchar *name, xmlNodePtr root, xmlNsPtr ns);
+static glTemplate *template_full_page           (const gchar *page_size);
+
+static GList      *read_templates               (void);
+
+static gchar      *get_home_data_dir            (void);
+static GList      *read_template_files_from_dir (GList *templates,
+                                                const gchar *dirname);
+static GList      *read_templates_from_file     (GList *templates,
+                                                gchar *xml_filename);
+
+static void        xml_parse_label              (xmlNodePtr label_node,
+                                                glTemplate *template);
+static void        xml_parse_layout             (xmlNodePtr layout_node,
+                                                glTemplate *template);
+static void        xml_parse_markup             (xmlNodePtr markup_node,
+                                                glTemplate *template);
+static void        xml_parse_alias              (xmlNodePtr alias_node,
+                                                glTemplate *template);
+
+static void        xml_add_label                (const glTemplate *template,
+                                                xmlNodePtr root,
+                                                xmlNsPtr ns);
+static void        xml_add_layout               (glTemplateLayout *layout,
+                                                xmlNodePtr root,
+                                                xmlNsPtr ns);
+static void        xml_add_markup_margin        (glTemplateMarkupMargin *margin,
+                                                xmlNodePtr root,
+                                                xmlNsPtr ns);
+static void        xml_add_alias                (gchar *name,
+                                                xmlNodePtr root,
+                                                xmlNsPtr ns);
+
+static gint compare_origins (gconstpointer a,
+                            gconstpointer b,
+                            gpointer user_data);
+
+static glTemplateLayout *layout_new  (gdouble nx,
+                                     gdouble ny,
+                                     gdouble x0,
+                                     gdouble y0,
+                                     gdouble dx,
+                                     gdouble dy);
+static glTemplateLayout *layout_dup  (glTemplateLayout *orig_layout);
+static void              layout_free (glTemplateLayout **layout);
+
+static glTemplateMarkup *markup_margin_new  (gdouble size);
+static glTemplateMarkup *markup_dup         (glTemplateMarkup *orig_markup);
+static void              markup_free        (glTemplateMarkup **markup);
 
 /*****************************************************************************/
 /* Initialize module.                                                        */
@@ -233,24 +264,40 @@ gl_template_from_name (const gchar * name)
 /*****************************************************************************/
 glTemplate *gl_template_dup (const glTemplate *orig_template)
 {
-       glTemplate *template;
-       GList *p;
+       glTemplate       *template;
+       GList            *p;
+       glTemplateLayout *layout;
+       glTemplateMarkup *markup;
 
        gl_debug (DEBUG_TEMPLATE, "START");
 
        template = g_new0 (glTemplate,1);
 
-       /* Shallow copy first */
-       *template = *orig_template;
-
-       /* Now the deep stuff */
        template->name = NULL;
        for ( p=orig_template->name; p != NULL; p=p->next ) {
                template->name = g_list_append (template->name,
                                                g_strdup (p->data));
        }
        template->description = g_strdup (orig_template->description);
-       template->page_size = g_strdup (orig_template->page_size);
+       template->page_size   = g_strdup (orig_template->page_size);
+
+       template->label       = orig_template->label;
+
+       template->label.any.layouts = NULL;
+       for ( p=orig_template->label.any.layouts; p != NULL; p=p->next ) {
+               layout = (glTemplateLayout *)p->data;
+               template->label.any.layouts =
+                       g_list_append (template->label.any.layouts,
+                                      layout_dup (layout));
+       }
+
+       template->label.any.markups = NULL;
+       for ( p=orig_template->label.any.markups; p != NULL; p=p->next ) {
+               markup = (glTemplateMarkup *)p->data;
+               template->label.any.markups =
+                       g_list_append (template->label.any.markups,
+                                      markup_dup (markup));
+       }
 
        gl_debug (DEBUG_TEMPLATE, "END");
        return template;
@@ -280,6 +327,18 @@ void gl_template_free (glTemplate **template)
                g_free ((*template)->page_size);
                (*template)->page_size = NULL;
 
+               for ( p=(*template)->label.any.layouts; p != NULL; p=p->next ) {
+                       layout_free ((glTemplateLayout **)&p->data);
+               }
+               g_list_free ((*template)->label.any.layouts);
+               (*template)->label.any.layouts = NULL;
+
+               for ( p=(*template)->label.any.markups; p != NULL; p=p->next ) {
+                       markup_free ((glTemplateMarkup **)&p->data);
+               }
+               g_list_free ((*template)->label.any.markups);
+               (*template)->label.any.markups = NULL;
+
                g_free (*template);
                *template = NULL;
 
@@ -304,21 +363,23 @@ template_full_page (const gchar *page_size)
 
        template = g_new0 (glTemplate, 1);
 
-       template->name        = g_list_append (template->name,
-                                              g_strdup_printf("*%s", page_size));
-       template->page_size   = g_strdup(page_size);
-       template->description = g_strdup(FULL_PAGE);
-
-       template->style = GL_TEMPLATE_STYLE_RECT;
+       template->name         = g_list_append (template->name,
+                                        g_strdup_printf("*%s", page_size));
+       template->page_size    = g_strdup(page_size);
+       template->description  = g_strdup(FULL_PAGE);
 
-       template->nx = 1;
-       template->ny = 1;
+       template->label.style  = GL_TEMPLATE_STYLE_RECT;
+       template->label.rect.w = paper->width;
+       template->label.rect.h = paper->height;
+       template->label.rect.r = 0.0;
 
-       template->label_width  = paper->width;
-       template->label_height = paper->height;
-       template->label_round  = 0.0;
+       template->label.any.layouts =
+               g_list_append (template->label.any.layouts,
+                              layout_new (1, 1, 0., 0., 0., 0.));
 
-       template->label_margin = 5.0;
+       template->label.any.markups =
+               g_list_append (template->label.any.markups,
+                              markup_margin_new (5.0));
 
        return template;
 }
@@ -525,34 +586,37 @@ xml_parse_label (xmlNodePtr label_node,
 
        style = xmlGetProp (label_node, "style");
        if (g_strcasecmp (style, "rectangle") == 0) {
-               template->style = GL_TEMPLATE_STYLE_RECT;
+               template->label.style = GL_TEMPLATE_STYLE_RECT;
        } else if (g_strcasecmp (style, "round") == 0) {
-               template->style = GL_TEMPLATE_STYLE_ROUND;
+               template->label.style = GL_TEMPLATE_STYLE_ROUND;
        } else if (g_strcasecmp (style, "cd") == 0) {
-               template->style = GL_TEMPLATE_STYLE_CD;
+               template->label.style = GL_TEMPLATE_STYLE_CD;
        } else {
+               template->label.style = GL_TEMPLATE_STYLE_RECT;
                g_warning ("Unknown label style in template");
        }
 
-       if (template->style == GL_TEMPLATE_STYLE_RECT) {
-               template->label_width =
+       switch (template->label.style) {
+       case GL_TEMPLATE_STYLE_RECT:
+               template->label.rect.w =
                    g_strtod (xmlGetProp (label_node, "width"), NULL);
-               template->label_height =
+               template->label.rect.h =
                    g_strtod (xmlGetProp (label_node, "height"), NULL);
-               template->label_round =
+               template->label.rect.r =
                    g_strtod (xmlGetProp (label_node, "round"), NULL);
-       } else if (template->style == GL_TEMPLATE_STYLE_ROUND) {
-               template->label_radius =
+               break;
+       case GL_TEMPLATE_STYLE_ROUND:
+               template->label.round.r =
                    g_strtod (xmlGetProp (label_node, "radius"), NULL);
-               template->label_width = 2.0 * template->label_radius;
-               template->label_height = 2.0 * template->label_radius;
-       } else if (template->style == GL_TEMPLATE_STYLE_CD) {
-               template->label_radius =
+               break;
+       case GL_TEMPLATE_STYLE_CD:
+               template->label.cd.r1 =
                    g_strtod (xmlGetProp (label_node, "radius"), NULL);
-               template->label_hole =
+               template->label.cd.r2 =
                    g_strtod (xmlGetProp (label_node, "hole"), NULL);
-               template->label_width = 2.0 * template->label_radius;
-               template->label_height = 2.0 * template->label_radius;
+               break;
+       default:
+               break;
        }
 
        for (node = label_node->xmlChildrenNode; node != NULL;
@@ -576,16 +640,18 @@ static void
 xml_parse_layout (xmlNodePtr layout_node,
                  glTemplate * template)
 {
+       gint nx, ny;
+       gdouble x0, y0, dx, dy;
        xmlNodePtr node;
 
        gl_debug (DEBUG_TEMPLATE, "START");
 
-       sscanf (xmlGetProp (layout_node, "nx"), "%d", &(template->nx));
-       sscanf (xmlGetProp (layout_node, "ny"), "%d", &(template->ny));
-       template->x0 = g_strtod (xmlGetProp (layout_node, "x0"), NULL);
-       template->y0 = g_strtod (xmlGetProp (layout_node, "y0"), NULL);
-       template->dx = g_strtod (xmlGetProp (layout_node, "dx"), NULL);
-       template->dy = g_strtod (xmlGetProp (layout_node, "dy"), NULL);
+       sscanf (xmlGetProp (layout_node, "nx"), "%d", &nx);
+       sscanf (xmlGetProp (layout_node, "ny"), "%d", &ny);
+       x0 = g_strtod (xmlGetProp (layout_node, "x0"), NULL);
+       y0 = g_strtod (xmlGetProp (layout_node, "y0"), NULL);
+       dx = g_strtod (xmlGetProp (layout_node, "dx"), NULL);
+       dy = g_strtod (xmlGetProp (layout_node, "dy"), NULL);
 
        for (node = layout_node->xmlChildrenNode; node != NULL;
             node = node->next) {
@@ -594,6 +660,10 @@ xml_parse_layout (xmlNodePtr layout_node,
                }
        }
 
+       template->label.any.layouts =
+               g_list_append (template->label.any.layouts,
+                              layout_new (nx, ny, x0, y0, dx, dy));
+
        gl_debug (DEBUG_TEMPLATE, "END");
 }
 
@@ -605,14 +675,17 @@ xml_parse_markup (xmlNodePtr markup_node,
                  glTemplate * template)
 {
        gchar *type;
+       gdouble size;
        xmlNodePtr node;
 
        gl_debug (DEBUG_TEMPLATE, "START");
 
        type = xmlGetProp (markup_node, "type");
        if (g_strcasecmp (type, "margin") == 0) {
-               template->label_margin =
-                       g_strtod (xmlGetProp (markup_node, "size"), NULL);
+               size = g_strtod (xmlGetProp (markup_node, "size"), NULL);
+               template->label.any.markups =
+                       g_list_append (template->label.any.markups,
+                                      markup_margin_new (size));
        }
 
        for (node = markup_node->xmlChildrenNode; node != NULL;
@@ -644,7 +717,7 @@ xml_parse_alias (xmlNodePtr alias_node,
 /* Add XML Template Node                                                    */
 /****************************************************************************/
 void
-gl_template_xml_add_sheet (glTemplate * template,
+gl_template_xml_add_sheet (const glTemplate * template,
                           xmlNodePtr root,
                           xmlNsPtr ns)
 {
@@ -672,12 +745,15 @@ gl_template_xml_add_sheet (glTemplate * template,
 /* PRIVATE.  Add XML Sheet->Label Node.                                     */
 /*--------------------------------------------------------------------------*/
 static void
-xml_add_label (glTemplate *template,
+xml_add_label (const glTemplate *template,
               xmlNodePtr root,
               xmlNsPtr ns)
 {
        xmlNodePtr node;
        gchar *string;
+       GList *p;
+       glTemplateMarkup *markup;
+       glTemplateLayout *layout;
 
        gl_debug (DEBUG_TEMPLATE, "START");
 
@@ -685,31 +761,31 @@ xml_add_label (glTemplate *template,
 
        xmlSetProp (node, "id", "0");
 
-       switch (template->style) {
+       switch (template->label.style) {
        case GL_TEMPLATE_STYLE_RECT:
                xmlSetProp (node, "style", "rectangle");
-               string = g_strdup_printf ("%g", template->label_width);
+               string = g_strdup_printf ("%g", template->label.rect.w);
                xmlSetProp (node, "width", string);
                g_free (string);
-               string = g_strdup_printf ("%g", template->label_height);
+               string = g_strdup_printf ("%g", template->label.rect.h);
                xmlSetProp (node, "height", string);
                g_free (string);
-               string = g_strdup_printf ("%g", template->label_round);
+               string = g_strdup_printf ("%g", template->label.rect.r);
                xmlSetProp (node, "round", string);
                g_free (string);
                break;
        case GL_TEMPLATE_STYLE_ROUND:
                xmlSetProp (node, "style", "round");
-               string = g_strdup_printf ("%g", template->label_radius);
+               string = g_strdup_printf ("%g", template->label.round.r);
                xmlSetProp (node, "radius", string);
                g_free (string);
                break;
        case GL_TEMPLATE_STYLE_CD:
                xmlSetProp (node, "style", "cd");
-               string = g_strdup_printf ("%g", template->label_radius);
+               string = g_strdup_printf ("%g", template->label.cd.r1);
                xmlSetProp (node, "radius", string);
                g_free (string);
-               string = g_strdup_printf ("%g", template->label_hole);
+               string = g_strdup_printf ("%g", template->label.cd.r2);
                xmlSetProp (node, "hole", string);
                g_free (string);
                break;
@@ -718,8 +794,23 @@ xml_add_label (glTemplate *template,
                break;
        }
 
-       xml_add_markup_margin (template, node, ns);
-       xml_add_layout (template, node, ns);
+       for ( p=template->label.any.markups; p != NULL; p=p->next ) {
+               markup = (glTemplateMarkup *)p->data;
+               switch (markup->type) {
+               case GL_TEMPLATE_MARKUP_MARGIN:
+                       xml_add_markup_margin ((glTemplateMarkupMargin *)markup,
+                                              node, ns);
+                       break;
+               default:
+                       g_warning ("Unknown markup type");
+                       break;
+               }
+       }
+
+       for ( p=template->label.any.layouts; p != NULL; p=p->next ) {
+               layout = (glTemplateLayout *)p->data;
+               xml_add_layout (layout, node, ns);
+       }
 
        gl_debug (DEBUG_TEMPLATE, "END");
 }
@@ -728,7 +819,7 @@ xml_add_label (glTemplate *template,
 /* PRIVATE.  Add XML Sheet->Label->Layout Node.                             */
 /*--------------------------------------------------------------------------*/
 static void
-xml_add_layout (glTemplate *template,
+xml_add_layout (glTemplateLayout *layout,
                xmlNodePtr root,
                xmlNsPtr ns)
 {
@@ -738,22 +829,22 @@ xml_add_layout (glTemplate *template,
        gl_debug (DEBUG_TEMPLATE, "START");
 
        node = xmlNewChild(root, ns, "Layout", NULL);
-       string = g_strdup_printf ("%d", template->nx);
+       string = g_strdup_printf ("%d", layout->nx);
        xmlSetProp (node, "nx", string);
        g_free (string);
-       string = g_strdup_printf ("%d", template->ny);
+       string = g_strdup_printf ("%d", layout->ny);
        xmlSetProp (node, "ny", string);
        g_free (string);
-       string = g_strdup_printf ("%g", template->x0);
+       string = g_strdup_printf ("%g", layout->x0);
        xmlSetProp (node, "x0", string);
        g_free (string);
-       string = g_strdup_printf ("%g", template->y0);
+       string = g_strdup_printf ("%g", layout->y0);
        xmlSetProp (node, "y0", string);
        g_free (string);
-       string = g_strdup_printf ("%g", template->dx);
+       string = g_strdup_printf ("%g", layout->dx);
        xmlSetProp (node, "dx", string);
        g_free (string);
-       string = g_strdup_printf ("%g", template->dy);
+       string = g_strdup_printf ("%g", layout->dy);
        xmlSetProp (node, "dy", string);
        g_free (string);
 
@@ -764,7 +855,7 @@ xml_add_layout (glTemplate *template,
 /* PRIVATE.  Add XML Sheet->Label->Markup Node.                             */
 /*--------------------------------------------------------------------------*/
 static void
-xml_add_markup_margin (glTemplate *template,
+xml_add_markup_margin (glTemplateMarkupMargin *margin,
                       xmlNodePtr root,
                       xmlNsPtr ns)
 {
@@ -776,7 +867,7 @@ xml_add_markup_margin (glTemplate *template,
        node = xmlNewChild(root, ns, "Markup", NULL);
        xmlSetProp (node, "type", "margin");
 
-       string = g_strdup_printf ("%g", template->label_margin);
+       string = g_strdup_printf ("%g", margin->size);
        xmlSetProp (node, "size", string);
        g_free (string);
 
@@ -801,3 +892,291 @@ xml_add_alias (gchar *name,
        gl_debug (DEBUG_TEMPLATE, "END");
 }
 
+/****************************************************************************/
+/* Get label size description.                                              */ 
+/****************************************************************************/
+gchar *
+gl_template_get_label_size_desc (const glTemplate *template)
+{
+       glPrefsUnits units;
+       const gchar *units_string;
+       gdouble units_per_point;
+       gchar *string = NULL;
+
+       units           = gl_prefs_get_units ();
+       units_string    = gl_prefs_get_units_string ();
+       units_per_point = gl_prefs_get_units_per_point ();
+
+       switch (template->label.style) {
+       case GL_TEMPLATE_STYLE_RECT:
+               if ( units == GL_PREFS_UNITS_INCHES ) {
+                       gchar *xstr, *ystr;
+
+                       xstr = gl_util_fraction (template->label.rect.w * units_per_point);
+                       ystr = gl_util_fraction (template->label.rect.h * units_per_point);
+                       string = g_strdup_printf (_("%s x %s %s"),
+                                                 xstr, ystr, units_string);
+                       g_free (xstr);
+                       g_free (ystr);
+               } else {
+                       string = g_strdup_printf (_("%.5g x %.5g %s"),
+                                                 template->label.rect.w * units_per_point,
+                                                 template->label.rect.h * units_per_point,
+                                                 units_string);
+               }
+               break;
+       case GL_TEMPLATE_STYLE_ROUND:
+               if ( units == GL_PREFS_UNITS_INCHES ) {
+                       gchar *dstr;
+
+                       dstr = gl_util_fraction (2.0 * template->label.round.r * units_per_point);
+                       string = g_strdup_printf (_("%s %s diameter"),
+                                                 dstr, units_string);
+                       g_free (dstr);
+               } else {
+                       string = g_strdup_printf (_("%.5g %s diameter"),
+                                                 2.0 * template->label.round.r * units_per_point,
+                                                 units_string);
+               }
+               break;
+       case GL_TEMPLATE_STYLE_CD:
+               if ( units == GL_PREFS_UNITS_INCHES ) {
+                       gchar *dstr;
+
+                       dstr = gl_util_fraction (2.0 * template->label.cd.r1 * units_per_point);
+                       string = g_strdup_printf (_("%s %s diameter"),
+                                                 dstr, units_string);
+                       g_free (dstr);
+               } else {
+                       string = g_strdup_printf (_("%.5g %s diameter"),
+                                                 2.0 * template->label.cd.r1 * units_per_point,
+                                                 units_string);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return string;
+}
+
+/****************************************************************************/
+/* Get raw label size (width and height).                                   */
+/****************************************************************************/
+void
+gl_template_get_label_size (const glTemplate *template,
+                           gdouble          *w,
+                           gdouble          *h)
+{
+       switch (template->label.style) {
+       case GL_TEMPLATE_STYLE_RECT:
+               *w = template->label.rect.w;
+               *h = template->label.rect.h;
+               break;
+       case GL_TEMPLATE_STYLE_ROUND:
+               *w = 2.0 * template->label.round.r;
+               *h = 2.0 * template->label.round.r;
+               break;
+       case GL_TEMPLATE_STYLE_CD:
+               *w = 2.0 * template->label.cd.r1;
+               *h = 2.0 * template->label.cd.r1;
+               break;
+       default:
+               *w = 0.0;
+               *h = 0.0;
+               break;
+       }
+}
+
+/****************************************************************************/
+/* Get total number of labels per sheet.                                    */
+/****************************************************************************/
+gint
+gl_template_get_n_labels (const glTemplate *template)
+{
+       gint n_labels = 0;
+       GList *p;
+       glTemplateLayout *layout;
+
+       for ( p=template->label.any.layouts; p != NULL; p=p->next ) {
+               layout = (glTemplateLayout *)p->data;
+
+               n_labels += layout->nx * layout->ny;
+       }
+
+       return n_labels;
+}
+
+/****************************************************************************/
+/* Get array of origins of individual labels.                               */
+/****************************************************************************/
+glTemplateOrigin *
+gl_template_get_origins (const glTemplate *template)
+{
+       gint i_label, n_labels, ix, iy;
+       glTemplateOrigin *origins;
+       GList *p;
+       glTemplateLayout *layout;
+
+       n_labels = gl_template_get_n_labels (template);
+       origins = g_new0 (glTemplateOrigin, n_labels);
+
+       i_label = 0;
+       for ( p=template->label.any.layouts; p != NULL; p=p->next ) {
+               layout = (glTemplateLayout *)p->data;
+
+               for (iy = 0; iy < layout->ny; iy++) {
+                       for (ix = 0; ix < layout->nx; ix++, i_label++) {
+                               origins[i_label].x = ix*layout->dx + layout->x0;
+                               origins[i_label].y = iy*layout->dy + layout->y0;
+                       }
+               }
+       }
+
+       g_qsort_with_data (origins, n_labels, sizeof(glTemplateOrigin),
+                          compare_origins, NULL);
+
+       return origins;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Sort origins comparison function, first by y then by x.        */
+/*--------------------------------------------------------------------------*/
+static gint
+compare_origins (gconstpointer a,
+                gconstpointer b,
+                gpointer user_data)
+{
+       const glTemplateOrigin *a_origin = a, *b_origin = b;
+
+       if ( a_origin->y < b_origin->y ) {
+               return -1;
+       } else if ( a_origin->y > b_origin->y ) {
+               return +1;
+       } else {
+               if ( a_origin->x < b_origin->x ) {
+                       return -1;
+               } else if ( a_origin->x > b_origin->x ) {
+                       return +1;
+               } else {
+                       return 0; /* hopefully 2 labels won't have the same origin */
+               }
+       }
+}
+
+/****************************************************************************/
+/* Get a description of the layout and number of labels.                    */
+/****************************************************************************/
+gchar *
+gl_template_get_layout_desc (const glTemplate *template)
+{
+       gint n_labels;
+       glTemplateLayout *layout;
+       gchar *string;
+
+       n_labels = gl_template_get_n_labels (template);
+
+       if ( template->label.any.layouts->next == NULL ) {
+               layout = (glTemplateLayout *)template->label.any.layouts->data;
+               string = g_strdup_printf (_("%d x %d  (%d per sheet)"),
+                                         layout->nx, layout->ny,
+                                         n_labels);
+       } else {
+               string = g_strdup_printf (_("%d per sheet"),
+                                         n_labels);
+       }
+
+       return string;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Create new layout structure.                                   */
+/*--------------------------------------------------------------------------*/
+static glTemplateLayout *
+layout_new (gdouble nx,
+           gdouble ny,
+           gdouble x0,
+           gdouble y0,
+           gdouble dx,
+           gdouble dy)
+{
+       glTemplateLayout *layout;
+
+       layout = g_new0 (glTemplateLayout, 1);
+
+       layout->nx = nx;
+       layout->ny = ny;
+       layout->x0 = x0;
+       layout->y0 = y0;
+       layout->dx = dx;
+       layout->dy = dy;
+
+       return layout;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Duplicate layout structure.                                    */
+/*--------------------------------------------------------------------------*/
+static glTemplateLayout *
+layout_dup (glTemplateLayout *orig_layout)
+{
+       glTemplateLayout *layout;
+
+       layout = g_new0 (glTemplateLayout, 1);
+
+       /* copy contents */
+       *layout = *orig_layout;
+
+       return layout;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Free layout structure.                                         */
+/*--------------------------------------------------------------------------*/
+static void
+layout_free (glTemplateLayout **layout)
+{
+       g_free (*layout);
+       *layout = NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Create new margin markup structure.                            */
+/*--------------------------------------------------------------------------*/
+static glTemplateMarkup *
+markup_margin_new (gdouble size)
+{
+       glTemplateMarkup *markup;
+
+       markup = g_new0 (glTemplateMarkup, 1);
+
+       markup->type        = GL_TEMPLATE_MARKUP_MARGIN;
+       markup->margin.size = size;
+
+       return markup;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Duplicate markup structure.                                    */
+/*--------------------------------------------------------------------------*/
+static glTemplateMarkup *
+markup_dup (glTemplateMarkup *orig_markup)
+{
+       glTemplateMarkup *markup;
+
+       markup = g_new0 (glTemplateMarkup, 1);
+
+       *markup = *orig_markup;
+
+       return markup;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Free markup structure.                                         */
+/*--------------------------------------------------------------------------*/
+static void
+markup_free (glTemplateMarkup **markup)
+{
+       g_free (*markup);
+       *markup = NULL;
+}
index 4ec025f9823a8971a4424a1c3ff2f9daf8fdf589..3b0a5fa2ef74393d2b9fdbc7e6efa9df019035f0 100644 (file)
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 
+
+/*
+ *   Template Label Structure
+ */
 typedef enum {
        GL_TEMPLATE_STYLE_RECT,
        GL_TEMPLATE_STYLE_ROUND,
        GL_TEMPLATE_STYLE_CD,
-} glTemplateStyle;
+} glTemplateLabelStyle;
+
+typedef struct {
+       glTemplateLabelStyle  style;
+       GList                *layouts;  /* List of glTemplateLayouts */
+       GList                *markups;  /* List of glTemplateMarkups */
+} glTemplateLabelParent;
+
+typedef struct {
+       glTemplateLabelParent parent;
+
+       gdouble               w, h, r;  /* Dimensions */
+} glTemplateLabelRect;
+
+typedef struct {
+       glTemplateLabelParent parent;
+
+       gdouble               r;        /* Dimensions */
+} glTemplateLabelRound;
 
 typedef struct {
-       GList *name;
-       gchar *description;
-       gchar *page_size;
-       glTemplateStyle style;
+       glTemplateLabelParent parent;
 
-       /* Suggested margin */
-       gdouble label_margin;
+       gdouble               r1, r2;   /* Dimensions */
+} glTemplateLabelCD;
+
+typedef union {
+       glTemplateLabelStyle  style;
+       glTemplateLabelParent any;
+       glTemplateLabelRect   rect;
+       glTemplateLabelRound  round;
+       glTemplateLabelCD     cd;
+} glTemplateLabel;
+
+
+/*
+ *   Label Markup
+ */
+typedef enum {
+       GL_TEMPLATE_MARKUP_MARGIN,
+} glTemplateMarkupType;
+
+typedef struct {
+       /* NOTE: These fields are common to all union members. */
+       glTemplateMarkupType   type;
+} glTemplateMarkupParent;
+
+typedef struct {
+       glTemplateMarkupParent parent;
 
-       /* Simple and rounded rectangles. */
-       gdouble label_width, label_height, label_round;
+       gdouble                size;
+} glTemplateMarkupMargin;
 
-       /* CD/DVD labels */
-       gdouble label_radius, label_hole;
+typedef union {
+       glTemplateMarkupType   type;
+       glTemplateMarkupParent any;
+       glTemplateMarkupMargin margin;
+} glTemplateMarkup;
 
-       /* Layout */
+
+/*
+ *   Label layout
+ */
+typedef struct {
        gint nx, ny;
        gdouble x0, y0, dx, dy;
+} glTemplateLayout;
+
+
+/*
+ *   Template
+ */
+typedef struct {
+       GList               *name;
+       gchar               *description;
+       gchar               *page_size;
+
+       glTemplateLabel      label;
+
 } glTemplate;
 
-extern void       gl_template_init                (void);
 
-extern GList      *gl_template_get_page_size_list (void);
-extern void       gl_template_free_page_size_list (GList **sizes);
+/*
+ *  Origin coordinates
+ */
+typedef struct {
+       gdouble x, y;
+} glTemplateOrigin;
+
+
+extern void                 gl_template_init                (void);
+
+extern GList               *gl_template_get_page_size_list  (void);
+extern void                 gl_template_free_page_size_list (GList **sizes);
+
+extern GList               *gl_template_get_name_list       (const gchar *page_size);
+extern void                 gl_template_free_name_list      (GList **names);
+
+extern glTemplate          *gl_template_from_name           (const gchar *name);
+
+extern glTemplate          *gl_template_dup                 (const glTemplate *orig);
+extern void                 gl_template_free                (glTemplate **template);
 
-extern GList      *gl_template_get_name_list      (const gchar *page_size);
-extern void       gl_template_free_name_list      (GList **names);
+extern glTemplate          *gl_template_xml_parse_sheet     (xmlNodePtr sheet_node);
 
-extern glTemplate *gl_template_from_name          (const gchar * name);
+extern void                 gl_template_xml_add_sheet       (const glTemplate *template,
+                                                            xmlNodePtr root,
+                                                            xmlNsPtr ns);
 
-extern glTemplate *gl_template_dup                (const glTemplate *orig);
-extern void       gl_template_free                (glTemplate **template);
+extern gchar               *gl_template_get_label_size_desc (const glTemplate *template);
+extern void                 gl_template_get_label_size      (const glTemplate *template,
+                                                            gdouble *w,
+                                                            gdouble *h);
 
-extern glTemplate *gl_template_xml_parse_sheet    (xmlNodePtr sheet_node);
+extern gint                 gl_template_get_n_labels        (const glTemplate *template);
+extern glTemplateOrigin    *gl_template_get_origins         (const glTemplate *template);
+extern gchar               *gl_template_get_layout_desc     (const glTemplate *template);
 
-extern void       gl_template_xml_add_sheet       (glTemplate * template,
-                                                  xmlNodePtr root,
-                                                  xmlNsPtr ns);
 #endif
index 916114eed74315b9f270316a7a993aef8362384d..9f3e36af460cc868d6a89b0cd3f4536fb9ac0596 100644 (file)
@@ -81,65 +81,80 @@ static gdouble scales[] = {
 /* Local function prototypes                 */
 /*===========================================*/
 
-static void       gl_view_class_init          (glViewClass *class);
-static void       gl_view_init                (glView *view);
-static void       gl_view_finalize            (GObject *object);
-
-static void       gl_view_construct           (glView *view);
-static GtkWidget *gl_view_construct_canvas    (glView *view);
-static void       gl_view_construct_selection (glView *view);
-
-static gdouble    get_apropriate_scale        (gdouble w, gdouble h);
-
-static void       draw_rect_bg_fg             (glView *view);
-static void       draw_rounded_rect_bg_fg     (glView *view);
-static void       draw_round_bg_fg            (glView *view);
-static void       draw_cd_bg_fg               (glView *view);
-
-static void       select_object_real          (glView *view,
-                                              glViewObject *view_object);
-static void       unselect_object_real        (glView *view,
-                                              glViewObject *view_object);
-
-static gboolean   object_at                   (glView *view,
-                                              gdouble x, gdouble y);
-static gboolean   is_object_selected          (glView *view,
-                                              glViewObject *view_object);
-
-static void       move_selection              (glView *view,
-                                              gdouble dx, gdouble dy);
-
-static int        canvas_event                (GnomeCanvas *canvas,
-                                              GdkEvent    *event,
-                                              glView      *view);
-static int        canvas_event_arrow_mode     (GnomeCanvas *canvas,
-                                              GdkEvent    *event,
-                                              glView      *view);
-
-static int        item_event_arrow_mode      (GnomeCanvasItem *item,
-                                             GdkEvent        *event,
-                                             glViewObject    *view_object);
-
-static GtkWidget *new_selection_menu         (glView *view);
-
-static void       popup_selection_menu       (glView       *view,
-                                             glViewObject *view_object,
-                                             GdkEvent     *event);
-
-static void       selection_clear_cb         (GtkWidget         *widget,
-                                             GdkEventSelection *event,
-                                             gpointer          data);
-
-static void       selection_get_cb           (GtkWidget         *widget,
-                                             GtkSelectionData  *selection_data,
-                                             guint             info,
-                                             guint             time,
-                                             gpointer          data);
-
-static void       selection_received_cb      (GtkWidget         *widget,
-                                             GtkSelectionData  *selection_data,
-                                             guint             time,
-                                             gpointer          data);
+static void       gl_view_class_init              (glViewClass *class);
+static void       gl_view_init                    (glView *view);
+static void       gl_view_finalize                (GObject *object);
+
+static void       gl_view_construct               (glView *view);
+static GtkWidget *gl_view_construct_canvas        (glView *view);
+static void       gl_view_construct_selection     (glView *view);
+
+static gdouble    get_apropriate_scale            (gdouble w, gdouble h);
+
+static void       draw_bg_fg                      (glView *view);
+static void       draw_bg_fg_rect                 (glView *view);
+static void       draw_bg_fg_rounded_rect         (glView *view);
+static void       draw_bg_fg_round                (glView *view);
+static void       draw_bg_fg_cd                   (glView *view);
+
+static void       draw_markup                     (glView *view);
+
+static void       draw_markup_margin              (glView *view,
+                                                  glTemplateMarkupMargin *margin);
+static void       draw_markup_margin_rect         (glView *view,
+                                                  glTemplateMarkupMargin *margin);
+static void       draw_markup_margin_rounded_rect (glView *view,
+                                                  glTemplateMarkupMargin *margin);
+static void       draw_markup_margin_round        (glView *view,
+                                                  glTemplateMarkupMargin *margin);
+static void       draw_markup_margin_cd           (glView *view,
+                                                  glTemplateMarkupMargin *margin);
+
+
+static void       select_object_real              (glView *view,
+                                                  glViewObject *view_object);
+static void       unselect_object_real            (glView *view,
+                                                  glViewObject *view_object);
+
+static gboolean   object_at                       (glView *view,
+                                                  gdouble x, gdouble y);
+static gboolean   is_object_selected              (glView *view,
+                                                  glViewObject *view_object);
+
+static void       move_selection                  (glView *view,
+                                                  gdouble dx, gdouble dy);
+
+static int        canvas_event                    (GnomeCanvas *canvas,
+                                                  GdkEvent    *event,
+                                                  glView      *view);
+static int        canvas_event_arrow_mode         (GnomeCanvas *canvas,
+                                                  GdkEvent    *event,
+                                                  glView      *view);
+
+static int        item_event_arrow_mode          (GnomeCanvasItem *item,
+                                                 GdkEvent        *event,
+                                                 glViewObject    *view_object);
+
+static GtkWidget *new_selection_menu             (glView *view);
+
+static void       popup_selection_menu           (glView       *view,
+                                                 glViewObject *view_object,
+                                                 GdkEvent     *event);
+
+static void       selection_clear_cb             (GtkWidget         *widget,
+                                                 GdkEventSelection *event,
+                                                 gpointer          data);
+
+static void       selection_get_cb               (GtkWidget         *widget,
+                                                 GtkSelectionData  *selection_data,
+                                                 guint             info,
+                                                 guint             time,
+                                                 gpointer          data);
+
+static void       selection_received_cb          (GtkWidget         *widget,
+                                                 GtkSelectionData  *selection_data,
+                                                 guint             time,
+                                                 gpointer          data);
 \f
 /****************************************************************************/
 /* Boilerplate Object stuff.                                                */
@@ -281,7 +296,6 @@ gl_view_construct_canvas (glView *view)
        gdouble scale;
        glLabel *label = view->label;
        gdouble label_width, label_height;
-       glTemplate *label_template;
        GList *p_obj;
        glLabelObject *object;
        glViewObject *view_object;
@@ -298,7 +312,6 @@ gl_view_construct_canvas (glView *view)
        gl_label_get_size (label, &label_width, &label_height);
        gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
                  label_width, label_height);
-       label_template = gl_label_get_template (label);
 
        scale = get_apropriate_scale (label_width, label_height);
        gl_debug (DEBUG_VIEW, "scale =%lf", scale);
@@ -317,30 +330,7 @@ gl_view_construct_canvas (glView *view)
                                        0.0, 0.0, label_width, label_height);
 
        /* Draw background shape of label/card */
-       switch (label_template->style) {
-
-       case GL_TEMPLATE_STYLE_RECT:
-               if (label_template->label_round == 0.0) {
-                       /* Square corners. */
-                       draw_rect_bg_fg (view);
-               } else {
-                       /* Rounded corners. */
-                       draw_rounded_rect_bg_fg (view);
-               }
-               break;
-
-       case GL_TEMPLATE_STYLE_ROUND:
-               draw_round_bg_fg (view);
-               break;
-
-       case GL_TEMPLATE_STYLE_CD:
-               draw_cd_bg_fg (view);
-               break;
-
-       default:
-               g_warning ("Unknown template label style");
-               break;
-       }
+       draw_bg_fg (view);
        gl_debug (DEBUG_VIEW, "n_bg_items = %d, n_fg_items = %d",
                  view->n_bg_items, view->n_fg_items);
 
@@ -445,15 +435,58 @@ get_apropriate_scale (gdouble w, gdouble h)
 }
 
 /*---------------------------------------------------------------------------*/
-/* PRIVATE.  Draw simple recangular background.                              */
+/* PRIVATE.  Draw background and foreground outlines.                        */
 /*---------------------------------------------------------------------------*/
 static void
-draw_rect_bg_fg (glView *view)
+draw_bg_fg (glView *view)
 {
-       glLabel *label = view->label;
+       glLabel    *label;
        glTemplate *template;
-       gdouble w, h, margin;
-       GnomeCanvasItem *item;
+
+       view->n_bg_items = 0;
+       view->bg_item_list = NULL;
+       view->n_fg_items = 0;
+       view->fg_item_list = NULL;
+
+       label = view->label;
+       template = gl_label_get_template (label);
+
+       switch (template->label.style) {
+
+       case GL_TEMPLATE_STYLE_RECT:
+               if (template->label.rect.r == 0.0) {
+                       /* Square corners. */
+                       draw_bg_fg_rect (view);
+               } else {
+                       /* Rounded corners. */
+                       draw_bg_fg_rounded_rect (view);
+               }
+               break;
+
+       case GL_TEMPLATE_STYLE_ROUND:
+               draw_bg_fg_round (view);
+               break;
+
+       case GL_TEMPLATE_STYLE_CD:
+               draw_bg_fg_cd (view);
+               break;
+
+       default:
+               g_warning ("Unknown template label style");
+               break;
+       }
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw simple recangular background.                              */
+/*---------------------------------------------------------------------------*/
+static void
+draw_bg_fg_rect (glView *view)
+{
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           w, h;
+       GnomeCanvasItem  *item;
        GnomeCanvasGroup *group;
 
        gl_debug (DEBUG_VIEW, "START");
@@ -463,15 +496,10 @@ draw_rect_bg_fg (glView *view)
 
        gl_label_get_size (label, &w, &h);
        template = gl_label_get_template (label);
-       margin = template->label_margin;
-
-       view->n_bg_items = 0;
-       view->bg_item_list = NULL;
-       view->n_fg_items = 0;
-       view->fg_item_list = NULL;
 
        group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
 
+       /* Background */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_rect_get_type (),
                                      "x1", 0.0,
@@ -483,19 +511,10 @@ draw_rect_bg_fg (glView *view)
        view->n_bg_items++;
        view->bg_item_list = g_list_append (view->bg_item_list, item);
 
-       /* Bounding box @ margin */
-       gnome_canvas_item_new (group,
-                              gnome_canvas_rect_get_type (),
-                              "x1", margin,
-                              "y1", margin,
-                              "x2", w - margin,
-                              "y2", h - margin,
-                              "width_pixels", 1,
-                              "outline_color", "light blue",
-                              NULL);
-       view->n_bg_items++;
-       view->bg_item_list = g_list_append (view->bg_item_list, item);
+       /* Markup */
+       draw_markup (view);
 
+       /* Foreground */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_rect_get_type (),
                                      "x1", 0.0,
@@ -515,15 +534,15 @@ draw_rect_bg_fg (glView *view)
 /* PRIVATE.  Draw rounded recangular background.                             */
 /*---------------------------------------------------------------------------*/
 static void
-draw_rounded_rect_bg_fg (glView *view)
+draw_bg_fg_rounded_rect (glView *view)
 {
-       glLabel *label = view->label;
-       GnomeCanvasPoints *label_points, *margin_points;
-       gint i_coords, i_theta;
-       glTemplate *template;
-       gdouble r, w, h, m;
-       GnomeCanvasItem *item;
-       GnomeCanvasGroup *group;
+       glLabel           *label = view->label;
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       glTemplate        *template;
+       gdouble            r, w, h;
+       GnomeCanvasItem   *item;
+       GnomeCanvasGroup  *group;
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -532,122 +551,60 @@ draw_rounded_rect_bg_fg (glView *view)
 
        group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
 
-       view->n_bg_items = 0;
-       view->bg_item_list = NULL;
-       view->n_fg_items = 0;
-       view->fg_item_list = NULL;
-
        gl_label_get_size (label, &w, &h);
        template = gl_label_get_template (label);
-       r = template->label_round;
-       m = template->label_margin;
+       r = template->label.rect.r;
 
-       label_points = gnome_canvas_points_new (4 * (1 + 90 / 5));
+       points = gnome_canvas_points_new (4 * (1 + 90 / 5));
        i_coords = 0;
        for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    r - r * sin (i_theta * M_PI / 180.0);
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    r - r * cos (i_theta * M_PI / 180.0);
        }
        for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    r - r * cos (i_theta * M_PI / 180.0);
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    (h - r) + r * sin (i_theta * M_PI / 180.0);
        }
        for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    (w - r) + r * sin (i_theta * M_PI / 180.0);
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    (h - r) + r * cos (i_theta * M_PI / 180.0);
        }
        for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    (w - r) + r * cos (i_theta * M_PI / 180.0);
-               label_points->coords[i_coords++] =
+               points->coords[i_coords++] =
                    r - r * sin (i_theta * M_PI / 180.0);
        }
 
-       /* Basic background */
+       /* Background */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_polygon_get_type (),
-                                     "points", label_points,
+                                     "points", points,
                                      "fill_color", "white",
                                      NULL);
        view->n_bg_items++;
        view->bg_item_list = g_list_append (view->bg_item_list, item);
 
-       /* Margin outline */
-       if (template->label_margin >= template->label_round) {
-               /* simple rectangle */
-               item = gnome_canvas_item_new (group,
-                                             gnome_canvas_rect_get_type (),
-                                             "x1", m,
-                                             "y1", m,
-                                             "x2", w - m,
-                                             "y2", h - m,
-                                             "width_pixels", 1,
-                                             "outline_color", "light blue",
-                                             NULL);
-               view->n_bg_items++;
-               view->bg_item_list =
-                   g_list_append (view->bg_item_list, item);
-       } else {
-               r = r - m;
-               w = w - 2 * m;
-               h = h - 2 * m;
-
-               /* rectangle with rounded corners */
-               margin_points = gnome_canvas_points_new (4 * (1 + 90 / 5));
-               i_coords = 0;
-               for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-                       margin_points->coords[i_coords++] =
-                           m + r - r * sin (i_theta * M_PI / 180.0);
-                       margin_points->coords[i_coords++] =
-                           m + r - r * cos (i_theta * M_PI / 180.0);
-               }
-               for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-                       margin_points->coords[i_coords++] =
-                           m + r - r * cos (i_theta * M_PI / 180.0);
-                       margin_points->coords[i_coords++] =
-                           m + (h - r) + r * sin (i_theta * M_PI / 180.0);
-               }
-               for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-                       margin_points->coords[i_coords++] =
-                           m + (w - r) + r * sin (i_theta * M_PI / 180.0);
-                       margin_points->coords[i_coords++] =
-                           m + (h - r) + r * cos (i_theta * M_PI / 180.0);
-               }
-               for (i_theta = 0; i_theta <= 90; i_theta += 5) {
-                       margin_points->coords[i_coords++] =
-                           m + (w - r) + r * cos (i_theta * M_PI / 180.0);
-                       margin_points->coords[i_coords++] =
-                           m + r - r * sin (i_theta * M_PI / 180.0);
-               }
-               item = gnome_canvas_item_new (group,
-                                             gnome_canvas_polygon_get_type (),
-                                             "points", margin_points,
-                                             "width_pixels", 1,
-                                             "outline_color", "light blue",
-                                             NULL);
-               gnome_canvas_points_free (margin_points);
-               view->n_bg_items++;
-               view->bg_item_list =
-                   g_list_append (view->bg_item_list, item);
-       }
+       /* Markup */
+       draw_markup (view);
 
-       /* Foreground outline */
+       /* Foreground */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_polygon_get_type (),
-                                     "points", label_points,
+                                     "points", points,
                                      "width_pixels", 2,
                                      "outline_color", "light blue",
                                      NULL);
        view->n_fg_items++;
        view->fg_item_list = g_list_append (view->fg_item_list, item);
 
-       gnome_canvas_points_free (label_points);
+       gnome_canvas_points_free (points);
 
        gl_debug (DEBUG_VIEW, "END");
 }
@@ -656,12 +613,12 @@ draw_rounded_rect_bg_fg (glView *view)
 /* PRIVATE.  Draw round background.                                          */
 /*---------------------------------------------------------------------------*/
 static void
-draw_round_bg_fg (glView *view)
+draw_bg_fg_round (glView *view)
 {
-       glLabel *label = view->label;
-       glTemplate *template;
-       gdouble r, m;
-       GnomeCanvasItem *item;
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           r;
+       GnomeCanvasItem  *item;
        GnomeCanvasGroup *group;
 
        gl_debug (DEBUG_VIEW, "START");
@@ -673,15 +630,9 @@ draw_round_bg_fg (glView *view)
 
        group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
 
-       view->n_bg_items = 0;
-       view->bg_item_list = NULL;
-       view->n_fg_items = 0;
-       view->fg_item_list = NULL;
-
-       r = template->label_radius;
-       m = template->label_margin;
+       r = template->label.round.r;
 
-       /* Basic background */
+       /* Background */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_ellipse_get_type (),
                                      "x1", 0.0,
@@ -693,20 +644,10 @@ draw_round_bg_fg (glView *view)
        view->n_bg_items++;
        view->bg_item_list = g_list_append (view->bg_item_list, item);
 
-       /* Margin outline */
-       item = gnome_canvas_item_new (group,
-                                     gnome_canvas_ellipse_get_type (),
-                                     "x1", m,
-                                     "y1", m,
-                                     "x2", 2.0*r - m,
-                                     "y2", 2.0*r - m,
-                                     "width_pixels", 1,
-                                     "outline_color", "light blue", NULL);
-       view->n_bg_items++;
-       view->bg_item_list = g_list_append (view->bg_item_list, item);
+       /* Markup */
+       draw_markup (view);
 
-       /* Foreground outline */
-       r = template->label_radius;
+       /* Foreground */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_ellipse_get_type (),
                                      "x1", 0.0,
@@ -726,12 +667,12 @@ draw_round_bg_fg (glView *view)
 /* PRIVATE.  Draw CD style background, circular w/ concentric hole.          */
 /*---------------------------------------------------------------------------*/
 static void
-draw_cd_bg_fg (glView *view)
+draw_bg_fg_cd (glView *view)
 {
-       glLabel *label = view->label;
-       glTemplate *template;
-       gdouble m, r1, r2;
-       GnomeCanvasItem *item;
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           r1, r2;
+       GnomeCanvasItem  *item;
        GnomeCanvasGroup *group;
 
        gl_debug (DEBUG_VIEW, "START");
@@ -743,16 +684,10 @@ draw_cd_bg_fg (glView *view)
 
        group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
 
-       view->n_bg_items = 0;
-       view->bg_item_list = NULL;
-       view->n_fg_items = 0;
-       view->fg_item_list = NULL;
-
-       r1 = template->label_radius;
-       r2 = template->label_hole;
-       m  = template->label_margin;
+       r1 = template->label.cd.r1;
+       r2 = template->label.cd.r2;
 
-       /* Basic background */
+       /* Background */
        /* outer circle */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_ellipse_get_type (),
@@ -776,32 +711,10 @@ draw_cd_bg_fg (glView *view)
        view->n_bg_items++;
        view->bg_item_list = g_list_append (view->bg_item_list, item);
 
-       /* Margin outline */
-       /* outer margin */
-       item = gnome_canvas_item_new (group,
-                                     gnome_canvas_ellipse_get_type (),
-                                     "x1", m,
-                                     "y1", m,
-                                     "x2", 2.0*r1 - m,
-                                     "y2", 2.0*r1 - m,
-                                     "width_pixels", 1,
-                                     "outline_color", "light blue", NULL);
-       view->n_bg_items++;
-       view->bg_item_list = g_list_append (view->bg_item_list, item);
-       /* inner margin */
-       item = gnome_canvas_item_new (group,
-                                     gnome_canvas_ellipse_get_type (),
-                                     "x1", r1 - r2 - m,
-                                     "y1", r1 - r2 - m,
-                                     "x2", r1 + r2 + m,
-                                     "y2", r1 + r2 + m,
-                                     "width_pixels", 1,
-                                     "outline_color", "light blue",
-                                     NULL);
-       view->n_bg_items++;
-       view->bg_item_list = g_list_append (view->bg_item_list, item);
+       /* Markup */
+       draw_markup (view);
 
-       /* Foreground outline */
+       /* Foreground */
        /* outer circle */
        item = gnome_canvas_item_new (group,
                                      gnome_canvas_ellipse_get_type (),
@@ -830,10 +743,288 @@ draw_cd_bg_fg (glView *view)
        gl_debug (DEBUG_VIEW, "END");
 }
 
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw markup lines.                                              */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup (glView *view)
+{
+       glLabel          *label;
+       glTemplate       *template;
+       GList            *p;
+       glTemplateMarkup *markup;
+
+       label = view->label;
+       template = gl_label_get_template (label);
+
+       for ( p=template->label.any.markups; p != NULL; p=p->next ) {
+               markup = (glTemplateMarkup *)p->data;
+
+               switch (markup->type) {
+               case GL_TEMPLATE_MARKUP_MARGIN:
+                       draw_markup_margin (view,
+                                           (glTemplateMarkupMargin *)markup);
+                       break;
+               default:
+                       g_warning ("Unknown template markup type");
+                       break;
+               }
+       }
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw margin markup.                                             */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin (glView                 *view,
+                   glTemplateMarkupMargin *margin)
+{
+       glLabel    *label;
+       glTemplate *template;
+
+       label = view->label;
+       template = gl_label_get_template (label);
+
+       switch (template->label.style) {
+
+       case GL_TEMPLATE_STYLE_RECT:
+               if (template->label.rect.r == 0.0) {
+                       /* Square corners. */
+                       draw_markup_margin_rect (view, margin);
+               } else {
+                       if ( margin->size < template->label.rect.r) {
+                               /* Rounded corners. */
+                               draw_markup_margin_rounded_rect (view, margin);
+                       } else {
+                               /* Square corners. */
+                               draw_markup_margin_rect (view, margin);
+                       }
+               }
+               break;
+
+       case GL_TEMPLATE_STYLE_ROUND:
+               draw_markup_margin_round (view, margin);
+               break;
+
+       case GL_TEMPLATE_STYLE_CD:
+               draw_markup_margin_cd (view, margin);
+               break;
+
+       default:
+               g_warning ("Unknown template label style");
+               break;
+       }
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw simple recangular margin.                                  */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin_rect (glView                 *view,
+                        glTemplateMarkupMargin *margin)
+{
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           w, h, m;
+       GnomeCanvasItem  *item;
+       GnomeCanvasGroup *group;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       gl_label_get_size (label, &w, &h);
+       template = gl_label_get_template (label);
+       m = margin->size;
+
+       group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
+
+       /* Bounding box @ margin */
+       gnome_canvas_item_new (group,
+                              gnome_canvas_rect_get_type (),
+                              "x1", m,
+                              "y1", m,
+                              "x2", w - m,
+                              "y2", h - m,
+                              "width_pixels", 1,
+                              "outline_color", "light blue",
+                              NULL);
+       view->n_bg_items++;
+       view->bg_item_list = g_list_append (view->bg_item_list, item);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw rounded recangular markup.                                 */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin_rounded_rect (glView                 *view,
+                                glTemplateMarkupMargin *margin)
+{
+       glLabel           *label = view->label;
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       glTemplate        *template;
+       gdouble            r, w, h, m;
+       GnomeCanvasItem   *item;
+       GnomeCanvasGroup  *group;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
+
+       gl_label_get_size (label, &w, &h);
+       template = gl_label_get_template (label);
+       r = template->label.rect.r;
+       m = margin->size;
+
+       r = r - m;
+       w = w - 2 * m;
+       h = h - 2 * m;
+
+       /* rectangle with rounded corners */
+       points = gnome_canvas_points_new (4 * (1 + 90 / 5));
+       i_coords = 0;
+       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+               points->coords[i_coords++] =
+                       m + r - r * sin (i_theta * M_PI / 180.0);
+               points->coords[i_coords++] =
+                       m + r - r * cos (i_theta * M_PI / 180.0);
+       }
+       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+               points->coords[i_coords++] =
+                       m + r - r * cos (i_theta * M_PI / 180.0);
+               points->coords[i_coords++] =
+                       m + (h - r) + r * sin (i_theta * M_PI / 180.0);
+       }
+       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+               points->coords[i_coords++] =
+                       m + (w - r) + r * sin (i_theta * M_PI / 180.0);
+               points->coords[i_coords++] =
+                       m + (h - r) + r * cos (i_theta * M_PI / 180.0);
+       }
+       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+               points->coords[i_coords++] =
+                       m + (w - r) + r * cos (i_theta * M_PI / 180.0);
+               points->coords[i_coords++] =
+                       m + r - r * sin (i_theta * M_PI / 180.0);
+       }
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "width_pixels", 1,
+                                     "outline_color", "light blue",
+                                     NULL);
+       gnome_canvas_points_free (points);
+       view->n_bg_items++;
+       view->bg_item_list = g_list_append (view->bg_item_list, item);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw round margin.                                              */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin_round (glView                 *view,
+                         glTemplateMarkupMargin *margin)
+{
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           r, m;
+       GnomeCanvasItem  *item;
+       GnomeCanvasGroup *group;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       template = gl_label_get_template (label);
+
+       group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
+
+       r = template->label.round.r;
+       m = margin->size;
+
+       /* Margin outline */
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", m,
+                                     "y1", m,
+                                     "x2", 2.0*r - m,
+                                     "y2", 2.0*r - m,
+                                     "width_pixels", 1,
+                                     "outline_color", "light blue", NULL);
+       view->n_bg_items++;
+       view->bg_item_list = g_list_append (view->bg_item_list, item);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw CD margins.                                                */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin_cd (glView                 *view,
+                      glTemplateMarkupMargin *margin)
+{
+       glLabel          *label = view->label;
+       glTemplate       *template;
+       gdouble           m, r1, r2;
+       GnomeCanvasItem  *item;
+       GnomeCanvasGroup *group;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       template = gl_label_get_template (label);
+
+       group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
+
+       r1 = template->label.cd.r1;
+       r2 = template->label.cd.r2;
+       m  = margin->size;
+
+       /* outer margin */
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", m,
+                                     "y1", m,
+                                     "x2", 2.0*r1 - m,
+                                     "y2", 2.0*r1 - m,
+                                     "width_pixels", 1,
+                                     "outline_color", "light blue", NULL);
+       view->n_bg_items++;
+       view->bg_item_list = g_list_append (view->bg_item_list, item);
+       /* inner margin */
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", r1 - r2 - m,
+                                     "y1", r1 - r2 - m,
+                                     "x2", r1 + r2 + m,
+                                     "y2", r1 + r2 + m,
+                                     "width_pixels", 1,
+                                     "outline_color", "light blue",
+                                     NULL);
+       view->n_bg_items++;
+       view->bg_item_list = g_list_append (view->bg_item_list, item);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
 /*****************************************************************************/
 /* Raise foreground items to top.                                            */
 /*****************************************************************************/
-void gl_view_raise_fg (glView *view)
+void
+gl_view_raise_fg (glView *view)
 {
        GList *p;
 
index d8dcca7ce2193f819f945358856fc8c285346265..03d7601588a05c26fa138b2417abbc5d1425f8ed 100644 (file)
@@ -405,30 +405,11 @@ details_update (glWdgtMediaSelect * media_select,
        gtk_label_set_text (GTK_LABEL (media_select->sheet_size_label),
                            template->page_size);
 
-       text = g_strdup_printf (_("%d x %d  (%d per sheet)"),
-                               template->nx, template->ny,
-                               template->nx * template->ny);
-
+       text = gl_template_get_layout_desc (template);
        gtk_label_set_text (GTK_LABEL (media_select->number_label), text);
        g_free (text);
 
-       if ( units == GL_PREFS_UNITS_INCHES ) {
-               gchar *xstr, *ystr;
-
-               xstr = gl_util_fraction (template->label_height
-                                        * units_per_point);
-               ystr = gl_util_fraction (template->label_width
-                                        * units_per_point);
-               text = g_strdup_printf (_("%s x %s %s"),
-                                       xstr, ystr, units_string);
-               g_free (xstr);
-               g_free (ystr);
-       } else {
-               text = g_strdup_printf (_("%.5g x %.5g %s"),
-                                       template->label_height*units_per_point,
-                                       template->label_width*units_per_point,
-                                       units_string);
-       }
+       text = gl_template_get_label_size_desc (template);
        gtk_label_set_text (GTK_LABEL (media_select->label_size_label), text);
        g_free (text);
 
index caf85f0e39ace7cd6fe938d99efa0214192466ce..16f7bcd8610204249efae971ab67c7831482a6c6 100644 (file)
@@ -314,16 +314,17 @@ void gl_wdgt_mini_preview_set_label (glWdgtMiniPreview * preview,
 /* PRIVATE.  Draw label outlines and return canvas item list.               */
 /*--------------------------------------------------------------------------*/
 static GList *
-mini_outline_list_new (GnomeCanvas * canvas,
-                      glTemplate template)
+mini_outline_list_new (GnomeCanvas *canvas,
+                      glTemplate  *template)
 {
-       GnomeCanvasGroup *group = NULL;
-       GnomeCanvasItem *item = NULL;
-       GList *list = NULL;
-       gint i, ix, iy;
-       gdouble x1, y1, x2, y2, y_temp;
+       GnomeCanvasGroup      *group = NULL;
+       GnomeCanvasItem       *item = NULL;
+       GList                 *list = NULL;
+       gint                   i, n_labels;
+       glTemplateOrigin      *origins;
+       gdouble                x1, y1, x2, y2, y_temp, w, h;
        const GnomePrintPaper *paper = NULL;
-       gdouble paper_height;
+       gdouble                paper_height;
 
        gl_debug (DEBUG_MINI_PREVIEW, "START");
 
@@ -334,57 +335,57 @@ mini_outline_list_new (GnomeCanvas * canvas,
        group = gnome_canvas_root (canvas);
 
        /* draw mini label outlines */
-       i = 1;
-       for (iy = (template->ny - 1); iy >= 0; iy--) {
-               for (ix = 0; ix < template->nx; ix++, i++) {
-
-                       x1 = ix * (template->dx) + template->x0;
-                       y1 = iy * (template->dy) + template->y0;
-                       x2 = x1 + template->label_width;
-                       y2 = y1 + template->label_height;
-
-                        /* transform origin from lower left to upper left */
-                       /* and swap y's so that (y1 < y2) */
-                       y_temp = y2;
-                       y2 = paper_height - y1;
-                       y1 = paper_height - y_temp;
-
-                       switch (template->style) {
-                       case GL_TEMPLATE_STYLE_RECT:
-                               item = gnome_canvas_item_new (group,
-                                                             gnome_canvas_rect_get_type(),
-                                                             "x1", x1,
-                                                             "y1", y1,
-                                                             "x2", x2,
-                                                             "y2", y2,
-                                                             "width_pixels", 1,
-                                                             "outline_color", "black",
-                                                             "fill_color", "white",
-                                                             NULL);
-                               break;
-                       case GL_TEMPLATE_STYLE_ROUND:
-                       case GL_TEMPLATE_STYLE_CD:
-                               item = gnome_canvas_item_new (group,
-                                                             gnome_canvas_ellipse_get_type(),
-                                                             "x1", x1,
-                                                             "y1", y1,
-                                                             "x2", x2,
-                                                             "y2", y2,
-                                                             "width_pixels", 1,
-                                                             "outline_color", "black",
-                                                             "fill_color", "white",
-                                                             NULL);
-                               break;
-                       default:
-                               g_warning ("Unknown label style");
-                               return list;
-                               break;
-                       }
-                       g_object_set_data (G_OBJECT (item), "i",
-                                            GINT_TO_POINTER (i));
-
-                       list = g_list_append (list, item);
+       n_labels = gl_template_get_n_labels (template);
+       origins  = gl_template_get_origins (template);
+       gl_template_get_label_size (template, &w, &h);
+       for ( i=0; i < n_labels; i++ ) {
+
+               x1 = origins[i].x;
+               y1 = origins[i].y;
+               x2 = x1 + w;
+               y2 = y1 + h;
+
+               /* transform origin from lower left to upper left */
+               /* and swap y's so that (y1 < y2) */
+               y_temp = y2;
+               y2 = paper_height - y1;
+               y1 = paper_height - y_temp;
+
+               switch (template->label.style) {
+               case GL_TEMPLATE_STYLE_RECT:
+                       item = gnome_canvas_item_new (group,
+                                                     gnome_canvas_rect_get_type(),
+                                                     "x1", x1,
+                                                     "y1", y1,
+                                                     "x2", x2,
+                                                     "y2", y2,
+                                                     "width_pixels", 1,
+                                                     "outline_color", "black",
+                                                     "fill_color", "white",
+                                                     NULL);
+                       break;
+               case GL_TEMPLATE_STYLE_ROUND:
+               case GL_TEMPLATE_STYLE_CD:
+                       item = gnome_canvas_item_new (group,
+                                                     gnome_canvas_ellipse_get_type(),
+                                                     "x1", x1,
+                                                     "y1", y1,
+                                                     "x2", x2,
+                                                     "y2", y2,
+                                                     "width_pixels", 1,
+                                                     "outline_color", "black",
+                                                     "fill_color", "white",
+                                                     NULL);
+                       break;
+               default:
+                       g_warning ("Unknown label style");
+                       return list;
+                       break;
                }
+               g_object_set_data (G_OBJECT (item), "i",
+                                  GINT_TO_POINTER (i));
+               
+               list = g_list_append (list, item);
        }
 
        gl_debug (DEBUG_MINI_PREVIEW, "END");
index 75dc8cdb1f345071ccaa9a47a655ffea7a09c8fd..3029e70de93a83730cfd866299c5d92934aeace4 100644 (file)
@@ -158,13 +158,13 @@ gl_wdgt_print_copies_construct (glWdgtPrintCopies * copies,
        whbox = GTK_WIDGET (copies);
 
        template = gl_label_get_template (label);
-       copies->labels_per_sheet = template->nx * template->ny;
+       copies->labels_per_sheet = gl_template_get_n_labels (template);
 
        /* mini_preview canvas */
        copies->mini_preview = gl_wdgt_mini_preview_new (WDGT_MINI_PREVIEW_HEIGHT,
                                                    WDGT_MINI_PREVIEW_WIDTH);
        gl_wdgt_mini_preview_set_label (GL_WDGT_MINI_PREVIEW(copies->mini_preview),
-                                  template->name->data);
+                                       template->name->data);
        gtk_box_pack_start (GTK_BOX (whbox), copies->mini_preview,
                            TRUE, TRUE, GNOME_PAD);
 
index f11a0e4f3bf2a8dee5bd65b22f5a780f0662b59e..ea7acadca02804531296da298b661fba5004b4d3 100644 (file)
@@ -155,13 +155,13 @@ gl_wdgt_print_merge_construct (glWdgtPrintMerge * merge,
        whbox = GTK_WIDGET (merge);
 
        template = gl_label_get_template (label);
-       merge->labels_per_sheet = template->nx * template->ny;
+       merge->labels_per_sheet = gl_template_get_n_labels (template);
 
        /* mini_preview canvas */
        merge->mini_preview = gl_wdgt_mini_preview_new (WDGT_MINI_PREVIEW_HEIGHT,
                                                        WDGT_MINI_PREVIEW_WIDTH);
        gl_wdgt_mini_preview_set_label( GL_WDGT_MINI_PREVIEW (merge->mini_preview),
-                                  template->name->data );
+                                       template->name->data );
        gtk_box_pack_start (GTK_BOX (whbox), merge->mini_preview,
                            TRUE, TRUE, GNOME_PAD);
        gl_wdgt_mini_preview_highlight_range (GL_WDGT_MINI_PREVIEW(merge->mini_preview),
index 23ba0b02e46af74d0ce4b0bbb2838353bd35fddf..fc0776c32bd6387f50fb7495936d035f2d944720 100644 (file)
@@ -244,12 +244,13 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
        gdouble canvas_scale;
        GnomeCanvasGroup *group = NULL;
        GnomeCanvasItem *label_item = NULL;
-       gdouble m, w, h;
+       gdouble m, raw_w, raw_h, w, h;
 
        /* Fetch our data from canvas */
        label_item = g_object_get_data (G_OBJECT (canvas), "label_item");
 
-       m = MAX (template->label_width, template->label_height);
+       gl_template_get_label_size (template, &raw_w, &raw_h);
+       m = MAX (raw_w, raw_h);
        canvas_scale = (MINI_PREVIEW_MAX_PIXELS) / m;
 
        /* FIXME: Stupid hack to eliminate canvas artifacts. */
@@ -271,13 +272,13 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
 
        /* draw mini label outline */
        if (!rotate_flag) {
-               w = template->label_width;
-               h = template->label_height;
+               w = raw_w;
+               h = raw_h;
        } else {
-               w = template->label_height;
-               h = template->label_width;
+               w = raw_h;
+               h = raw_w;
        }
-       switch (template->style) {
+       switch (template->label.style) {
        case GL_TEMPLATE_STYLE_RECT:
                label_item = gnome_canvas_item_new (group,
                                                    gnome_canvas_rect_get_type(),
@@ -342,11 +343,13 @@ gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel * rotate_select,
                                        gchar * name)
 {
        glTemplate *template;
+       gdouble raw_w, raw_h;
 
        template = gl_template_from_name (name);
        rotate_select->template = template;
+       gl_template_get_label_size (template, &raw_w, &raw_h);
 
-       if (template->label_width != template->label_height) {
+       if (raw_w != raw_h) {
                gtk_widget_set_sensitive (rotate_select->rotate_check, TRUE);
        } else {
                gtk_widget_set_sensitive (rotate_select->rotate_check, FALSE);