3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "label-barcode.h"
26 #include <glib/gi18n.h>
27 #include <pango/pangocairo.h>
32 /*========================================================*/
33 /* Private macros and constants. */
34 /*========================================================*/
36 #define FONT_SCALE (72.0/96.0)
39 /*========================================================*/
41 /*========================================================*/
43 struct _glLabelBarcodePrivate {
44 glTextNode *text_node;
46 glColorNode *color_node;
48 gboolean checksum_flag;
53 /*========================================================*/
54 /* Private globals. */
55 /*========================================================*/
58 /*========================================================*/
59 /* Private function prototypes. */
60 /*========================================================*/
62 static void gl_label_barcode_finalize (GObject *object);
64 static void copy (glLabelObject *dst_object,
65 glLabelObject *src_object);
67 static void get_size (glLabelObject *object,
71 static void set_line_color (glLabelObject *object,
72 glColorNode *line_color,
75 static glColorNode *get_line_color (glLabelObject *object);
77 static void draw_object (glLabelObject *object,
80 glMergeRecord *record);
82 static gboolean object_at (glLabelObject *object,
88 /*****************************************************************************/
89 /* Boilerplate object stuff. */
90 /*****************************************************************************/
91 G_DEFINE_TYPE (glLabelBarcode, gl_label_barcode, GL_TYPE_LABEL_OBJECT);
95 gl_label_barcode_class_init (glLabelBarcodeClass *class)
97 GObjectClass *object_class = G_OBJECT_CLASS (class);
98 glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
100 gl_label_barcode_parent_class = g_type_class_peek_parent (class);
102 label_object_class->copy = copy;
103 label_object_class->get_size = get_size;
104 label_object_class->set_line_color = set_line_color;
105 label_object_class->get_line_color = get_line_color;
106 label_object_class->draw_object = draw_object;
107 label_object_class->draw_shadow = NULL;
108 label_object_class->object_at = object_at;
110 object_class->finalize = gl_label_barcode_finalize;
115 gl_label_barcode_init (glLabelBarcode *lbc)
117 lbc->priv = g_new0 (glLabelBarcodePrivate, 1);
118 lbc->priv->text_node = gl_text_node_new_from_text ("");
123 gl_label_barcode_finalize (GObject *object)
125 glLabelBarcode *lbc = GL_LABEL_BARCODE (object);
127 g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
129 gl_text_node_free (&lbc->priv->text_node);
130 g_free (lbc->priv->id);
131 gl_color_node_free (&(lbc->priv->color_node));
134 G_OBJECT_CLASS (gl_label_barcode_parent_class)->finalize (object);
138 /*****************************************************************************/
139 /* NEW label "barcode" object. */
140 /*****************************************************************************/
142 gl_label_barcode_new (glLabel *label,
146 glColorNode *line_color_node;
148 lbc = g_object_new (gl_label_barcode_get_type(), NULL);
154 gl_label_checkpoint (label, _("Create barcode object"));
157 line_color_node = gl_color_node_new_default ();
159 line_color_node->color = gl_label_get_default_line_color(label);
161 lbc->priv->color_node = line_color_node;
163 gl_label_add_object (label, GL_LABEL_OBJECT (lbc));
164 gl_label_object_set_parent (GL_LABEL_OBJECT (lbc), label);
167 return G_OBJECT (lbc);
171 /*****************************************************************************/
172 /* Copy object contents. */
173 /*****************************************************************************/
175 copy (glLabelObject *dst_object,
176 glLabelObject *src_object)
178 glLabelBarcode *lbc = (glLabelBarcode *)src_object;
179 glLabelBarcode *new_lbc = (glLabelBarcode *)dst_object;
180 glTextNode *text_node;
183 gboolean checksum_flag;
184 glColorNode *color_node;
187 gl_debug (DEBUG_LABEL, "START");
189 g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
190 g_return_if_fail (new_lbc && GL_IS_LABEL_BARCODE (new_lbc));
192 text_node = gl_label_barcode_get_data (lbc);
193 gl_label_barcode_get_props (lbc, &id, &text_flag, &checksum_flag, &format_digits);
194 color_node = get_line_color (src_object);
196 gl_label_barcode_set_data (new_lbc, text_node, FALSE);
197 gl_label_barcode_set_props (new_lbc, id, text_flag, checksum_flag, format_digits, FALSE);
198 set_line_color (dst_object, color_node, FALSE);
200 gl_color_node_free (&color_node);
201 gl_text_node_free (&text_node);
204 gl_debug (DEBUG_LABEL, "END");
208 /*****************************************************************************/
209 /* Set object params. */
210 /*****************************************************************************/
212 gl_label_barcode_set_data (glLabelBarcode *lbc,
213 glTextNode *text_node,
218 gl_debug (DEBUG_LABEL, "START");
220 g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
222 if (!gl_text_node_equal (lbc->priv->text_node, text_node))
226 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbc));
227 gl_label_checkpoint (label, _("Barcode data"));
230 gl_text_node_free (&lbc->priv->text_node);
231 lbc->priv->text_node = gl_text_node_dup (text_node);
233 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
236 gl_debug (DEBUG_LABEL, "END");
241 gl_label_barcode_set_props (glLabelBarcode *lbc,
244 gboolean checksum_flag,
250 gl_debug (DEBUG_LABEL, "START");
252 g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
254 if ( ((lbc->priv->id == NULL) && (id != NULL))
255 || ((lbc->priv->id != NULL) && (id != NULL) && (g_ascii_strcasecmp (lbc->priv->id, id) != 0))
256 || (lbc->priv->text_flag != text_flag)
257 || (lbc->priv->checksum_flag != checksum_flag)
258 || (lbc->priv->format_digits != format_digits))
262 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbc));
263 gl_label_checkpoint (label, _("Barcode property"));
266 lbc->priv->id = g_strdup (id);
267 lbc->priv->text_flag = text_flag;
268 lbc->priv->checksum_flag = checksum_flag;
269 lbc->priv->format_digits = format_digits;
271 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
274 gl_debug (DEBUG_LABEL, "END");
278 /*****************************************************************************/
279 /* Get object params. */
280 /*****************************************************************************/
282 gl_label_barcode_get_data (glLabelBarcode *lbc)
284 g_return_val_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc), NULL);
286 return gl_text_node_dup (lbc->priv->text_node);
291 gl_label_barcode_get_props (glLabelBarcode *lbc,
294 gboolean *checksum_flag,
295 guint *format_digits)
297 g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
299 *id = g_strdup (lbc->priv->id);
300 *text_flag = lbc->priv->text_flag;
301 *checksum_flag = lbc->priv->checksum_flag;
302 *format_digits = lbc->priv->format_digits;
306 /*---------------------------------------------------------------------------*/
307 /* PRIVATE. Get object size method. */
308 /*---------------------------------------------------------------------------*/
310 get_size (glLabelObject *object,
314 glLabelBarcode *lbc = (glLabelBarcode *)object;
316 gdouble w_parent, h_parent;
319 gl_debug (DEBUG_LABEL, "START");
321 g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
323 gl_label_object_get_raw_size (object, &w_parent, &h_parent);
325 if (lbc->priv->text_node->field_flag) {
326 data = gl_barcode_default_digits (lbc->priv->id,
327 lbc->priv->format_digits);
329 data = gl_text_node_expand (lbc->priv->text_node, NULL);
332 gbc = gl_barcode_new (lbc->priv->id,
333 lbc->priv->text_flag,
334 lbc->priv->checksum_flag,
341 /* Try again with default digits. */
342 data = gl_barcode_default_digits (lbc->priv->id,
343 lbc->priv->format_digits);
344 gbc = gl_barcode_new (lbc->priv->id,
345 lbc->priv->text_flag,
346 lbc->priv->checksum_flag,
360 /* If we still can't render, just set a default size. */
365 gl_barcode_free (&gbc);
367 gl_debug (DEBUG_LABEL, "END");
371 /*---------------------------------------------------------------------------*/
372 /* PRIVATE. Set line color method. */
373 /*---------------------------------------------------------------------------*/
375 set_line_color (glLabelObject *object,
376 glColorNode *line_color_node,
379 glLabelBarcode *lbarcode = (glLabelBarcode *)object;
382 g_return_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode));
384 if ( !gl_color_node_equal(lbarcode->priv->color_node, line_color_node) )
388 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbarcode));
389 gl_label_checkpoint (label, _("Barcode data"));
392 gl_color_node_free (&(lbarcode->priv->color_node));
393 lbarcode->priv->color_node = gl_color_node_dup (line_color_node);
394 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbarcode));
399 /*---------------------------------------------------------------------------*/
400 /* PRIVATE. Get line color method. */
401 /*---------------------------------------------------------------------------*/
403 get_line_color (glLabelObject *object)
405 glLabelBarcode *lbarcode = (glLabelBarcode *)object;
407 g_return_val_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode), NULL);
409 return gl_color_node_dup (lbarcode->priv->color_node);
413 /*****************************************************************************/
414 /* Draw object method. */
415 /*****************************************************************************/
417 draw_object (glLabelObject *object,
419 gboolean screen_flag,
420 glMergeRecord *record)
423 cairo_matrix_t matrix;
425 glBarcodeShape *shape;
426 glBarcodeShapeLine *line;
427 glBarcodeShapeAlpha *bchar;
431 PangoFontDescription *desc;
432 gchar *text, *cstring;
433 glTextNode *text_node;
436 gboolean checksum_flag;
438 glColorNode *color_node;
442 gl_debug (DEBUG_LABEL, "START");
444 gl_label_object_get_position (object, &x0, &y0);
445 gl_label_object_get_matrix (object, &matrix);
447 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE (object));
448 gl_label_barcode_get_props (GL_LABEL_BARCODE (object),
449 &id, &text_flag, &checksum_flag, &format_digits);
451 color_node = gl_label_object_get_line_color (object);
452 color = gl_color_node_expand (color_node, record);
453 if (color_node->field_flag && screen_flag)
455 color = GL_COLOR_MERGE_DEFAULT;
457 gl_color_node_free (&color_node);
459 gl_label_object_get_size (object, &w, &h);
461 text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
462 text = gl_text_node_expand (text_node, record);
463 if (text_node->field_flag && screen_flag) {
464 text = gl_barcode_default_digits (id, format_digits);
467 gbc = gl_barcode_new (id, text_flag, checksum_flag, w, h, text);
469 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color));
473 layout = pango_cairo_create_layout (cr);
475 desc = pango_font_description_new ();
476 pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
477 pango_font_description_set_size (desc, 12 * PANGO_SCALE * FONT_SCALE);
478 pango_layout_set_font_description (layout, desc);
479 pango_font_description_free (desc);
481 if (text == NULL || *text == '\0')
483 pango_layout_set_text (layout, _("Barcode data empty"), -1);
487 pango_layout_set_text (layout, _("Invalid barcode data"), -1);
490 cairo_move_to (cr, 0, 0);
491 pango_cairo_show_layout (cr, layout);
493 g_object_unref (layout);
497 for (p = gbc->shapes; p != NULL; p = p->next) {
498 shape = (glBarcodeShape *)p->data;
502 case GL_BARCODE_SHAPE_LINE:
503 line = (glBarcodeShapeLine *) shape;
505 cairo_move_to (cr, line->x, line->y);
506 cairo_line_to (cr, line->x, line->y + line->length);
507 cairo_set_line_width (cr, line->width);
512 case GL_BARCODE_SHAPE_ALPHA:
513 bchar = (glBarcodeShapeAlpha *) shape;
515 layout = pango_cairo_create_layout (cr);
517 desc = pango_font_description_new ();
518 pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
519 pango_font_description_set_size (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
520 pango_layout_set_font_description (layout, desc);
521 pango_font_description_free (desc);
523 cstring = g_strdup_printf ("%c", bchar->c);
524 pango_layout_set_text (layout, cstring, -1);
527 y_offset = 0.2 * bchar->fsize;
529 cairo_move_to (cr, bchar->x, bchar->y-y_offset);
530 pango_cairo_show_layout (cr, layout);
532 g_object_unref (layout);
537 g_assert_not_reached ();
544 gl_barcode_free (&gbc);
549 gl_text_node_free (&text_node);
552 gl_debug (DEBUG_LABEL, "END");
556 /*****************************************************************************/
557 /* Is object at coordinates? */
558 /*****************************************************************************/
560 object_at (glLabelObject *object,
567 gl_label_object_get_size (object, &w, &h);
570 cairo_rectangle (cr, 0.0, 0.0, w, h);
572 if (cairo_in_fill (cr, x, y))
584 * Local Variables: -- emacs
586 * c-basic-offset: 8 -- emacs
587 * tab-width: 8 -- emacs
588 * indent-tabs-mode: nil -- emacs