]> git.sur5r.net Git - glabels/blob - src/label-barcode.c
Some optimization of barcode updates.
[glabels] / src / label-barcode.c
1 /*
2  *  label-barcode.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
23 #include "label-barcode.h"
24
25 #include <glib.h>
26 #include <glib/gi18n.h>
27 #include <pango/pangocairo.h>
28 #include "bc-backends.h"
29
30 #include "debug.h"
31
32 /*========================================================*/
33 /* Private macros and constants.                          */
34 /*========================================================*/
35
36 #define FONT_SCALE (72.0/96.0)
37 #define PI 3.141592654
38
39 #define GL_BARCODE_FONT_FAMILY      "Sans"
40
41 #define HANDLE_OUTLINE_RGBA_ARGS   0.5,   0.5,   0.5,   0.75
42 #define HANDLE_OUTLINE_WIDTH_PIXELS   2.0
43
44 #define SELECTION_SLOP_PIXELS 4.0
45
46
47 /*========================================================*/
48 /* Private types.                                         */
49 /*========================================================*/
50
51 struct _glLabelBarcodePrivate {
52
53         glTextNode          *text_node;
54         glLabelBarcodeStyle *style;
55         glColorNode         *color_node;
56
57         /* Cached info.  Only regenerate when text_node,
58          * style, or raw size changed */
59         lglBarcode          *display_gbc;
60         gdouble              w, h;
61
62 };
63
64
65 /*========================================================*/
66 /* Private globals.                                       */
67 /*========================================================*/
68
69
70 /*========================================================*/
71 /* Private function prototypes.                           */
72 /*========================================================*/
73
74 static void  gl_label_barcode_finalize      (GObject             *object);
75
76 static void  copy                           (glLabelObject       *dst_object,
77                                              glLabelObject       *src_object);
78
79 static void  update_barcode                 (glLabelBarcode      *lbc);
80
81 static void  set_size                       (glLabelObject       *object,
82                                              gdouble              w,
83                                              gdouble              h,
84                                              gboolean             checkpoint);
85
86 static void  get_size                       (glLabelObject       *object,
87                                              gdouble             *w,
88                                              gdouble             *h);
89
90 static void  set_line_color                 (glLabelObject       *object,
91                                              glColorNode         *line_color,
92                                              gboolean             checkpoint);
93
94 static glColorNode *get_line_color          (glLabelObject       *object);
95
96 static void     draw_object                 (glLabelObject       *object,
97                                              cairo_t             *cr,
98                                              gboolean             screen_flag,
99                                              glMergeRecord       *record);
100
101 static gboolean object_at                   (glLabelObject       *object,
102                                              cairo_t             *cr,
103                                              gdouble              x_pixels,
104                                              gdouble              y_pixels);
105
106 static void     draw_handles                (glLabelObject       *object,
107                                              cairo_t             *cr);
108
109 static void     create_alt_msg_path         (cairo_t             *cr,
110                                              gchar               *text);
111
112
113 /*****************************************************************************/
114 /* Boilerplate object stuff.                                                 */
115 /*****************************************************************************/
116 G_DEFINE_TYPE (glLabelBarcode, gl_label_barcode, GL_TYPE_LABEL_OBJECT);
117
118
119 static void
120 gl_label_barcode_class_init (glLabelBarcodeClass *class)
121 {
122         GObjectClass       *object_class       = G_OBJECT_CLASS (class);
123         glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
124
125         gl_label_barcode_parent_class = g_type_class_peek_parent (class);
126
127         label_object_class->copy           = copy;
128         label_object_class->set_size       = set_size;
129         label_object_class->get_size       = get_size;
130         label_object_class->set_line_color = set_line_color;
131         label_object_class->get_line_color = get_line_color;
132         label_object_class->draw_object    = draw_object;
133         label_object_class->draw_shadow    = NULL;
134         label_object_class->object_at      = object_at;
135         label_object_class->draw_handles   = draw_handles;
136
137         object_class->finalize = gl_label_barcode_finalize;
138 }
139
140
141 static void
142 gl_label_barcode_init (glLabelBarcode *lbc)
143 {
144         lbc->priv = g_new0 (glLabelBarcodePrivate, 1);
145         lbc->priv->text_node  = gl_text_node_new_from_text ("");
146 }
147
148
149 static void
150 gl_label_barcode_finalize (GObject *object)
151 {
152         glLabelBarcode *lbc = GL_LABEL_BARCODE (object);
153
154         g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
155
156         gl_text_node_free (&lbc->priv->text_node);
157         gl_label_barcode_style_free (lbc->priv->style);
158         gl_color_node_free (&(lbc->priv->color_node));
159         lgl_barcode_free (lbc->priv->display_gbc);
160         g_free (lbc->priv);
161
162         G_OBJECT_CLASS (gl_label_barcode_parent_class)->finalize (object);
163 }
164
165
166 /*****************************************************************************/
167 /* NEW label "barcode" object.                                               */
168 /*****************************************************************************/
169 GObject *
170 gl_label_barcode_new (glLabel *label,
171                       gboolean checkpoint)
172 {
173         glLabelBarcode      *lbc;
174         glLabelBarcodeStyle *style;
175         glColorNode         *line_color_node;
176
177         lbc = g_object_new (gl_label_barcode_get_type(), NULL);
178
179         if (label != NULL)
180         {
181                 if ( checkpoint )
182                 {
183                         gl_label_checkpoint (label, _("Create barcode object"));
184                 }
185
186                 /* Default barcode style and properties. */
187                 style = gl_label_barcode_style_new ();
188                 gl_label_barcode_style_set_backend_id (style, gl_barcode_backends_backend_name_to_id (NULL));
189                 gl_label_barcode_style_set_style_id (style, gl_barcode_backends_style_name_to_id (style->backend_id, NULL));
190                 style->text_flag     = gl_barcode_backends_style_can_text (style->backend_id, style->id);
191                 style->checksum_flag = gl_barcode_backends_style_can_csum (style->backend_id, style->id);
192                 style->format_digits = gl_barcode_backends_style_get_prefered_n (style->backend_id, style->id);
193                 lbc->priv->style = style;
194                 update_barcode (lbc);
195
196                 line_color_node = gl_color_node_new_default ();
197                 line_color_node->color = gl_label_get_default_line_color(label);
198                 lbc->priv->color_node = line_color_node;
199
200                 gl_label_add_object (label, GL_LABEL_OBJECT (lbc));
201                 gl_label_object_set_parent (GL_LABEL_OBJECT (lbc), label);
202         }
203
204         return G_OBJECT (lbc);
205 }
206
207
208 /*****************************************************************************/
209 /* Copy object contents.                                                     */
210 /*****************************************************************************/
211 static void
212 copy (glLabelObject *dst_object,
213       glLabelObject *src_object)
214 {
215         glLabelBarcode      *lbc     = (glLabelBarcode *)src_object;
216         glLabelBarcode      *new_lbc = (glLabelBarcode *)dst_object;
217         glTextNode          *text_node;
218         glLabelBarcodeStyle *style;
219         glColorNode         *color_node;
220
221         gl_debug (DEBUG_LABEL, "START");
222
223         g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
224         g_return_if_fail (new_lbc && GL_IS_LABEL_BARCODE (new_lbc));
225
226         text_node = gl_label_barcode_get_data (lbc);
227         style = gl_label_barcode_get_style (lbc);
228         color_node = get_line_color (src_object);
229
230         new_lbc->priv->text_node  = text_node;
231         new_lbc->priv->style      = style;
232         new_lbc->priv->color_node = color_node;
233
234         update_barcode (new_lbc);
235
236         gl_debug (DEBUG_LABEL, "END");
237 }
238
239
240 /*****************************************************************************/
241 /* Set object params.                                                        */
242 /*****************************************************************************/
243 void
244 gl_label_barcode_set_data (glLabelBarcode   *lbc,
245                            const glTextNode *text_node,
246                            gboolean          checkpoint)
247 {
248         glLabel *label;
249
250         gl_debug (DEBUG_LABEL, "START");
251
252         g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
253
254         if (!gl_text_node_equal (lbc->priv->text_node, text_node))
255         {
256                 if ( checkpoint )
257                 {
258                         label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbc));
259                         gl_label_checkpoint (label, _("Barcode data"));
260                 }
261                 
262                 gl_text_node_free (&lbc->priv->text_node);
263                 lbc->priv->text_node = gl_text_node_dup (text_node);
264
265                 update_barcode (lbc);
266
267                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
268         }
269
270         gl_debug (DEBUG_LABEL, "END");
271 }
272
273
274 void
275 gl_label_barcode_set_style (glLabelBarcode            *lbc,
276                             const glLabelBarcodeStyle *style,
277                             gboolean                   checkpoint)
278 {
279         glLabel *label;
280
281         gl_debug (DEBUG_LABEL, "START");
282
283         g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
284
285         if ( !gl_label_barcode_style_is_equal (style, lbc->priv->style) )
286         {
287                 if ( checkpoint )
288                 {
289                         label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbc));
290                         gl_label_checkpoint (label, _("Barcode property"));
291                 }
292
293                 gl_label_barcode_style_free (lbc->priv->style);
294                 lbc->priv->style = gl_label_barcode_style_dup (style);
295
296                 update_barcode (lbc);
297
298                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbc));
299         }
300
301         gl_debug (DEBUG_LABEL, "END");
302 }
303
304
305 /*****************************************************************************/
306 /* Get object params.                                                        */
307 /*****************************************************************************/
308 glTextNode *
309 gl_label_barcode_get_data (glLabelBarcode *lbc)
310 {
311         g_return_val_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc), NULL);
312
313         return gl_text_node_dup (lbc->priv->text_node);
314 }
315
316
317 glLabelBarcodeStyle *
318 gl_label_barcode_get_style (glLabelBarcode *lbc)
319 {
320         g_return_val_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc), NULL);
321
322         return gl_label_barcode_style_dup (lbc->priv->style);
323 }
324
325
326 /*---------------------------------------------------------------------------*/
327 /* PRIVATE.  Update cached lglBarcode.                                       */
328 /*---------------------------------------------------------------------------*/
329 static void
330 update_barcode (glLabelBarcode *lbc)
331 {
332         gdouble              w_raw, h_raw;
333         gchar               *data;
334
335         gl_debug (DEBUG_LABEL, "START");
336
337         g_return_if_fail (lbc && GL_IS_LABEL_BARCODE (lbc));
338
339         gl_label_object_get_raw_size (GL_LABEL_OBJECT (lbc), &w_raw, &h_raw);
340
341         lgl_barcode_free (lbc->priv->display_gbc);
342
343         if (lbc->priv->text_node->field_flag)
344         {
345                 data = gl_barcode_backends_style_default_digits (lbc->priv->style->backend_id,
346                                                                  lbc->priv->style->id,
347                                                                  lbc->priv->style->format_digits);
348         }
349         else
350         {
351                 data = gl_text_node_expand (lbc->priv->text_node, NULL);
352         }
353
354         lbc->priv->display_gbc = gl_barcode_backends_new_barcode (lbc->priv->style->backend_id,
355                                                                   lbc->priv->style->id,
356                                                                   lbc->priv->style->text_flag,
357                                                                   lbc->priv->style->checksum_flag,
358                                                                   w_raw,
359                                                                   h_raw,
360                                                                   data);
361         g_free (data);
362
363         if ( lbc->priv->display_gbc == NULL )
364         {
365                 lglBarcode *gbc;
366
367                 /* Try again with default digits, but don't save -- just extract size. */
368                 data = gl_barcode_backends_style_default_digits (lbc->priv->style->backend_id,
369                                                                  lbc->priv->style->id,
370                                                                  lbc->priv->style->format_digits);
371                 gbc = gl_barcode_backends_new_barcode (lbc->priv->style->backend_id,
372                                                        lbc->priv->style->id,
373                                                        lbc->priv->style->text_flag,
374                                                        lbc->priv->style->checksum_flag,
375                                                        w_raw,
376                                                        h_raw,
377                                                        data);
378                 g_free (data);
379
380                 if ( gbc != NULL )
381                 {
382                         lbc->priv->w = gbc->width;
383                         lbc->priv->h = gbc->height;
384                 }
385                 else
386                 {
387                         /* If we still can't render, just set a default size. */
388                         lbc->priv->w = 144;
389                         lbc->priv->h = 72;
390                 }
391
392                 lgl_barcode_free (gbc);
393         }
394         else
395         {
396                 lbc->priv->w = lbc->priv->display_gbc->width;
397                 lbc->priv->h = lbc->priv->display_gbc->height;
398         }
399
400         gl_debug (DEBUG_LABEL, "END");
401 }
402
403
404 /*---------------------------------------------------------------------------*/
405 /* PRIVATE.  Set object size method.                                         */
406 /*---------------------------------------------------------------------------*/
407 static void
408 set_size (glLabelObject       *object,
409           gdouble              w,
410           gdouble              h,
411           gboolean             checkpoint)
412 {
413         gl_debug (DEBUG_LABEL, "START");
414
415         g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
416
417         gl_label_object_set_raw_size (object, w, h, checkpoint);
418         update_barcode (GL_LABEL_BARCODE (object));
419
420         gl_debug (DEBUG_LABEL, "END");
421 }
422
423
424 /*---------------------------------------------------------------------------*/
425 /* PRIVATE.  Get object size method.                                         */
426 /*---------------------------------------------------------------------------*/
427 static void
428 get_size (glLabelObject *object,
429           gdouble       *w,
430           gdouble       *h)
431 {
432         gl_debug (DEBUG_LABEL, "START");
433
434         g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
435
436         *w = GL_LABEL_BARCODE (object)->priv->w;
437         *h = GL_LABEL_BARCODE (object)->priv->h;
438
439         gl_debug (DEBUG_LABEL, "END");
440 }
441
442
443 /*---------------------------------------------------------------------------*/
444 /* PRIVATE.  Set line color method.                                          */
445 /*---------------------------------------------------------------------------*/
446 static void
447 set_line_color (glLabelObject *object,
448                 glColorNode   *line_color_node,
449                 gboolean       checkpoint)
450 {
451         glLabelBarcode *lbarcode = (glLabelBarcode *)object;
452         glLabel        *label;
453
454         g_return_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode));
455
456         if ( !gl_color_node_equal(lbarcode->priv->color_node, line_color_node) )
457         {
458                 if ( checkpoint )
459                 {
460                         label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbarcode));
461                         gl_label_checkpoint (label, _("Barcode data"));
462                 }
463
464                 gl_color_node_free (&(lbarcode->priv->color_node));
465                 lbarcode->priv->color_node = gl_color_node_dup (line_color_node);
466                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbarcode));
467         }
468 }
469
470
471 /*---------------------------------------------------------------------------*/
472 /* PRIVATE.  Get line color method.                                          */
473 /*---------------------------------------------------------------------------*/
474 static glColorNode*
475 get_line_color (glLabelObject *object)
476 {
477         glLabelBarcode *lbarcode = (glLabelBarcode *)object;
478
479         g_return_val_if_fail (lbarcode && GL_IS_LABEL_BARCODE (lbarcode), NULL);
480
481         return gl_color_node_dup (lbarcode->priv->color_node);
482 }
483
484
485 /*****************************************************************************/
486 /* Draw object method.                                                       */
487 /*****************************************************************************/
488 static void
489 draw_object (glLabelObject *object,
490              cairo_t       *cr,
491              gboolean       screen_flag,
492              glMergeRecord *record)
493 {
494         glLabelBarcode       *lbc     = (glLabelBarcode *)object;
495         gdouble               x0, y0;
496         cairo_matrix_t        matrix;
497         lglBarcode           *gbc;
498         gchar                *text;
499         glTextNode           *text_node;
500         glLabelBarcodeStyle  *style;
501         guint                 color;
502         glColorNode          *color_node;
503         gdouble               w, h;
504
505         gl_debug (DEBUG_LABEL, "START");
506
507         gl_label_object_get_position (object, &x0, &y0);
508         gl_label_object_get_matrix (object, &matrix);
509
510         text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE (object));
511         style = gl_label_barcode_get_style (GL_LABEL_BARCODE (object));
512
513         color_node = gl_label_object_get_line_color (object);
514         color = gl_color_node_expand (color_node, record);
515         if (color_node->field_flag && screen_flag)
516         {
517                 color = GL_COLOR_MERGE_DEFAULT;
518         }
519
520         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color));
521
522         if (text_node->field_flag && !screen_flag) {
523
524                 gl_label_object_get_raw_size (object, &w, &h);
525
526                 text = gl_text_node_expand (text_node, record);
527                 gbc = gl_barcode_backends_new_barcode (style->backend_id, style->id, style->text_flag, style->checksum_flag, w, h, text);
528                 g_free (text);
529
530                 if ( gbc != NULL )
531                 {
532                         lgl_barcode_render_to_cairo (gbc, cr);
533                         lgl_barcode_free (gbc);
534                 }
535
536         }
537         else
538         {
539
540                 if (lbc->priv->display_gbc == NULL)
541                 {
542                         create_alt_msg_path (cr, text_node->data);
543                         cairo_fill (cr);
544                 }
545                 else
546                 {
547                         lgl_barcode_render_to_cairo (lbc->priv->display_gbc, cr);
548                         lgl_barcode_free (gbc);
549                 }
550
551         }
552
553         gl_text_node_free (&text_node);
554         gl_label_barcode_style_free (style);
555         gl_color_node_free (&color_node);
556
557         gl_debug (DEBUG_LABEL, "END");
558 }
559
560
561 /*****************************************************************************/
562 /* Is object at coordinates?                                                 */
563 /*****************************************************************************/
564 static gboolean
565 object_at (glLabelObject *object,
566            cairo_t       *cr,
567            gdouble        x,
568            gdouble        y)
569 {
570         glLabelBarcode       *lbc     = (glLabelBarcode *)object;
571         gdouble               w, h;
572         lglBarcode           *gbc;
573         glLabelBarcodeStyle  *style;
574         glTextNode           *text_node;
575         gchar                *text;
576         gdouble               scale_x, scale_y;
577
578         gl_label_object_get_size (object, &w, &h);
579
580         if ( (x >= 0) && (x <= w) && (y >= 0) && (y <= h) )
581         {
582
583                 text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
584
585                 if ( lbc->priv->display_gbc == NULL )
586                 {
587                         create_alt_msg_path (cr, text_node->data);
588                 }
589                 else
590                 {
591                         lgl_barcode_render_to_cairo_path (lbc->priv->display_gbc, cr);
592                 }
593
594                 if (cairo_in_fill (cr, x, y))
595                 {
596                         return TRUE;
597                 }
598
599
600                 scale_x = 1.0;
601                 scale_y = 1.0;
602                 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
603
604                 cairo_set_line_width (cr, 2*SELECTION_SLOP_PIXELS*scale_x);
605
606                 if (cairo_in_stroke (cr, x, y))
607                 {
608                         return TRUE;
609                 }
610
611
612                 if (gl_label_object_is_selected (object))
613                 {
614                         cairo_new_path (cr);
615                         cairo_rectangle (cr, 0, 0, w, h);
616
617                         scale_x = 1.0;
618                         scale_y = 1.0;
619                         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
620
621                         cairo_set_line_width (cr, (HANDLE_OUTLINE_WIDTH_PIXELS + 2*SELECTION_SLOP_PIXELS)*scale_x);
622
623                         if (cairo_in_stroke (cr, x, y))
624                         {
625                                 return TRUE;
626                         }
627                 }
628
629         }
630
631         return FALSE;
632 }
633
634
635 /*****************************************************************************/
636 /* Draw barcode style handles.                                               */
637 /*****************************************************************************/
638 static void
639 draw_handles (glLabelObject     *object,
640               cairo_t           *cr)
641 {
642         gdouble w, h;
643         gdouble scale_x, scale_y;
644         gdouble dashes[2] = { 2, 2 };
645
646         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
647
648         cairo_save (cr);
649
650         cairo_rectangle (cr, 0, 0, w, h);
651
652         scale_x = 1.0;
653         scale_y = 1.0;
654         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
655         cairo_scale (cr, scale_x, scale_y);
656
657         cairo_set_dash (cr, dashes, 2, 0);
658         cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
659         cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
660         cairo_stroke (cr);
661
662         cairo_restore (cr);
663
664         gl_label_object_draw_handles_box (object, cr);
665 }
666
667
668 /*****************************************************************************/
669 /* Create a cairo path with apropos message.                                 */
670 /*****************************************************************************/
671 static void
672 create_alt_msg_path (cairo_t *cr,
673                      gchar   *text)
674 {
675         PangoLayout          *layout;
676         PangoFontDescription *desc;
677
678         layout = pango_cairo_create_layout (cr);
679
680         desc = pango_font_description_new ();
681         pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
682         pango_font_description_set_size   (desc, 12 * PANGO_SCALE * FONT_SCALE);
683         pango_layout_set_font_description (layout, desc);
684         pango_font_description_free       (desc);
685
686         if (text == NULL || *text == '\0')
687         {
688                 pango_layout_set_text (layout, _("Barcode data empty"), -1);
689         }
690         else
691         {
692                 pango_layout_set_text (layout, _("Invalid barcode data"), -1);
693         }
694
695         cairo_move_to (cr, 0, 0);
696         pango_cairo_layout_path (cr, layout);
697
698         g_object_unref (layout);
699 }
700
701
702 /*****************************************************************************/
703 /* Barcode style utilities.                                                  */
704 /*****************************************************************************/
705 glLabelBarcodeStyle *
706 gl_label_barcode_style_new (void)
707 {
708         return g_new0 (glLabelBarcodeStyle, 1);
709 }
710
711
712 glLabelBarcodeStyle *
713 gl_label_barcode_style_dup (const glLabelBarcodeStyle *style)
714 {
715         glLabelBarcodeStyle *style2;
716
717         style2 = gl_label_barcode_style_new ();
718
719         /* Shallow copy first. */
720         *style2 = *style;
721
722         /* Now go deep. */
723         style2->backend_id = g_strdup (style->backend_id);
724         style2->id         = g_strdup (style->id);
725
726         return style2;
727 }
728
729
730 void
731 gl_label_barcode_style_free (glLabelBarcodeStyle *style)
732 {
733         if ( style )
734         {
735                 g_free (style->backend_id);
736                 g_free (style->id);
737
738                 g_free (style);
739         }
740 }
741
742
743 gboolean
744 gl_label_barcode_style_is_equal (const glLabelBarcodeStyle *style1,
745                                  const glLabelBarcodeStyle *style2)
746 {
747
748         /* First take care of the case of either or both being NULL. */
749         if ( style1 == NULL )
750         {
751                 return ( style2 == NULL );
752         }
753         else
754         {
755                 if ( style2 == NULL )
756                 {
757                         return FALSE;
758                 }
759         }
760
761         /* Compare field by field, bail on first difference. */
762         if ( style1->text_flag != style2->text_flag )
763         {
764                 return FALSE;
765         }
766         if ( style1->checksum_flag != style2->checksum_flag )
767         {
768                 return FALSE;
769         }
770         if ( style1->format_digits != style2->format_digits )
771         {
772                 return FALSE;
773         }
774         if ( style1->backend_id && style2->backend_id )
775         {
776                 if ( strcmp (style1->backend_id, style2->backend_id) != 0 )
777                 {
778                         return FALSE;
779                 }
780         }
781         else
782         {
783                 if ( style1->backend_id != style2->backend_id )
784                 {
785                         return FALSE;
786                 }
787         }
788         if ( style1->id && style2->id )
789         {
790                 if ( strcmp (style1->id, style2->id) != 0 )
791                 {
792                         return FALSE;
793                 }
794         }
795         else
796         {
797                 if ( style1->id != style2->id )
798                 {
799                         return FALSE;
800                 }
801         }
802
803         /* Passed all tests. */
804         return TRUE;
805 }
806
807
808 void
809 gl_label_barcode_style_set_backend_id (glLabelBarcodeStyle *style,
810                                        const gchar         *backend_id)
811 {
812         style->backend_id = g_strdup (backend_id);
813 }
814
815
816 void
817 gl_label_barcode_style_set_style_id (glLabelBarcodeStyle *style,
818                                      const gchar         *id)
819 {
820         style->id = g_strdup (id);
821 }
822
823
824
825
826
827 /*
828  * Local Variables:       -- emacs
829  * mode: C                -- emacs
830  * c-basic-offset: 8      -- emacs
831  * tab-width: 8           -- emacs
832  * indent-tabs-mode: nil  -- emacs
833  * End:                   -- emacs
834  */