]> git.sur5r.net Git - glabels/blob - src/bc-iec18004.c
Imported Upstream version 3.0.0
[glabels] / src / bc-iec18004.c
1 /*
2  *  bc-iec18004.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 #ifdef HAVE_LIBQRENCODE
24
25 #include "bc-iec18004.h"
26
27 #include <glib.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <qrencode.h>
32
33 #include "debug.h"
34
35
36 /*========================================================*/
37 /* Private macros and constants.                          */
38 /*========================================================*/
39
40 #define MIN_PIXEL_SIZE 1.0
41
42
43 /*===========================================*/
44 /* Local function prototypes                 */
45 /*===========================================*/
46 static lglBarcode *render_iec18004 (const gchar *grid,
47                                     gint         i_width,
48                                     gint         i_height,
49                                     gdouble      w,
50                                     gdouble      h);
51
52
53 /*****************************************************************************/
54 /* Generate intermediate representation of barcode.                          */
55 /*****************************************************************************/
56 lglBarcode *
57 gl_barcode_iec18004_new (const gchar    *id,
58                          gboolean        text_flag,
59                          gboolean        checksum_flag,
60                          gdouble         w,
61                          gdouble         h,
62                          const gchar    *digits)
63 {
64         gint             i_width, i_height;
65         lglBarcode      *gbc;
66         QRcode          *qrcode;
67
68         if ( *digits == '\0' )
69         {
70                 return NULL;
71         }
72
73         i_width  = 0;
74         i_height = 0;
75
76         qrcode = QRcode_encodeString ((const char *)digits, 0, QR_ECLEVEL_M,
77                                       QR_MODE_8, 1);
78         if (qrcode == NULL)
79         {
80                 return NULL;
81         }
82         
83         i_width = i_height = qrcode->width;
84         gbc = render_iec18004 ((const gchar *)qrcode->data, i_width, i_height,
85                                w, h);
86
87         QRcode_free ( qrcode );
88
89         return gbc;
90 }
91
92
93 /*--------------------------------------------------------------------------
94  * PRIVATE.  Render to lglBarcode intermediate representation of barcode.
95  *--------------------------------------------------------------------------*/
96 static lglBarcode *
97 render_iec18004 (const gchar *grid,
98                  gint         i_width,
99                  gint         i_height,
100                  gdouble      w,
101                  gdouble      h)
102 {
103         lglBarcode         *gbc;
104         gint                x, y;
105         gdouble             aspect_ratio, pixel_size;
106
107         /* Treat requested size as a bounding box, scale to maintain aspect
108          * ratio while fitting it in this bounding box. */
109         aspect_ratio = (gdouble)i_height / (gdouble)i_width;
110         if ( h > w*aspect_ratio )
111         {
112                 h = w * aspect_ratio;
113         }
114         else
115         {
116                 w = h / aspect_ratio;
117         }
118
119         /* Now determine pixel size. */
120         pixel_size = w / i_width;
121         if ( pixel_size < MIN_PIXEL_SIZE )
122         {
123                 pixel_size = MIN_PIXEL_SIZE;
124         }
125
126         gbc = lgl_barcode_new ();
127
128         /* Now traverse the code string and create a list of boxes */
129         for ( y = 0; y < i_height; y++ )
130         {
131                 for ( x = 0; x < i_width; x++ )
132                 {
133
134                         /* Symbol data is represented as an array contains 
135                          * width*width uchars. Each uchar represents a module 
136                          * (dot). If the less significant bit of the uchar 
137                          * is 1, the corresponding module is black. The other
138                          * bits are meaningless for us. */
139                         if ((*grid++) & 1)
140                         {
141                                 lgl_barcode_add_box (gbc, x*pixel_size, y*pixel_size, pixel_size, pixel_size);
142                         }
143
144                 }
145
146         }
147
148         /* Fill in other info */
149         gbc->height = i_height * pixel_size;
150         gbc->width  = i_width  * pixel_size;
151
152         return gbc;
153 }
154
155 #endif /* HAVE_LIBQRENCODE */
156
157
158
159 /*
160  * Local Variables:       -- emacs
161  * mode: C                -- emacs
162  * c-basic-offset: 8      -- emacs
163  * tab-width: 8           -- emacs
164  * indent-tabs-mode: nil  -- emacs
165  * End:                   -- emacs
166  */