+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
/*
* (GLABELS) Label and Business Card Creation program for GNOME
*
* label_barcode.c: GLabels label text object
*
- * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
+ * Copyright (C) 2001-2007 Jim Evins <evins@snaught.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "label-barcode.h"
+#include <glib/gi18n.h>
#include <glib/gmem.h>
#include <glib/gstrfuncs.h>
#include <glib/gmessages.h>
-
-#include "pixmaps/checkerboard.xpm"
+#include <cairo.h>
+#include <pango/pangocairo.h>
#include "debug.h"
/* Private macros and constants. */
/*========================================================*/
+#define FONT_SCALE (72.0/96.0)
+
/*========================================================*/
/* Private types. */
/*========================================================*/
/* Private globals. */
/*========================================================*/
-static glLabelObjectClass *parent_class = NULL;
-
-static guint instance = 0;
-
/*========================================================*/
/* Private function prototypes. */
/*========================================================*/
-static void gl_label_barcode_class_init (glLabelBarcodeClass *klass);
-static void gl_label_barcode_instance_init (glLabelBarcode *lbc);
static void gl_label_barcode_finalize (GObject *object);
static void copy (glLabelObject *dst_object,
static void set_line_color (glLabelObject *object,
glColorNode *line_color);
-static glColorNode *get_line_color (glLabelObject *object);
+static glColorNode *get_line_color (glLabelObject *object);
+
+static void draw_object (glLabelObject *object,
+ cairo_t *cr,
+ gboolean screen_flag,
+ glMergeRecord *record);
\f
/*****************************************************************************/
/* Boilerplate object stuff. */
/*****************************************************************************/
-GType
-gl_label_barcode_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (glLabelBarcodeClass),
- NULL,
- NULL,
- (GClassInitFunc) gl_label_barcode_class_init,
- NULL,
- NULL,
- sizeof (glLabelBarcode),
- 0,
- (GInstanceInitFunc) gl_label_barcode_instance_init,
- NULL
- };
-
- type = g_type_register_static (GL_TYPE_LABEL_OBJECT,
- "glLabelBarcode", &info, 0);
- }
-
- return type;
-}
+G_DEFINE_TYPE (glLabelBarcode, gl_label_barcode, GL_TYPE_LABEL_OBJECT);
static void
-gl_label_barcode_class_init (glLabelBarcodeClass *klass)
+gl_label_barcode_class_init (glLabelBarcodeClass *class)
{
- GObjectClass *object_class = (GObjectClass *) klass;
- glLabelObjectClass *label_object_class = (glLabelObjectClass *) klass;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
- parent_class = g_type_class_peek_parent (klass);
+ gl_label_barcode_parent_class = g_type_class_peek_parent (class);
label_object_class->copy = copy;
label_object_class->get_size = get_size;
label_object_class->set_line_color = set_line_color;
label_object_class->get_line_color = get_line_color;
+ label_object_class->draw_object = draw_object;
+ label_object_class->draw_shadow = NULL;
object_class->finalize = gl_label_barcode_finalize;
}
static void
-gl_label_barcode_instance_init (glLabelBarcode *lbc)
+gl_label_barcode_init (glLabelBarcode *lbc)
{
- lbc->private = g_new0 (glLabelBarcodePrivate, 1);
- lbc->private->color_node = gl_color_node_new_default ();
+ lbc->priv = g_new0 (glLabelBarcodePrivate, 1);
+ lbc->priv->color_node = gl_color_node_new_default ();
+ lbc->priv->text_node = gl_text_node_new_from_text ("");
}
static void
gl_label_barcode_finalize (GObject *object)
{
- glLabelBarcode *lbc;
+ glLabelBarcode *lbc = GL_LABEL_BARCODE (object);
g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
- lbc = GL_LABEL_BARCODE (object);
-
- gl_color_node_free (&(lbc->private->color_node));
- gl_text_node_free (&lbc->private->text_node);
- g_free (lbc->private);
+ gl_text_node_free (&lbc->priv->text_node);
+ g_free (lbc->priv->id);
+ gl_color_node_free (&(lbc->priv->color_node));
+ g_free (lbc->priv);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (gl_label_barcode_parent_class)->finalize (object);
}
/*****************************************************************************/
-/* NEW label "text" object. */
+/* NEW label "barcode" object. */
/*****************************************************************************/
GObject *
gl_label_barcode_new (glLabel *label)
g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
- if (!gl_text_node_equal (lbc->private->text_node, text_node)) {
+ if (!gl_text_node_equal (lbc->priv->text_node, text_node)) {
- gl_text_node_free (&lbc->private->text_node);
- lbc->private->text_node = gl_text_node_dup (text_node);
+ gl_text_node_free (&lbc->priv->text_node);
+ lbc->priv->text_node = gl_text_node_dup (text_node);
gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
- if ( ((lbc->private->id == NULL) && (id != NULL))
- || (g_strcasecmp (lbc->private->id, id) != 0)
- || (lbc->private->text_flag != text_flag)
- || (lbc->private->checksum_flag != checksum_flag)
- || (lbc->private->format_digits != format_digits)) {
+ if ( ((lbc->priv->id == NULL) && (id != NULL))
+ || (g_ascii_strcasecmp (lbc->priv->id, id) != 0)
+ || (lbc->priv->text_flag != text_flag)
+ || (lbc->priv->checksum_flag != checksum_flag)
+ || (lbc->priv->format_digits != format_digits)) {
- lbc->private->id = g_strdup (id);
- lbc->private->text_flag = text_flag;
- lbc->private->checksum_flag = checksum_flag;
- lbc->private->format_digits = format_digits;
+ lbc->priv->id = g_strdup (id);
+ lbc->priv->text_flag = text_flag;
+ lbc->priv->checksum_flag = checksum_flag;
+ lbc->priv->format_digits = format_digits;
gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
{
g_return_val_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc), NULL);
- return gl_text_node_dup (lbc->private->text_node);
+ return gl_text_node_dup (lbc->priv->text_node);
}
void
{
g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
- *id = g_strdup (lbc->private->id);
- *text_flag = lbc->private->text_flag;
- *checksum_flag = lbc->private->checksum_flag;
- *format_digits = lbc->private->format_digits;
+ *id = g_strdup (lbc->priv->id);
+ *text_flag = lbc->priv->text_flag;
+ *checksum_flag = lbc->priv->checksum_flag;
+ *format_digits = lbc->priv->format_digits;
}
/*---------------------------------------------------------------------------*/
g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
- (* parent_class->get_size) (object, &w_parent, &h_parent);
+ gl_label_object_get_raw_size (object, &w_parent, &h_parent);
-
- if (lbc->private->text_node->field_flag) {
- data = gl_barcode_default_digits (lbc->private->id,
- lbc->private->format_digits);
+ if (lbc->priv->text_node->field_flag) {
+ data = gl_barcode_default_digits (lbc->priv->id,
+ lbc->priv->format_digits);
} else {
- data = gl_text_node_expand (lbc->private->text_node, NULL);
+ data = gl_text_node_expand (lbc->priv->text_node, NULL);
}
- gbc = gl_barcode_new (lbc->private->id,
- lbc->private->text_flag,
- lbc->private->checksum_flag,
+ gbc = gl_barcode_new (lbc->priv->id,
+ lbc->priv->text_flag,
+ lbc->priv->checksum_flag,
w_parent,
h_parent,
data);
+ g_free (data);
if ( gbc == NULL ) {
/* Try again with default digits. */
- data = gl_barcode_default_digits (lbc->private->id,
- lbc->private->format_digits);
- gbc = gl_barcode_new (lbc->private->id,
- lbc->private->text_flag,
- lbc->private->checksum_flag,
+ data = gl_barcode_default_digits (lbc->priv->id,
+ lbc->priv->format_digits);
+ gbc = gl_barcode_new (lbc->priv->id,
+ lbc->priv->text_flag,
+ lbc->priv->checksum_flag,
w_parent,
h_parent,
data);
+ g_free (data);
}
- *w = gbc->width;
- *h = gbc->height;
+ if ( gbc != NULL )
+ {
+ *w = gbc->width;
+ *h = gbc->height;
+ }
+ else
+ {
+ /* If we still can't render, just set a default size. */
+ *w = 144;
+ *h = 72;
+ }
gl_barcode_free (&gbc);
- g_free (data);
gl_debug (DEBUG_LABEL, "END");
}
g_return_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode));
- if ( !gl_color_node_equal(lbarcode->private->color_node, line_color_node) ) {
+ if ( !gl_color_node_equal(lbarcode->priv->color_node, line_color_node) ) {
- gl_color_node_free (&(lbarcode->private->color_node));
- lbarcode->private->color_node = gl_color_node_dup (line_color_node);
+ gl_color_node_free (&(lbarcode->priv->color_node));
+ lbarcode->priv->color_node = gl_color_node_dup (line_color_node);
gl_label_object_emit_changed (GL_LABEL_OBJECT(lbarcode));
}
}
{
glLabelBarcode *lbarcode = (glLabelBarcode *)object;
- g_return_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode));
+ g_return_val_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode), NULL);
- return gl_color_node_dup (lbarcode->private->color_node);
+ return gl_color_node_dup (lbarcode->priv->color_node);
}
+
+/*****************************************************************************/
+/* Draw object method. */
+/*****************************************************************************/
+static void
+draw_object (glLabelObject *object,
+ cairo_t *cr,
+ gboolean screen_flag,
+ glMergeRecord *record)
+{
+ gdouble x0, y0;
+ cairo_matrix_t matrix;
+ glBarcode *gbc;
+ glBarcodeLine *line;
+ glBarcodeChar *bchar;
+ GList *li;
+ gdouble y_offset;
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ gchar *text, *cstring;
+ glTextNode *text_node;
+ gchar *id;
+ gboolean text_flag;
+ gboolean checksum_flag;
+ guint color;
+ glColorNode *color_node;
+ guint format_digits;
+ gdouble w, h;
+
+ gl_debug (DEBUG_LABEL, "START");
+
+ gl_label_object_get_position (object, &x0, &y0);
+ gl_label_object_get_matrix (object, &matrix);
+
+ text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE (object));
+ gl_label_barcode_get_props (GL_LABEL_BARCODE (object),
+ &id, &text_flag, &checksum_flag, &format_digits);
+
+ color_node = gl_label_object_get_line_color (object);
+ color = gl_color_node_expand (color_node, record);
+ if (color_node->field_flag && screen_flag)
+ {
+ color = GL_COLOR_MERGE_DEFAULT;
+ }
+ gl_color_node_free (&color_node);
+
+ gl_label_object_get_size (object, &w, &h);
+
+ text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
+ text = gl_text_node_expand (text_node, record);
+ if (text_node->field_flag && screen_flag) {
+ text = gl_barcode_default_digits (id, format_digits);
+ }
+
+ gbc = gl_barcode_new (id, text_flag, checksum_flag, w, h, text);
+
+ cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color));
+
+ if (gbc == NULL) {
+
+ 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, 12 * PANGO_SCALE * FONT_SCALE);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+
+ if (text == NULL || *text == '\0')
+ {
+ pango_layout_set_text (layout, _("Barcode data empty"), -1);
+ }
+ else
+ {
+ pango_layout_set_text (layout, _("Invalid barcode data"), -1);
+ }
+
+ cairo_move_to (cr, 0, 0);
+ pango_cairo_show_layout (cr, layout);
+
+ g_object_unref (layout);
+
+ } else {
+
+ for (li = gbc->lines; li != NULL; li = li->next) {
+ line = (glBarcodeLine *) li->data;
+
+ cairo_move_to (cr, line->x, line->y);
+ cairo_line_to (cr, line->x, line->y + line->length);
+ cairo_set_line_width (cr, line->width);
+ cairo_stroke (cr);
+ }
+
+ for (li = gbc->chars; li != NULL; li = li->next) {
+ bchar = (glBarcodeChar *) li->data;
+
+ 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, bchar->fsize * PANGO_SCALE * FONT_SCALE);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+
+ cstring = g_strdup_printf ("%c", bchar->c);
+ pango_layout_set_text (layout, cstring, -1);
+ g_free (cstring);
+
+ y_offset = 0.2 * bchar->fsize;
+
+ cairo_move_to (cr, bchar->x, bchar->y-y_offset);
+ pango_cairo_show_layout (cr, layout);
+
+ g_object_unref (layout);
+
+ }
+
+ gl_barcode_free (&gbc);
+
+ }
+
+ g_free (text);
+ gl_text_node_free (&text_node);
+ g_free (id);
+
+ gl_debug (DEBUG_LABEL, "END");
+}
+