summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Evins <evins@snaught.com>2010-07-09 23:20:11 -0400
committerJim Evins <evins@snaught.com>2010-07-10 00:17:47 -0400
commite43f6397f295172646ed67456799c1fe6cbfb94a (patch)
tree12388b08982bc0072c538319a37deb9abcd59a15
parentf2ced22e6919c5311fb0467e0f07874d9e28e16d (diff)
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.
-rw-r--r--src/bc-zint.c81
-rw-r--r--src/bc.c49
-rw-r--r--src/bc.h118
-rw-r--r--src/label-barcode.c32
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;