From: Jim Evins Date: Sun, 15 Sep 2002 23:38:00 +0000 (+0000) Subject: Restructured template module to ultimately support multiple layouts and markups. X-Git-Tag: glabels-2_3_0~768 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=26bbbd8b02ac36829fe272c10d502206a95322f0;p=glabels Restructured template module to ultimately support multiple layouts and markups. git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@117 f5e0f49d-192f-0410-a22d-a8d8700d0965 --- diff --git a/glabels2/src/Makefile.am b/glabels2/src/Makefile.am index 8099522d..29d1a1b2 100644 --- a/glabels2/src/Makefile.am +++ b/glabels2/src/Makefile.am @@ -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 \ diff --git a/glabels2/src/label.c b/glabels2/src/label.c index e6dd7134..cd654d46 100644 --- a/glabels2/src/label.c +++ b/glabels2/src/label.c @@ -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; } diff --git a/glabels2/src/prefs.h b/glabels2/src/prefs.h index 6a0967be..27fcd96d 100644 --- a/glabels2/src/prefs.h +++ b/glabels2/src/prefs.h @@ -22,6 +22,7 @@ #ifndef __PREFS_H__ #define __PREFS_H__ +#include #include typedef struct _glPreferences glPreferences; diff --git a/glabels2/src/print.c b/glabels2/src/print.c index a3a69798..5e0a7a8d 100644 --- a/glabels2/src/print.c +++ b/glabels2/src/print.c @@ -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; diff --git a/glabels2/src/template.c b/glabels2/src/template.c index ef568edb..9e994619 100644 --- a/glabels2/src/template.c +++ b/glabels2/src/template.c @@ -25,6 +25,8 @@ #include #include +#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; +} diff --git a/glabels2/src/template.h b/glabels2/src/template.h index 4ec025f9..3b0a5fa2 100644 --- a/glabels2/src/template.h +++ b/glabels2/src/template.h @@ -27,48 +27,130 @@ #include #include + +/* + * 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 diff --git a/glabels2/src/view.c b/glabels2/src/view.c index 916114ee..9f3e36af 100644 --- a/glabels2/src/view.c +++ b/glabels2/src/view.c @@ -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); /****************************************************************************/ /* 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; diff --git a/glabels2/src/wdgt-media-select.c b/glabels2/src/wdgt-media-select.c index d8dcca7c..03d76015 100644 --- a/glabels2/src/wdgt-media-select.c +++ b/glabels2/src/wdgt-media-select.c @@ -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); diff --git a/glabels2/src/wdgt-mini-preview.c b/glabels2/src/wdgt-mini-preview.c index caf85f0e..16f7bcd8 100644 --- a/glabels2/src/wdgt-mini-preview.c +++ b/glabels2/src/wdgt-mini-preview.c @@ -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"); diff --git a/glabels2/src/wdgt-print-copies.c b/glabels2/src/wdgt-print-copies.c index 75dc8cdb..3029e70d 100644 --- a/glabels2/src/wdgt-print-copies.c +++ b/glabels2/src/wdgt-print-copies.c @@ -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); diff --git a/glabels2/src/wdgt-print-merge.c b/glabels2/src/wdgt-print-merge.c index f11a0e4f..ea7acadc 100644 --- a/glabels2/src/wdgt-print-merge.c +++ b/glabels2/src/wdgt-print-merge.c @@ -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), diff --git a/glabels2/src/wdgt-rotate-label.c b/glabels2/src/wdgt-rotate-label.c index 23ba0b02..fc0776c3 100644 --- a/glabels2/src/wdgt-rotate-label.c +++ b/glabels2/src/wdgt-rotate-label.c @@ -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);