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