[glabels/zint: 14/15] Added new barcode drawing primitives.



commit e43f6397f295172646ed67456799c1fe6cbfb94a
Author: Jim Evins <evins snaught com>
Date:   Fri Jul 9 23:20:11 2010 -0400

    Added new barcode drawing primitives.
    
    Added a "Box" and a "String" barcode drawing primitives.  The box primitive
    should be more natural for drawing actual boxes instead of lines.  The string
    primitive allows an entire string to be rendered with a single interaction with
    pango and cairo, rather than an interaction for each character.  There is no
    need to try to implement kerning since pango will take care of the string as
    a single layout.

 src/bc-zint.c       |   81 ++++++++++++++++-------------------
 src/bc.c            |   49 +++++++++++++++++++++-
 src/bc.h            |  118 ++++++++++++++++++++++++++++++++++++++++++---------
 src/label-barcode.c |   32 ++++++++++++++
 4 files changed, 214 insertions(+), 66 deletions(-)
---
diff --git a/src/bc-zint.c b/src/bc-zint.c
index 3ee26ac..fb02b51 100644
--- a/src/bc-zint.c
+++ b/src/bc-zint.c
@@ -179,62 +179,55 @@ gl_barcode_zint_new (const gchar          *id,
  * internal  Zint code to convert directly to glBarcode representation.
  *
  *--------------------------------------------------------------------------*/
-static glBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag) {
+static glBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag)
+{
+        glBarcode            *gbc;
+        glBarcodeShapeBox    *box;
+        glBarcodeShapeString *bstring;
 	
-	int i;
-	double string_offset, x;
+        struct zint_render        *render;
+        struct zint_render_line   *zline;
+        struct zint_render_string *zstring;
 
-        glBarcode           *gbc;
-        glBarcodeShapeLine  *line;
-        glBarcodeShapeAlpha *bchar;
-	
-	struct zint_render      *render;
-	struct zint_render_line *zline;
-	struct zint_render_string *zstring;
 
-	render = symbol->rendered;
-	gbc = g_new0(glBarcode, 1);
-	
+        render = symbol->rendered;
+        gbc = g_new0(glBarcode, 1);
 	
-	for ( zline = render->lines; zline != NULL; zline = zline->next ) {
-		line = gl_barcode_shape_line_new ();
+        for ( zline = render->lines; zline != NULL; zline = zline->next )
+        {
+                box = gl_barcode_shape_box_new ();
 
-		line->width = (double) zline->width;
-		line->length = (double) zline->length;
-		/* glBarcodeLine centers based on width, counter-act!!! */
-		line->x = (double) (zline->x + (zline->width / 2.0));
-		line->y = (double) zline->y;
+                box->x      = (gdouble) zline->x;
+                box->y      = (gdouble) zline->y;
+                box->width  = (gdouble) zline->width;
+                box->height = (gdouble) zline->length;
 
-		gl_barcode_add_shape (gbc, (glBarcodeShape *)line);
-	}
+                gl_barcode_add_shape (gbc, (glBarcodeShape *)box);
+        }
 
 	/*
 	 * Repeat loop for characters
 	 */
-	if(text_flag) {
-		for ( zstring = render->strings; zstring != NULL; zstring = zstring->next ) {
-			string_offset = (double) zstring->x - (((6.0 / 9.0) * zstring->length * zstring->fsize) / 2);
-			for(i = 0; i < zstring->length; i++) {
-        x = 0.0;
-        // Poor man's kerning
-        if (zstring->text[i] == '(') { x = 0.18; }
-				bchar = gl_barcode_shape_alpha_new();
-				bchar->x = (double) string_offset + ((((6.0 / 9.0) * i) + x) * zstring->fsize);
-				bchar->y = (double) zstring->y;
-				bchar->fsize = (double) zstring->fsize;
-				bchar->c = (char) zstring->text[i];
-				gl_barcode_add_shape (gbc, (glBarcodeShape *)bchar);
-			}
-		}
-	}
+        if(text_flag)
+        {
+                for ( zstring = render->strings; zstring != NULL; zstring = zstring->next )
+                {
+                        bstring = gl_barcode_shape_string_new();
+                        bstring->x = (double) zstring->x - (((6.0 / 9.0) * zstring->length * zstring->fsize) / 2);
+                        bstring->y = (double) zstring->y;
+                        bstring->fsize = (double) zstring->fsize;
+                        bstring->str   = g_strndup (zstring->text, zstring->length);
+                        gl_barcode_add_shape (gbc, (glBarcodeShape *)bstring);
+                }
+        }
 
-	/*
-	 * Finally add complete sizes
-	 */
-	gbc->width = (gdouble) render->width;
-	gbc->height = (gdouble) render->height;
+        /*
+         * Finally add complete sizes
+         */
+        gbc->width = (gdouble) render->width;
+        gbc->height = (gdouble) render->height;
 
-	return gbc;
+        return gbc;
 }
 
 #endif /* HAVE_LIBZINT */
