]> git.sur5r.net Git - glabels/commitdiff
Added new barcode drawing primitives.
authorJim Evins <evins@snaught.com>
Sat, 10 Jul 2010 03:20:11 +0000 (23:20 -0400)
committerJim Evins <evins@snaught.com>
Sat, 10 Jul 2010 04:17:47 +0000 (00:17 -0400)
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
src/bc.c
src/bc.h
src/label-barcode.c

index 3ee26acb5e271189c39b4ddb3a9995fee8414c60..fb02b51450f7ebbb170e561eb60007c97c8a49fa 100644 (file)
@@ -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 */
index 35a2bc4b49890e0c34b21756c523d3b7edda1d8f..247b50658788f338a16be6686d34a5881dbe93e2 100644 (file)
--- a/src/bc.c
+++ b/src/bc.c
@@ -440,6 +440,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.                                                 */
 /*****************************************************************************/
@@ -453,6 +466,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.*/
 /*****************************************************************************/
@@ -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);
index 909f74f24da9941c20a946a6cf055845f4fcdd0d..5a0374f0ad1ce0db4ef85c930c72396572e4ec15 100644 (file)
--- 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.
  *
 
 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 {
@@ -70,6 +81,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:
  *
@@ -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__ */
index fe108fd07855f80fad4adb0794619e15f233644f..6f538189e454e7e72d6165354c355685e4a7df4c 100644 (file)
@@ -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;