[glabels/zint: 14/15] Added new barcode drawing primitives.
- From: Jim Evins <jimevins src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glabels/zint: 14/15] Added new barcode drawing primitives.
- Date: Sat, 10 Jul 2010 04:41:36 +0000 (UTC)
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]