diff --git a/src/bc.c b/src/bc.c
index 35a2bc4..247b506 100644
--- a/src/bc.c
+++ b/src/bc.c
@@ -441,6 +441,19 @@ gl_barcode_shape_line_new (void)
 
 
 /*****************************************************************************/
+/* Allocate new Box shape.                                                   */
+/*****************************************************************************/
+glBarcodeShapeBox *
+gl_barcode_shape_box_new (void)
+{
+        glBarcodeShapeBox *box_shape = g_new0 (glBarcodeShapeBox, 1);
+        box_shape->type = GL_BARCODE_SHAPE_BOX;
+
+        return box_shape;
+}
+
+
+/*****************************************************************************/
 /* Allocate new Alpha shape.                                                 */
 /*****************************************************************************/
 glBarcodeShapeAlpha *
@@ -454,6 +467,40 @@ gl_barcode_shape_alpha_new (void)
 
 
 /*****************************************************************************/
+/* Allocate new String shape.                                                */
+/*****************************************************************************/
+glBarcodeShapeString *
+gl_barcode_shape_string_new (void)
+{
+        glBarcodeShapeString *string_shape = g_new0 (glBarcodeShapeString, 1);
+        string_shape->type = GL_BARCODE_SHAPE_STRING;
+
+        return string_shape;
+}
+
+
+/*****************************************************************************/
+/* Free a shape primitive.                                                   */
+/*****************************************************************************/
+void
+gl_barcode_shape_free (glBarcodeShape *shape)
+{
+        switch (shape->type)
+        {
+
+        case GL_BARCODE_SHAPE_STRING:
+                g_free (shape->string.str);
+                break;
+
+        default:
+                break;
+        }
+
+        g_free (shape);
+}
+
+
+/*****************************************************************************/
 /* Call appropriate barcode backend to create barcode in intermediate format.*/
 /*****************************************************************************/
 glBarcode *
@@ -492,7 +539,7 @@ gl_barcode_free (glBarcode **gbc)
 	if (*gbc != NULL) {
 
 		for (p = (*gbc)->shapes; p != NULL; p = p->next) {
-			g_free (p->data);
+			gl_barcode_shape_free ((glBarcodeShape *)p->data);
 			p->data = NULL;
 		}
 		g_list_free ((*gbc)->shapes);
diff --git a/src/bc.h b/src/bc.h
index 909f74f..5a0374f 100644
--- a/src/bc.h
+++ b/src/bc.h
@@ -1,6 +1,6 @@
 /*
  *  bc.h
- *  Copyright (C) 2001-2009  Jim Evins <evins snaught com>.
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -26,9 +26,20 @@
 
 G_BEGIN_DECLS
 
+
+#define GL_BARCODE_FONT_FAMILY      "Sans"
+#define GL_BARCODE_FONT_WEIGHT      PANGO_WEIGHT_NORMAL
+
+
+/*******************************/
+/* Barcode Drawing Primitives. */
+/*******************************/
+
 typedef enum {
         GL_BARCODE_SHAPE_LINE,
+        GL_BARCODE_SHAPE_BOX,
         GL_BARCODE_SHAPE_ALPHA,
+        GL_BARCODE_SHAPE_STRING,
 } glBarcodeShapeType;
 
 typedef struct {
@@ -71,6 +82,35 @@ typedef struct {
 } glBarcodeShapeLine;
 
 /*
+ * glBarcodeShapeBox:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              @---------+
+ *              |         |
+ *              |         |
+ *              |         |
+ *              |         | height
+ *              |         |
+ *              |         |
+ *              |         |
+ *              +---------+
+ *                 width
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        glBarcodeShapeType  type; /* Always GL_BARCODE_SHAPE_LINE. */
+        gdouble             x;
+        gdouble             y;
+        /* End Common Fields */
+
+        gdouble             width;
+        gdouble             height;
+
+} glBarcodeShapeBox;
+
+/*
  * glBarcodeShapeAlpha:
  *
  * @ =  origin (x,y) from top left corner of barcode
@@ -98,42 +138,77 @@ typedef struct {
 
 } glBarcodeShapeAlpha;
 
+/*
+ * glBarcodeShapeString:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              ____        _  ------------------
+ *             /    \      | |                  ^
+ *            /  /\  \     | |                  |
+ *           /  /__\  \    | |___     ____      |
+ *          /  ______  \   | ._  \   /  __|     | ~fsize
+ *         /  /      \  \  | |_)  | |  (__      |
+ *        /__/        \__\ |_.___/   \____|     |
+ *                                              v
+ *       @ --------------------------------------
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        glBarcodeShapeType  type; /* Always GL_BARCODE_SHAPE_ALPHA. */
+        gdouble             x;
+        gdouble             y;
+        /* End Common Fields */
+
+        gdouble             fsize;
+        gchar              *str;
+
+} glBarcodeShapeString;
+
 typedef union {
 
         glBarcodeShapeType    type;
         glBarcodeShapeAny     any;
 
         glBarcodeShapeLine    line;
+        glBarcodeShapeBox     box;
         glBarcodeShapeAlpha   alpha;
+        glBarcodeShapeString  string;
 
 } glBarcodeShape;
 
