source: trunk/Packages/lazbarcodes/src/lbc_render.pas

Last change on this file was 123, checked in by chronos, 3 years ago
  • Added: QR code image visible in contact others tab. It can be saved as image to file.
File size: 27.0 KB
Line 
1unit lbc_render;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils,
9 zint, lbc_helper;
10
11function render_plot_create_line(x, y, width, length: Single): PointerTo_zint_render_line;
12function render_plot_add_line(symbol: PointerTo_zint_symbol; line: PointerTo_zint_render_line; last_line: PointerTo_PointerTo_zint_render_line): Integer;
13function render_plot_create_ring(x, y, radius, line_width: Single): PointerTo_zint_render_ring;
14function render_plot_add_ring(symbol: PointerTo_zint_symbol; ring: PointerTo_zint_render_ring; last_ring: PointerTo_PointerTo_zint_render_ring): Integer;
15function render_plot_create_hexagon(x, y: Single): PointerTo_zint_render_hexagon;
16function render_plot_add_hexagon(symbol: PointerTo_zint_symbol; hexagon: PointerTo_zint_render_hexagon; last_hexagon: PointerTo_PointerTo_zint_render_hexagon): Integer;
17function render_plot_add_string(symbol: PointerTo_zint_symbol; text: PBYTE; x, y, fsize, width: Single; last_string: PointerTo_PointerTo_zint_render_string): Integer;
18function render_plot(symbol: PointerTo_zint_symbol; width: Single; height: Single): Integer;
19
20implementation
21
22function render_plot(symbol: PointerTo_zint_symbol; width: Single; height: Single): Integer;
23var
24 render: PointerTo_zint_render;
25 last_line: PointerTo_zint_render_line = nil;
26 line: PointerTo_zint_render_line = nil;
27 last_string: PointerTo_zint_render_string = nil;
28 last_ring: PointerTo_zint_render_ring = nil;
29 ring: PointerTo_zint_render_ring = nil;
30 {%H-}last_hexagon: PointerTo_zint_render_hexagon = nil;
31 {%H-}hexagon: PointerTo_zint_render_hexagon = nil;
32 this_row: Integer;
33 latch: Integer;
34 block_width: Integer;
35 r: Integer;
36 i: Integer;
37 row_posn: Single = 0.0;
38 row_height: Single = 0.0;
39 preset_height: Single = 0.0;
40 large_bar_height: Single = 0.0;
41 textwidth: Single = 0.0;
42 textpos: Single = 0.0;
43 addon_width_x: Integer;
44 main_symbol_width_x: Integer;
45 textdone: Integer;
46 yoffset: Integer;
47 xoffset: Integer;
48 text_height: Integer;
49 text_offset: Integer;
50 textpart: array[0..9] of Char;
51 addon: array[0..5] of Char;
52 total_area_width_x: Integer;
53 total_symbol_width_x: Integer;
54 symbol_lead_in: Integer;
55 large_bar_count: Integer;
56 addon_text_posn: Single;
57 default_text_posn: Single;
58 scaler: Single;
59 //locale: pchar = nil;
60 hide_text: Boolean = false;
61 required_aspect: Single;
62 symbol_aspect: Single = 1.0;
63 x_dimension: Single;
64 upceanflag: Integer = 0;
65 addon_latch: Integer = 0;
66begin
67 Result := 0;
68
69 // Allocate memory for the rendered version
70 GetMem(Symbol^.rendered,sizeof(zint_render));
71 render:=Symbol^.rendered;
72 render^.lines := nil;
73 render^.strings := nil;
74 render^.rings := nil;
75 render^.hexagons := nil;
76// locale := setlocale (LC_ALL, 'C');
77
78 row_height := 0;
79 textdone := 0;
80 textpos := 0.0;
81 main_symbol_width_x := symbol^.width;
82 addon[0] := #0;
83 strcpy(addon, '');
84 symbol_lead_in := 0;
85 addon_text_posn := 0.0;
86 addon_width_x := 0;
87
88 { Determine if there will be any addon texts and text height }
89 latch := 0;
90 r := 0;
91 // Isolate add-on text
92 if is_extendable (symbol^.symbology) then
93 begin
94 for i := 0 to sysutils.strlen(@symbol^.text[0])-1 do
95 begin
96 if latch = 1 then
97 begin
98 addon[r] := char(symbol^.text[i]);
99 Inc(r);
100 end;
101 if char(symbol^.text[i]) = '+' then
102 begin
103 latch := 1;
104 end;
105 end;
106 end;
107 addon[r] := #0;
108
109 if (symbol^.show_hrt=0) or (sysutils.strlen(@symbol^.text[0]) = 0) then
110 begin
111 hide_text := true;
112 text_offset := 0;
113 text_height := 0;
114 end else begin
115 text_height := symbol^.font_height;
116 text_offset := 2;
117 end;
118
119 { Calculate the width of the barcode, especially if there are any extra
120 borders or white space to add. }
121 while not (module_is_set(symbol, symbol^.rows - 1, symbol_lead_in)) do
122 Inc(symbol_lead_in);
123
124 // Certain symbols need whitespace otherwise characters get chopped off the sides
125 if ((symbol^.symbology = BARCODE_EANX) and (symbol^.rows = 1)) or
126 (symbol^.symbology = BARCODE_EANX_CC) or
127 (symbol^.symbology = BARCODE_ISBNX) then
128 begin
129 case sysutils.strlen(@symbol^.text[0]) of
130 13, 16, 19:
131 begin
132 if symbol^.whitespace_width = 0 then
133 symbol^.whitespace_width := 10;
134 main_symbol_width_x := 96 + symbol_lead_in;
135 upceanflag := 13;
136 end;
137 2:
138 begin
139 main_symbol_width_x := 22 + symbol_lead_in;
140 upceanflag := 2;
141 end;
142 5:
143 begin
144 main_symbol_width_x := 49 + symbol_lead_in;
145 upceanflag := 5;
146 end;
147 otherwise
148 begin
149 main_symbol_width_x := 68 + symbol_lead_in;
150 upceanflag := 8;
151 end;
152 end;
153 case sysutils.strlen(@symbol^.text[0]) of
154 11, 16: addon_width_x := 31; // EAN-2 add-on
155 14, 19: addon_width_x := 58; // EAN-5 add-on
156 end;
157 end;
158
159 if ((symbol^.symbology = BARCODE_UPCA) and (symbol^.rows = 1)) or
160 (symbol^.symbology = BARCODE_UPCA_CC) then
161 begin
162 upceanflag := 12;
163 if symbol^.whitespace_width < 10 then
164 begin
165 symbol^.whitespace_width := 10;
166 main_symbol_width_x := 96 + symbol_lead_in;
167 end;
168 case sysutils.strlen (@symbol^.text[0]) of
169 15: addon_width_x := 31; // EAN-2 add-on
170 18: addon_width_x := 58; // EAN-5 add-on
171 end;
172 end;
173
174 if ((symbol^.symbology = BARCODE_UPCE)) and (symbol^.rows = 1) or
175 (symbol^.symbology = BARCODE_UPCE_CC) then
176 begin
177 upceanflag := 6;
178 if symbol^.whitespace_width = 0 then
179 begin
180 symbol^.whitespace_width := 10;
181 main_symbol_width_x := 51 + symbol_lead_in;
182 end;
183 case sysutils.strlen (@symbol^.text[0]) of
184 11: addon_width_x := 31; // EAN-2 add-on
185 14: addon_width_x := 58; // EAN-5 add-on
186 end;
187 end;
188
189 total_symbol_width_x := main_symbol_width_x + addon_width_x;
190 total_area_width_x := total_symbol_width_x + 2*(symbol^.border_width + symbol^.whitespace_width);
191
192 xoffset := symbol^.border_width + symbol^.whitespace_width;
193 yoffset := symbol^.border_width;
194
195 { Determine if height should be overridden }
196 large_bar_count := 0;
197 preset_height := 0.0;
198 i := 0;
199 while i < symbol^.rows do
200 begin
201 preset_height := preset_height + symbol^.row_height[i];
202 if symbol^.row_height[i] = 0 then
203 begin
204 Inc(large_bar_count);
205 end;
206 Inc (i);
207 end;
208
209 if large_bar_count = 0 then
210 begin
211 if height = 0 then
212 required_aspect := 1.0
213 else
214 required_aspect := width / height;
215 symbol_aspect := (total_symbol_width_x + 2*xoffset) / (preset_height + 2*yoffset + text_offset + text_height);
216 symbol^.height := trunc(preset_height);
217 if required_aspect > symbol_aspect then
218 begin
219 // the area is too wide
220 if symbol^.scale > 0 then
221 scaler := symbol^.scale
222 else
223 scaler := height / (preset_height + 2*yoffset + text_offset + text_height);
224 render^.width := symbol_aspect * height;
225 render^.height := height;
226 end else begin
227 // the area is too high
228 if symbol^.scale > 0 then
229 scaler := symbol^.scale
230 else
231 scaler := width / (total_symbol_width_x + 2*xoffset);
232 render^.width := width;
233 render^.height := width / symbol_aspect;
234 end;
235 large_bar_height := 0;
236 end else begin
237 if symbol^.scale > 0 then
238 scaler := symbol^.scale
239 else
240 scaler := width / (total_symbol_width_x + 2*xoffset);
241 if scaler = 0 then
242 begin
243 Result := ERROR_TOO_LONG; // avoid divide-by-zero error
244 exit;
245 end;
246// symbol^.height := Trunc((height / scaler) - (2*yoffset + text_offset + text_height)); // -- orig
247 symbol^.height := Trunc(((height - text_height - text_offset) / scaler) - 2*yoffset);
248 render^.width := width;
249 render^.height := height;
250 large_bar_height := (symbol^.height - preset_height) / large_bar_count;
251 end;
252 {
253 if ((symbol^.output_options and BARCODE_BOX) <> 0) or ((symbol^.output_options and BARCODE_BIND) <> 0) then
254 default_text_posn := (symbol^.height + text_offset + 2*symbol^.border_width) * scaler
255 else
256 default_text_posn := (symbol^.height + text_offset + symbol^.border_width) * scaler;
257}
258
259 if symbol^.output_options and (BARCODE_BOX or BARCODE_BIND) <> 0 then
260 default_text_posn := (symbol^.height + 2*symbol^.border_width) * scaler + text_offset
261 else
262 default_text_posn := (symbol^.height + symbol^.border_width) * scaler + text_offset;
263
264 x_dimension := render^.width / total_area_width_x;
265 x_dimension := x_dimension / GL_CONST;
266
267
268 { Set minimum size of symbol }
269
270 // Barcode must be at least 2 mm high and 2 mm across
271 if render^.height < ((x_dimension * (2*symbol^.border_width + text_offset + text_height)) + 2.0) * GL_CONST then
272 render^.height := ((x_dimension * (2*symbol^.border_width + text_offset + text_height)) + 2.0) * GL_CONST;
273 if render^.width < 2.0 * GL_CONST then
274 render^.width := 2.0 * GL_CONST;
275
276 // The minimum X-dimension of Codabar is 0.191 mm. The minimum bar height is 5 mm
277 if symbol^.symbology = BARCODE_CODABAR then
278 begin
279 if x_dimension < 0.191 then
280 render^.width := 0.191 * GL_CONST * total_area_width_x;
281 if render^.height < ((x_dimension * (2*symbol^.border_width + text_offset + text_height)) + 5.0) * GL_CONST then
282 render^.height := ((x_dimension * (2*symbol^.border_width + text_offset + text_height)) + 5.0) * GL_CONST;
283 end;
284
285 // The minimum X-dimension of Code 49 is 0.191 mm
286 if symbol^.symbology = BARCODE_CODE49 then
287 begin
288 if x_dimension < 0.191 then
289 begin
290 render^.width := 0.191 * GL_CONST * total_area_width_x;
291 render^.height := render^.width / symbol_aspect;
292 end;
293 end;
294
295 // The X-dimension of UPC/EAN symbols is fixed at 0.330mm
296 // NOTE: This code will need adjustment before it correctly deals with composite symbols
297 if upceanflag <> 0 then
298 begin
299 render^.width := 0.330 * GL_CONST * total_area_width_x;
300 // The height is also fixed.
301 case upceanflag of
302 6, 12, 13:
303 // UPC-A, UPC-E and EAN-13: Height of bars should be 22.85 mm
304 render^.height := ((0.330 * ((2 * symbol^.border_width) + text_offset + text_height)) + 22.85) * GL_CONST;
305 8:
306 // EAN-8: Height of bars should be 18.23 mm
307 render^.height := ((0.330 * ((2 * symbol^.border_width) + text_offset + text_height)) + 18.23) * GL_CONST;
308 otherwise
309 // EAN-2 and EAN-5: Height of bars should be 21.10 mm
310 render^.height := ((0.330 * ((2 * symbol^.border_width) + text_offset + text_height)) + 21.10) * GL_CONST;
311 end;
312 end;
313
314 // The size of USPS Intelligent Mail barcode is fixed
315 if symbol^.symbology = BARCODE_ONECODE then
316 begin
317 render^.width := 0.508 * GL_CONST * total_area_width_x;
318 render^.height := 4.064 * GL_CONST;
319 end;
320
321 // The sizes of PostNet and PLANET are fized
322 if (symbol^.symbology = BARCODE_POSTNET) or (symbol^.symbology = BARCODE_PLANET) then
323 begin
324 render^.width := 0.508 * GL_CONST * total_area_width_x;
325 render^.height := 2.921 * GL_CONST;
326 end;
327
328 // Australia Post use the same sizes as USPS
329 if (symbol^.symbology = BARCODE_AUSPOST) or
330 (symbol^.symbology = BARCODE_AUSREPLY) or
331 (symbol^.symbology = BARCODE_AUSROUTE) or
332 (symbol^.symbology = BARCODE_AUSREDIRECT) then
333 begin
334 render^.width := 0.508 * GL_CONST * total_area_width_x;
335 render^.height := 4.064 * GL_CONST;
336 end;
337
338 // Royal Mail and KIX Code uses 22 bars per inch
339 if (symbol^.symbology = BARCODE_RM4SCC) or (symbol^.symbology = BARCODE_KIX) then
340 begin
341 render^.width := 0.577 * GL_CONST * total_area_width_x;
342 render^.height := 5.22 * GL_CONST;
343 end;
344
345 // Maxicode is a fixed size
346 if symbol^.symbology = BARCODE_MAXICODE then
347 begin
348 scaler := GL_CONST; // Converts from millimeters to the scale used by glabels
349 render^.width := 28.16 * scaler;
350 render^.height := 26.86 * scaler;
351
352 // Central bullseye pattern
353 ring := render_plot_create_ring (13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler);
354 render_plot_add_ring (symbol, ring, @last_ring);
355 ring := render_plot_create_ring (13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler);
356 render_plot_add_ring (symbol, ring, @last_ring);
357 ring := render_plot_create_ring (13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler);
358 render_plot_add_ring (symbol, ring, @last_ring);
359
360 // Hexagons
361 for r := 0 to symbol^.rows-1 do
362 begin
363 for i := 0 to symbol^.width-1 do
364 if module_is_set(symbol,r, i) then
365 begin
366 if r and 1 <> 0 then
367 hexagon := render_plot_create_hexagon((i*0.88 + 1.76) * scaler, (r*0.76 + 0.76)*scaler)
368 else
369 hexagon := render_plot_create_hexagon((i*0.88 + 1.32) * scaler, (r*0.76 + 0.76)*scaler);
370 end;
371 end;
372 end
373 else
374 begin
375 // Everything else uses rectangles (or squares).
376 // Works from the bottom of the symbol up
377 addon_latch := 0;
378 for r := 0 to symbol^.rows-1 do
379 begin
380 this_row := r;
381 if symbol^.row_height[this_row] = 0 then
382 begin
383 row_height := large_bar_height;
384 end else begin
385 row_height := symbol^.row_height[this_row];
386 end;
387 row_posn := 0;
388 i := 0;
389 while i < r do
390 begin
391 if symbol^.row_height[i] = 0 then
392 begin
393 row_posn := row_posn + large_bar_height;
394 end else begin
395 row_posn := row_posn + (symbol^.row_height[i]);
396 end;
397 Inc (i);
398 end;
399 row_posn := row_posn + yoffset;
400
401 i := 0;
402 if module_is_set (symbol, this_row, 0) then
403 latch := 1
404 else
405 latch := 0;
406
407 repeat
408 block_width := 0;
409 repeat
410 Inc(block_width);
411 until (i + block_width >= symbol^.width) or (module_is_set (symbol, this_row, i + block_width) <> module_is_set (symbol, this_row, i));
412 if (addon_latch = 0) and (r = (symbol^.rows - 1)) and (i > main_symbol_width_x) then
413 begin
414 addon_text_posn := row_posn * scaler;
415 addon_latch := 1;
416 end;
417 if latch = 1 then
418 begin
419 // a bar
420 if addon_latch = 0 then
421 line := render_plot_create_line ((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler)
422 else
423 line := render_plot_create_line ((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler);
424 latch := 0;
425 render_plot_add_line (symbol, line, @last_line);
426 end else
427 // a space
428 latch := 1;
429 inc(i, block_width);
430 until (i >= symbol^.width);
431 end;
432 end;
433 // That's done the actual data area, everything else is human-friendly
434
435 // Add the text
436 xoffset := xoffset - symbol_lead_in;
437 row_posn := (row_posn + large_bar_height) * scaler;
438
439 if not hide_text then
440 begin
441 // guard bar extensions and text formatting for EAN-8
442 if upceanflag = 8 then
443 begin
444 i := 0;
445 line := symbol^.rendered^.lines;
446 while line <> nil do
447 begin
448 case i of
449 0, 1, 10, 11, 20, 21:
450 line^.length := line^.length + 5.0 * scaler;
451 otherwise
452 ;
453 end;
454 Inc (i);
455 line := line^.next;
456 end;
457
458 for i := 0 to 3 do
459 textpart[i] := char(symbol^.text[i]);
460 textpart[4] := #0;
461 textpos := 17;
462 textwidth := 4.0 * 8.5;
463 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, @last_string);
464
465 for i := 0 to 3 do
466 textpart[i] := char(symbol^.text[i + 4]);
467 textpart[4] := #0;
468 textpos := 50;
469 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, @last_string);
470 textdone := 1;
471
472 case strlen(addon) of
473 2:
474 begin
475 textpos := xoffset + 86;
476 textwidth := 2.0 * 8.5;
477 render_plot_add_string(symbol, PByte(@addon[0]), textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, @last_string);
478 end;
479 5:
480 begin
481 textpos := xoffset + 100;
482 textwidth := 5.0 * 8.5;
483 render_plot_add_string(symbol, PByte(@addon[0]), textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, @last_string);
484 end;
485 end;
486 end;
487
488 // guard bar extensions and text formatting for EAN-13
489 if upceanflag = 13 then
490 begin
491 i := 0;
492 line := symbol^.rendered^.lines;
493 while line <> nil do
494 begin
495 if (i in [0, 1, 14, 15, 28, 29]) then
496 line^.length := line^.length + 5.0*scaler;
497 inc(i);
498 line := line^.next;
499 end;
500
501 textpart[0] := char(symbol^.text[0]);
502 textpart[1] := #0;
503 textpos := -5;
504 textwidth := 8.5;
505 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
506
507 for i := 0 to 5 do
508 textpart[i] := char(symbol^.text[i + 1]);
509 textpart[6] := #0;
510 textpos := 25;
511 textwidth := 8.5;
512 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
513
514 for i := 0 to 5 do
515 textpart[i] := char(symbol^.text[i + 7]);
516 textpart[6] := #0;
517 textpos := 72;
518 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
519 textdone := 1;
520
521 case strlen(addon) of
522 2:
523 begin
524 textpos := xoffset + 114;
525 textwidth := 2.0 * 8.5;
526 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
527 end;
528 5:
529 begin
530 textpos := xoffset + 128;
531 textwidth := 5.0 * 8.5;
532 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
533 end;
534 end;
535 end;
536
537 // guard bar extensions and text formatting for UPCA
538 if upceanflag = 12 then
539 begin
540 i := 0;
541 line := symbol^.rendered^.lines;
542 while line <> nil do
543 begin
544 if (i in [0, 1, 2, 3, 14, 15, 26, 27, 28, 29]) then
545 line^.length := line^.length + 5.0*scaler;
546 Inc (i);
547 line := line^.next;
548 end;
549
550 textpart[0] := char(symbol^.text[0]);
551 textpart[1] := #0;
552 textpos := -5;
553 textwidth := 6.2;
554 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn + 2.0*scaler, 8.0*scaler, textwidth*scaler, @last_string);
555 for i := 0 to 4 do
556 textpart[i] := char(symbol^.text[i + 1]);
557 textpart[5] := #0;
558 textpos := 27;
559 textwidth := 5.0 * 8.5;
560 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
561 for i := 0 to 5 do
562 textpart[i] := char(symbol^.text[i + 6]);
563 textpos := 68;
564 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
565 textpart[0] :=char(symbol^.text[11]);
566 textpart[1] := #0;
567 textpos := 100;
568 textwidth := 6.2;
569 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn + 2.0*scaler, 8.0*scaler, textwidth*scaler, @last_string);
570 textdone := 1;
571 case strlen (addon) of
572 2:
573 begin
574 textpos := xoffset + 116;
575 textwidth := 2.0 * 8.5;
576 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
577 end;
578 5:
579 begin
580 textpos := xoffset + 130;
581 textwidth := 5.0 * 8.5;
582 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
583 end;
584 end;
585 end;
586
587 // guard bar extensions and text formatting for UPCE
588 if upceanflag = 6 then
589 begin
590 i := 0;
591 line := symbol^.rendered^.lines;
592 while line <> nil do
593 begin
594 if (i in [0, 1, 14, 15, 16]) then
595 line^.length := line^.length + 5.0*scaler;
596 Inc(i);
597 line := line^.next;
598 end;
599
600 textpart[0] := char(symbol^.text[0]);
601 textpart[1] := #0;
602 textpos := -5;
603 textwidth := 6.2;
604 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn + 2.0*scaler, 8.0*scaler, textwidth*scaler, @last_string);
605 for i := 0 to 5 do
606 textpart[i] := char(symbol^.text[i + 1]);
607 textpart[6] := #0;
608 textpos := 24;
609 textwidth := 6.0 * 8.5;
610 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn, 11.0*scaler, textwidth*scaler, @last_string);
611 textpart[0] := char(symbol^.text[7]);
612 textpart[1] := #0;
613 textpos := 55;
614 textwidth := 6.2;
615 render_plot_add_string(symbol, PByte(@textpart[0]), (textpos + xoffset)*scaler, default_text_posn + 2.0*scaler, 8.0*scaler, textwidth*scaler, @last_string);
616 textdone := 1;
617 case strlen(addon) of
618 2:
619 begin
620 textpos := xoffset + 70;
621 textwidth := 2.0 * 8.5;
622 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
623 end;
624 5:
625 begin
626 textpos := xoffset + 84;
627 textwidth := 5.0 * 8.5;
628 render_plot_add_string(symbol, PByte(@addon[0]), textpos*scaler, addon_text_posn*scaler, 11.0*scaler, textwidth*scaler, @last_string);
629 end;
630 end;
631 end;
632
633 // Put normal human readable text at the bottom (and centered)
634 if textdone = 0 then
635 // calculate start xoffset to center text
636 render_plot_add_string(symbol, symbol^.text, ((symbol^.width / 2.0) + xoffset) * scaler, default_text_posn, text_height {9.0 * scaler}, 0.0, @last_string);
637 end;
638
639 case symbol^.symbology of
640 BARCODE_MAXICODE:
641 begin
642 //Do nothing...
643 end;
644 otherwise
645 begin
646 if (symbol^.output_options and BARCODE_BIND) <> 0 then
647 begin
648 if (symbol^.rows > 1) and is_stackable(symbol^.symbology) then
649 begin
650 // row binding
651 for r := 1 to symbol^.rows-1 do
652 begin
653 line := render_plot_create_line(xoffset * scaler, (r*row_height + yoffset - 1) * scaler, symbol^.width * scaler, 2.0*scaler);
654 render_plot_add_line(symbol, line, @last_line);
655 end;
656 end;
657 end;
658 if (symbol^.output_options and BARCODE_BOX <> 0) or (symbol^.output_options and BARCODE_BIND <> 0) then
659 begin
660 line := render_plot_create_line(0, 0, (symbol^.width + xoffset + xoffset) * scaler, symbol^.border_width * scaler);
661 render_plot_add_line(symbol, line, @last_line);
662 line := render_plot_create_line(0, (symbol^.height + symbol^.border_width) * scaler, (symbol^.width + xoffset + xoffset) * scaler, symbol^.border_width * scaler);
663 render_plot_add_line(symbol, line, @last_line);
664 end;
665 if (symbol^.output_options and BARCODE_BOX) <> 0 then
666 begin
667 line := render_plot_create_line(0, 0, symbol^.border_width * scaler, (symbol^.height + 2*symbol^.border_width) * scaler);
668 render_plot_add_line(symbol, line, @last_line);
669 line := render_plot_create_line((symbol^.width + xoffset + xoffset - symbol^.border_width) * scaler, 0, symbol^.border_width * scaler, (symbol^.height + 2*symbol^.border_width) * scaler);
670 render_plot_add_line(symbol, line, @last_line);
671 end;
672 end;
673 end;
674 (*
675 if Boolean(locale) then
676 begin
677 setlocale (LC_ALL, locale);
678 end;
679 *)
680
681 // store for calling routine
682 render^.scale := scaler;
683 render^.exact_width := total_area_width_x * scaler;
684
685 Result := 1;
686end;
687
688{ Create a new line with its memory allocated ready for adding to the
689 rendered structure.
690 This is much quicker than writing out each line manually (in some cases!) }
691function render_plot_create_line(x, y, width, length: Single): PointerTo_zint_render_line;
692var
693 line: PointerTo_zint_render_line;
694begin
695 line := GetMem (SizeOf (zint_render_line));
696 line^.next := nil;
697 line^.x := x;
698 line^.y := y;
699 line^.width := width;
700 line^.length := length;
701 Result := line;
702end;
703
704{ Add the line to the current rendering and update the last line's next value. }
705function render_plot_add_line(symbol: PointerTo_zint_symbol;
706 line: PointerTo_zint_render_line; last_line: PointerTo_PointerTo_zint_render_line): Integer;
707begin
708 if last_line^ <> nil then
709 begin
710 (last_line^)^.next := line;
711 end else begin
712 symbol^.rendered^.lines := line;
713 end;
714 last_line^ := line;
715 Result := 1;
716end;
717
718function render_plot_create_ring(x: Single; y: Single; radius: Single; line_width: Single): PointerTo_zint_render_ring;
719var
720 ring: PointerTo_zint_render_ring;
721begin
722 ring := GetMem (SizeOf (zint_render_ring));
723 ring^.next := nil;
724 ring^.x := x;
725 ring^.y := y;
726 ring^.radius := radius;
727 ring^.line_width := line_width;
728 exit (ring);
729end;
730
731function render_plot_add_ring(symbol: PointerTo_zint_symbol; ring: PointerTo_zint_render_ring; last_ring: PointerTo_PointerTo_zint_render_ring): Integer;
732begin
733 if last_ring^<>nil then
734 begin
735 (last_ring^)^.next := ring;
736 end else begin
737 symbol^.rendered^.rings := ring;
738 end;
739 last_ring^ := ring;
740 exit (1);
741end;
742
743function render_plot_create_hexagon(x: Single; y: Single): PointerTo_zint_render_hexagon;
744var
745 hexagon: PointerTo_zint_render_hexagon;
746begin
747 hexagon := GetMem (SizeOf (zint_render_hexagon));
748 hexagon^.next := nil;
749 hexagon^.x := x;
750 hexagon^.y := y;
751 exit (hexagon);
752end;
753
754function render_plot_add_hexagon(symbol: PointerTo_zint_symbol; hexagon: PointerTo_zint_render_hexagon; last_hexagon: PointerTo_PointerTo_zint_render_hexagon): Integer;
755begin
756 if last_hexagon^<>nil then
757 begin
758 (last_hexagon^)^.next := hexagon;
759 end else begin
760 symbol^.rendered^.hexagons := hexagon;
761 end;
762 last_hexagon^ := hexagon;
763 exit (1);
764end;
765
766{ Add a string structure to the symbol.
767 Coordinates assumed to be from top-center. }
768function render_plot_add_string(symbol: PointerTo_zint_symbol; text: PByte;
769 x, y, fsize, width: Single; last_string: PointerTo_PointerTo_zint_render_string): Integer;
770var
771 pstring: PointerTo_zint_render_string;
772begin
773 pstring := GetMem (SizeOf(zint_render_string));
774 pstring^.next := nil;
775 pstring^.x := x;
776 pstring^.y := y;
777 pstring^.width := width;
778 pstring^.fsize := fsize;
779 pstring^.length := sysutils.strlen(PChar(text));
780 pstring^.text := GetMem(SizeOf (BYTE) * (sysutils.strlen(PChar(text)) + 1));
781 strcpy (pchar(pstring^.text), pchar(text));
782 if last_string^ <> nil then
783 (last_string^)^.next := pstring
784 else
785 symbol^.rendered^.strings := pstring;
786 last_string^ := pstring;
787 Result := 1;
788end;
789
790end.
791
Note: See TracBrowser for help on using the repository browser.