]> git.sur5r.net Git - glabels/blob - src/label-barcode.c
Added Sigel template
[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                 }
549
550         }
551
552         gl_text_node_free (&text_node);
553         gl_label_barcode_style_free (style);
554         gl_color_node_free (&color_node);
555
556         gl_debug (DEBUG_LABEL, "END");
557 }
558
559
560 /*****************************************************************************/
561 /* Is object at coordinates?                                                 */
562 /*****************************************************************************/
563 static gboolean
564 object_at (glLabelObject *object,
565            cairo_t       *cr,
566            gdouble        x,
567            gdouble        y)
568 {
569         glLabelBarcode       *lbc     = (glLabelBarcode *)object;
570         gdouble               w, h;
571         glTextNode           *text_node;
572         gdouble               scale_x, scale_y;
573
574         gl_label_object_get_size (object, &w, &h);
575
576         if ( (x >= 0) && (x <= w) && (y >= 0) && (y <= h) )
577         {
578
579                 text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
580
581                 if ( lbc->priv->display_gbc == NULL )
582                 {
583                         create_alt_msg_path (cr, text_node->data);
584                 }
585                 else
586                 {
587                         lgl_barcode_render_to_cairo_path (lbc->priv->display_gbc, cr);
588                 }
589
590                 if (cairo_in_fill (cr, x, y))
591                 {
592                         return TRUE;
593                 }
594
595
596                 scale_x = 1.0;
597                 scale_y = 1.0;
598                 cairo_device_to_user_distance (cr, &scale_x, &scale_y);
599
600                 cairo_set_line_width (cr, 2*SELECTION_SLOP_PIXELS*scale_x);
601
602                 if (cairo_in_stroke (cr, x, y))
603                 {
604                         return TRUE;
605                 }
606
607
608                 if (gl_label_object_is_selected (object))
609                 {
610                         cairo_new_path (cr);
611                         cairo_rectangle (cr, 0, 0, w, h);
612
613                         scale_x = 1.0;
614                         scale_y = 1.0;
615                         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
616
617                         cairo_set_line_width (cr, (HANDLE_OUTLINE_WIDTH_PIXELS + 2*SELECTION_SLOP_PIXELS)*scale_x);
618
619                         if (cairo_in_stroke (cr, x, y))
620                         {
621                                 return TRUE;
622                         }
623                 }
624
625         }
626
627         return FALSE;
628 }
629
630
631 /*****************************************************************************/
632 /* Draw barcode style handles.                                               */
633 /*****************************************************************************/
634 static void
635 draw_handles (glLabelObject     *object,
636               cairo_t           *cr)
637 {
638         gdouble w, h;
639         gdouble scale_x, scale_y;
640         gdouble dashes[2] = { 2, 2 };
641
642         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
643
644         cairo_save (cr);
645
646         cairo_rectangle (cr, 0, 0, w, h);
647
648         scale_x = 1.0;
649         scale_y = 1.0;
650         cairo_device_to_user_distance (cr, &scale_x, &scale_y);
651         cairo_scale (cr, scale_x, scale_y);
652
653         cairo_set_dash (cr, dashes, 2, 0);
654         cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
655         cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
656         cairo_stroke (cr);
657
658         cairo_restore (cr);
659
660         gl_label_object_draw_handles_box (object, cr);
661 }
662
663
664 /*****************************************************************************/
665 /* Create a cairo path with apropos message.                                 */
666 /*****************************************************************************/
667 static void
668 create_alt_msg_path (cairo_t *cr,
669                      gchar   *text)
670 {
671         PangoLayout          *layout;
672         PangoFontDescription *desc;
673
674         layout = pango_cairo_create_layout (cr);
675
676         desc = pango_font_description_new ();
677         pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
678         pango_font_description_set_size   (desc, 12 * PANGO_SCALE * FONT_SCALE);
679         pango_layout_set_font_description (layout, desc);
680         pango_font_description_free       (desc);
681
682         if (text == NULL || *text == '\0')
683         {
684                 pango_layout_set_text (layout, _("Barcode data empty"), -1);
685         }
686         else
687         {
688                 pango_layout_set_text (layout, _("Invalid barcode data"), -1);
689         }
690
691         cairo_move_to (cr, 0, 0);
692         pango_cairo_layout_path (cr, layout);
693
694         g_object_unref (layout);
695 }
696
697
698 /*****************************************************************************/
699 /* Barcode style utilities.                                                  */
700 /*****************************************************************************/
701 glLabelBarcodeStyle *
702 gl_label_barcode_style_new (void)
703 {
704         return g_new0 (glLabelBarcodeStyle, 1);
705 }
706
707
708 glLabelBarcodeStyle *
709 gl_label_barcode_style_dup (const glLabelBarcodeStyle *style)
710 {
711         glLabelBarcodeStyle *style2;
712
713         style2 = gl_label_barcode_style_new ();
714
715         /* Shallow copy first. */
716         *style2 = *style;
717
718         /* Now go deep. */
719         style2->backend_id = g_strdup (style->backend_id);
720         style2->id         = g_strdup (style->id);
721
722         return style2;
723 }
724
725
726 void
727 gl_label_barcode_style_free (glLabelBarcodeStyle *style)
728 {
729         if ( style )
730         {
731                 g_free (style->backend_id);
732                 g_free (style->id);
733
734                 g_free (style);
735         }
736 }
737
738
739 gboolean
740 gl_label_barcode_style_is_equal (const glLabelBarcodeStyle *style1,
741                                  const glLabelBarcodeStyle *style2)
742 {
743
744         /* First take care of the case of either or both being NULL. */
745         if ( style1 == NULL )
746         {
747                 return ( style2 == NULL );
748         }
749         else
750         {
751                 if ( style2 == NULL )
752                 {
753                         return FALSE;
754                 }
755         }
756
757         /* Compare field by field, bail on first difference. */
758         if ( style1->text_flag != style2->text_flag )
759         {
760                 return FALSE;
761         }
762         if ( style1->checksum_flag != style2->checksum_flag )
763         {
764                 return FALSE;
765         }
766         if ( style1->format_digits != style2->format_digits )
767         {
768                 return FALSE;
769         }
770         if ( style1->backend_id && style2->backend_id )
771         {
772                 if ( strcmp (style1->backend_id, style2->backend_id) != 0 )
773                 {
774                         return FALSE;
775                 }
776         }
777         else
778         {
779                 if ( style1->backend_id != style2->backend_id )
780                 {
781                         return FALSE;
782                 }
783         }
784         if ( style1->id && style2->id )
785         {
786                 if ( strcmp (style1->id, style2->id) != 0 )
787                 {
788                         return FALSE;
789                 }
790         }
791         else
792         {
793                 if ( style1->id != style2->id )
794                 {
795                         return FALSE;
796                 }
797         }
798
799         /* Passed all tests. */
800         return TRUE;
801 }
802
803
804 void
805 gl_label_barcode_style_set_backend_id (glLabelBarcodeStyle *style,
806                                        const gchar         *backend_id)
807 {
808         style->backend_id = g_strdup (backend_id);
809 }
810
811
812 void
813 gl_label_barcode_style_set_style_id (glLabelBarcodeStyle *style,
814                                      const gchar         *id)
815 {
816         style->id = g_strdup (id);
817 }
818
819
820
821
822
823 /*
824  * Local Variables:       -- emacs
825  * mode: C                -- emacs
826  * c-basic-offset: 8      -- emacs
827  * tab-width: 8           -- emacs
828  * indent-tabs-mode: nil  -- emacs
829  * End:                   -- emacs
830  */