| 1 | unit lbc_render;
|
|---|
| 2 |
|
|---|
| 3 | {$mode objfpc}{$H+}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | uses
|
|---|
| 8 | Classes, SysUtils,
|
|---|
| 9 | zint, lbc_helper;
|
|---|
| 10 |
|
|---|
| 11 | function render_plot_create_line(x, y, width, length: Single): PointerTo_zint_render_line;
|
|---|
| 12 | function render_plot_add_line(symbol: PointerTo_zint_symbol; line: PointerTo_zint_render_line; last_line: PointerTo_PointerTo_zint_render_line): Integer;
|
|---|
| 13 | function render_plot_create_ring(x, y, radius, line_width: Single): PointerTo_zint_render_ring;
|
|---|
| 14 | function render_plot_add_ring(symbol: PointerTo_zint_symbol; ring: PointerTo_zint_render_ring; last_ring: PointerTo_PointerTo_zint_render_ring): Integer;
|
|---|
| 15 | function render_plot_create_hexagon(x, y: Single): PointerTo_zint_render_hexagon;
|
|---|
| 16 | function render_plot_add_hexagon(symbol: PointerTo_zint_symbol; hexagon: PointerTo_zint_render_hexagon; last_hexagon: PointerTo_PointerTo_zint_render_hexagon): Integer;
|
|---|
| 17 | function render_plot_add_string(symbol: PointerTo_zint_symbol; text: PBYTE; x, y, fsize, width: Single; last_string: PointerTo_PointerTo_zint_render_string): Integer;
|
|---|
| 18 | function render_plot(symbol: PointerTo_zint_symbol; width: Single; height: Single): Integer;
|
|---|
| 19 |
|
|---|
| 20 | implementation
|
|---|
| 21 |
|
|---|
| 22 | function render_plot(symbol: PointerTo_zint_symbol; width: Single; height: Single): Integer;
|
|---|
| 23 | var
|
|---|
| 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;
|
|---|
| 66 | begin
|
|---|
| 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;
|
|---|
| 686 | end;
|
|---|
| 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!) }
|
|---|
| 691 | function render_plot_create_line(x, y, width, length: Single): PointerTo_zint_render_line;
|
|---|
| 692 | var
|
|---|
| 693 | line: PointerTo_zint_render_line;
|
|---|
| 694 | begin
|
|---|
| 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;
|
|---|
| 702 | end;
|
|---|
| 703 |
|
|---|
| 704 | { Add the line to the current rendering and update the last line's next value. }
|
|---|
| 705 | function render_plot_add_line(symbol: PointerTo_zint_symbol;
|
|---|
| 706 | line: PointerTo_zint_render_line; last_line: PointerTo_PointerTo_zint_render_line): Integer;
|
|---|
| 707 | begin
|
|---|
| 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;
|
|---|
| 716 | end;
|
|---|
| 717 |
|
|---|
| 718 | function render_plot_create_ring(x: Single; y: Single; radius: Single; line_width: Single): PointerTo_zint_render_ring;
|
|---|
| 719 | var
|
|---|
| 720 | ring: PointerTo_zint_render_ring;
|
|---|
| 721 | begin
|
|---|
| 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);
|
|---|
| 729 | end;
|
|---|
| 730 |
|
|---|
| 731 | function render_plot_add_ring(symbol: PointerTo_zint_symbol; ring: PointerTo_zint_render_ring; last_ring: PointerTo_PointerTo_zint_render_ring): Integer;
|
|---|
| 732 | begin
|
|---|
| 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);
|
|---|
| 741 | end;
|
|---|
| 742 |
|
|---|
| 743 | function render_plot_create_hexagon(x: Single; y: Single): PointerTo_zint_render_hexagon;
|
|---|
| 744 | var
|
|---|
| 745 | hexagon: PointerTo_zint_render_hexagon;
|
|---|
| 746 | begin
|
|---|
| 747 | hexagon := GetMem (SizeOf (zint_render_hexagon));
|
|---|
| 748 | hexagon^.next := nil;
|
|---|
| 749 | hexagon^.x := x;
|
|---|
| 750 | hexagon^.y := y;
|
|---|
| 751 | exit (hexagon);
|
|---|
| 752 | end;
|
|---|
| 753 |
|
|---|
| 754 | function render_plot_add_hexagon(symbol: PointerTo_zint_symbol; hexagon: PointerTo_zint_render_hexagon; last_hexagon: PointerTo_PointerTo_zint_render_hexagon): Integer;
|
|---|
| 755 | begin
|
|---|
| 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);
|
|---|
| 764 | end;
|
|---|
| 765 |
|
|---|
| 766 | { Add a string structure to the symbol.
|
|---|
| 767 | Coordinates assumed to be from top-center. }
|
|---|
| 768 | function render_plot_add_string(symbol: PointerTo_zint_symbol; text: PByte;
|
|---|
| 769 | x, y, fsize, width: Single; last_string: PointerTo_PointerTo_zint_render_string): Integer;
|
|---|
| 770 | var
|
|---|
| 771 | pstring: PointerTo_zint_render_string;
|
|---|
| 772 | begin
|
|---|
| 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;
|
|---|
| 788 | end;
|
|---|
| 789 |
|
|---|
| 790 | end.
|
|---|
| 791 |
|
|---|