-typedef struct {
-	gdouble width, height;
-	GList *shapes;		/* List of glBarcodeShape */
-} glBarcode;
+glBarcodeShapeLine   *gl_barcode_shape_line_new   (void);
+glBarcodeShapeBox    *gl_barcode_shape_box_new    (void);
+glBarcodeShapeAlpha  *gl_barcode_shape_alpha_new  (void);
+glBarcodeShapeString *gl_barcode_shape_string_new (void);
 
-typedef glBarcode *(*glBarcodeNewFunc) (const gchar    *id,
-					gboolean        text_flag,
-					gboolean        checksum_flag,
-					gdouble         w,
-					gdouble         h,
-					const gchar    *digits);
+void                  gl_barcode_shape_free       (glBarcodeShape *shape);
 
 
-#define GL_BARCODE_FONT_FAMILY      "Sans"
-#define GL_BARCODE_FONT_WEIGHT      PANGO_WEIGHT_NORMAL
+/********************************/
+/* Barcode Intermediate Format. */
+/********************************/
 
+typedef struct {
+        gdouble width, height;
+        GList *shapes;    /* List of glBarcodeShape */
+} glBarcode;
+
+typedef glBarcode *(*glBarcodeNewFunc)       (const gchar    *id,
+                                              gboolean        text_flag,
+                                              gboolean        checksum_flag,
+                                              gdouble         w,
+                                              gdouble         h,
+                                              const gchar    *digits);
 
-glBarcodeShapeLine  *gl_barcode_shape_line_new  (void);
-glBarcodeShapeAlpha *gl_barcode_shape_alpha_new (void);
 
 glBarcode       *gl_barcode_new              (const gchar    *id,
-					      gboolean        text_flag,
-					      gboolean        checksum_flag,
-					      gdouble         w,
-					      gdouble         h,
-					      const gchar    *digits);
+                                              gboolean        text_flag,
+                                              gboolean        checksum_flag,
+                                              gdouble         w,
+                                              gdouble         h,
+                                              const gchar    *digits);
 
 void             gl_barcode_free             (glBarcode     **bc);
 
@@ -144,7 +219,7 @@ GList           *gl_barcode_get_styles_list  (void);
 void             gl_barcode_free_styles_list (GList          *styles_list);
 
 gchar           *gl_barcode_default_digits   (const gchar    *id,
-					      guint            n);
+                                              guint            n);
 
 gboolean         gl_barcode_can_text         (const gchar    *id);
 gboolean         gl_barcode_text_optional    (const gchar    *id);
@@ -158,6 +233,7 @@ guint            gl_barcode_get_prefered_n   (const gchar    *id);
 const gchar     *gl_barcode_id_to_name       (const gchar    *id);
 const gchar     *gl_barcode_name_to_id       (const gchar    *name);
 
+
 G_END_DECLS
 
 #endif /* __BC_H__ */
diff --git a/src/label-barcode.c b/src/label-barcode.c
index fe108fd..6f53818 100644
--- a/src/label-barcode.c
+++ b/src/label-barcode.c
@@ -424,7 +424,9 @@ draw_object (glLabelObject *object,
         glBarcode            *gbc;
         glBarcodeShape       *shape;
         glBarcodeShapeLine   *line;
+        glBarcodeShapeBox    *box;
         glBarcodeShapeAlpha  *bchar;
+        glBarcodeShapeString *bstring;
         GList                *p;
         gdouble               y_offset;
         PangoLayout          *layout;
@@ -509,6 +511,14 @@ draw_object (glLabelObject *object,
 
                                 break;
 
+                        case GL_BARCODE_SHAPE_BOX:
+                                box = (glBarcodeShapeBox *) shape;
+
+                                cairo_rectangle (cr, box->x, box->y, box->width, box->height);
+                                cairo_fill (cr);
+
+                                break;
+
                         case GL_BARCODE_SHAPE_ALPHA:
                                 bchar = (glBarcodeShapeAlpha *) shape;
 
@@ -533,6 +543,28 @@ draw_object (glLabelObject *object,
 
                                 break;
 
+                        case GL_BARCODE_SHAPE_STRING:
+                                bstring = (glBarcodeShapeString *) shape;
+
+                                layout = pango_cairo_create_layout (cr);
+
+                                desc = pango_font_description_new ();
+                                pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
+                                pango_font_description_set_size   (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
+                                pango_layout_set_font_description (layout, desc);
+                                pango_font_description_free       (desc);
+
+                                pango_layout_set_text (layout, bstring->str, -1);
+
+                                y_offset = 0.2 * bstring->fsize;
+
+                                cairo_move_to (cr, bstring->x, bstring->y-y_offset);
+                                pango_cairo_show_layout (cr, layout);
+
+                                g_object_unref (layout);
+
+                                break;
+
                         default:
                                 g_assert_not_reached ();
                                 break;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]