2 * lgl-barcode-render-to-cairo.c
3 * Copyright (C) 2010 Jim Evins <evins@snaught.com>.
5 * This file is part of libglbarcode.
7 * libglbarcode is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser 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 * libglbarcode 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 Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with libglbarcode. If not, see <http://www.gnu.org/licenses/>.
23 #include "lgl-barcode-render-to-cairo.h"
25 #include <pango/pangocairo.h>
29 /*===========================================*/
30 /* Private macros and constants. */
31 /*===========================================*/
33 #define FONT_SCALE (72.0/96.0)
34 #define BARCODE_FONT_FAMILY "Sans"
35 #define BARCODE_FONT_WEIGHT PANGO_WEIGHT_NORMAL
38 /*===========================================*/
40 /*===========================================*/
43 /*===========================================*/
45 /*===========================================*/
48 /*===========================================*/
49 /* Local function prototypes */
50 /*===========================================*/
53 /****************************************************************************/
55 * lgl_barcode_render_to_cairo:
56 * @bc: An #lglBarcode structure
57 * @cr: A #cairo_t context
59 * Render barcode to cairo context. Context should be prepared with desired
60 * translation and appropriate scale. Context should be translated such that
61 * the origin is at the desired location of the upper left hand corner of the
62 * barcode bounding box. Context should be scaled such that all dimensions
63 * are in points ( 1 point = 1/72 inch ) and that positive y coordinates
64 * go down the surface.
67 lgl_barcode_render_to_cairo (const lglBarcode *bc,
72 lglBarcodeShape *shape;
73 lglBarcodeShapeLine *line;
74 lglBarcodeShapeBox *box;
75 lglBarcodeShapeChar *bchar;
76 lglBarcodeShapeString *bstring;
77 lglBarcodeShapeRing *ring;
78 lglBarcodeShapeHexagon *hexagon;
81 PangoFontDescription *desc;
83 gdouble x_offset, y_offset;
88 for (p = bc->shapes; p != NULL; p = p->next) {
90 shape = (lglBarcodeShape *)p->data;
95 case LGL_BARCODE_SHAPE_LINE:
96 line = (lglBarcodeShapeLine *) shape;
98 cairo_move_to (cr, line->x, line->y);
99 cairo_line_to (cr, line->x, line->y + line->length);
100 cairo_set_line_width (cr, line->width);
105 case LGL_BARCODE_SHAPE_BOX:
106 box = (lglBarcodeShapeBox *) shape;
108 cairo_rectangle (cr, box->x, box->y, box->width, box->height);
113 case LGL_BARCODE_SHAPE_CHAR:
114 bchar = (lglBarcodeShapeChar *) shape;
116 layout = pango_cairo_create_layout (cr);
118 desc = pango_font_description_new ();
119 pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
120 pango_font_description_set_size (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
121 pango_layout_set_font_description (layout, desc);
122 pango_font_description_free (desc);
124 cstring = g_strdup_printf ("%c", bchar->c);
125 pango_layout_set_text (layout, cstring, -1);
128 y_offset = 0.2 * bchar->fsize;
130 cairo_move_to (cr, bchar->x, bchar->y-y_offset);
131 pango_cairo_show_layout (cr, layout);
133 g_object_unref (layout);
137 case LGL_BARCODE_SHAPE_STRING:
138 bstring = (lglBarcodeShapeString *) shape;
140 layout = pango_cairo_create_layout (cr);
142 desc = pango_font_description_new ();
143 pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
144 pango_font_description_set_size (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
145 pango_layout_set_font_description (layout, desc);
146 pango_font_description_free (desc);
148 pango_layout_set_text (layout, bstring->string, -1);
150 pango_layout_get_size (layout, &iw, &ih);
151 layout_width = (gdouble)iw / (gdouble)PANGO_SCALE;
153 x_offset = layout_width / 2.0;
154 y_offset = 0.2 * bstring->fsize;
156 cairo_move_to (cr, (bstring->x - x_offset), (bstring->y - y_offset));
157 pango_cairo_show_layout (cr, layout);
159 g_object_unref (layout);
163 case LGL_BARCODE_SHAPE_RING:
164 ring = (lglBarcodeShapeRing *) shape;
166 cairo_arc (cr, ring->x, ring->y, ring->radius, 0.0, 2 * G_PI);
167 cairo_set_line_width (cr, ring->line_width);
172 case LGL_BARCODE_SHAPE_HEXAGON:
173 hexagon = (lglBarcodeShapeHexagon *) shape;
175 cairo_move_to (cr, hexagon->x, hexagon->y);
176 cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
177 cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
178 cairo_line_to (cr, hexagon->x, hexagon->y + hexagon->height);
179 cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
180 cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
181 cairo_close_path (cr);
187 g_assert_not_reached ();
197 /****************************************************************************/
199 * lgl_barcode_render_to_cairo_path:
200 * @bc: An #lglBarcode structure
201 * @cr: A #cairo_t context
203 * Render barcode to cairo context, but only create a path to be filled or
204 * tested against. Context should be prepared with desired
205 * translation and appropriate scale. Context should be translated such that
206 * the origin is at the desired location of the upper left hand corner of the
207 * barcode bounding box. Context should be scaled such that all dimensions
208 * are in points ( 1 point = 1/72 inch ) and that positive y coordinates
209 * go down the surface.
212 lgl_barcode_render_to_cairo_path (const lglBarcode *bc,
217 lglBarcodeShape *shape;
218 lglBarcodeShapeLine *line;
219 lglBarcodeShapeBox *box;
220 lglBarcodeShapeChar *bchar;
221 lglBarcodeShapeString *bstring;
222 lglBarcodeShapeRing *ring;
223 lglBarcodeShapeHexagon *hexagon;
226 PangoFontDescription *desc;
228 gdouble x_offset, y_offset;
230 gdouble layout_width;
233 for (p = bc->shapes; p != NULL; p = p->next) {
235 shape = (lglBarcodeShape *)p->data;
240 case LGL_BARCODE_SHAPE_LINE:
241 line = (lglBarcodeShapeLine *) shape;
243 cairo_rectangle (cr, line->x - line->width/2, line->y, line->width, line->length);
247 case LGL_BARCODE_SHAPE_BOX:
248 box = (lglBarcodeShapeBox *) shape;
250 cairo_rectangle (cr, box->x, box->y, box->width, box->height);
254 case LGL_BARCODE_SHAPE_CHAR:
255 bchar = (lglBarcodeShapeChar *) shape;
257 layout = pango_cairo_create_layout (cr);
259 desc = pango_font_description_new ();
260 pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
261 pango_font_description_set_size (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
262 pango_layout_set_font_description (layout, desc);
263 pango_font_description_free (desc);
265 cstring = g_strdup_printf ("%c", bchar->c);
266 pango_layout_set_text (layout, cstring, -1);
269 y_offset = 0.2 * bchar->fsize;
271 cairo_move_to (cr, bchar->x, bchar->y-y_offset);
272 pango_cairo_layout_path (cr, layout);
274 g_object_unref (layout);
278 case LGL_BARCODE_SHAPE_STRING:
279 bstring = (lglBarcodeShapeString *) shape;
281 layout = pango_cairo_create_layout (cr);
283 desc = pango_font_description_new ();
284 pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
285 pango_font_description_set_size (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
286 pango_layout_set_font_description (layout, desc);
287 pango_font_description_free (desc);
289 pango_layout_set_text (layout, bstring->string, -1);
291 pango_layout_get_size (layout, &iw, &ih);
292 layout_width = (gdouble)iw / (gdouble)PANGO_SCALE;
294 x_offset = layout_width / 2.0;
295 y_offset = 0.2 * bstring->fsize;
297 cairo_move_to (cr, (bstring->x - x_offset), (bstring->y - y_offset));
298 pango_cairo_layout_path (cr, layout);
300 g_object_unref (layout);
304 case LGL_BARCODE_SHAPE_RING:
305 ring = (lglBarcodeShapeRing *) shape;
307 cairo_new_sub_path (cr);
308 cairo_arc (cr, ring->x, ring->y, ring->radius + ring->line_width/2, 0.0, 2 * G_PI);
309 cairo_close_path (cr);
310 cairo_new_sub_path (cr);
311 cairo_arc (cr, ring->x, ring->y, ring->radius - ring->line_width/2, 0.0, 2 * G_PI);
312 cairo_close_path (cr);
315 case LGL_BARCODE_SHAPE_HEXAGON:
316 hexagon = (lglBarcodeShapeHexagon *) shape;
318 cairo_move_to (cr, hexagon->x, hexagon->y);
319 cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
320 cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
321 cairo_line_to (cr, hexagon->x, hexagon->y + hexagon->height);
322 cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
323 cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
324 cairo_close_path (cr);
328 g_assert_not_reached ();
340 * Local Variables: -- emacs
342 * c-basic-offset: 8 -- emacs
343 * tab-width: 8 -- emacs
344 * indent-tabs-mode: nil -- emacs