diff --git a/ChangeLog b/ChangeLog
index 850b2ac8..22d1ebc6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,7 +16,7 @@ Version 2.12.0.9 (dev) not released yet
- For Windows, filenames are now assumed to be UTF-8 encoded. Affects `outfile`
in `zint_symbol` and all API filename arguments
- Never-used `fontsize` member removed from `zint_symbol`
-- Buffer length of member `text` (HRT) in `zint_symbol` extended 128 -> 160
+- Buffer length of member `text` (HRT) in `zint_symbol` extended 128 -> 200
(client buffers may need checking/extending)
- Font of text of SVG vector output now "OCRB, monospace" (EAN/UPC) or
"Arimo, Arial, sans-serif" (all others)
@@ -27,6 +27,7 @@ Version 2.12.0.9 (dev) not released yet
- Unlikely-to-be-used `bitmap_byte_length` member removed from `zint_symbol`
(was only set on BMP output to length of BMP pixel array)
- EXCODE39 now defaults to displaying check digit in Human Readable Text (HRT)
+- GS1_128 now warns if data > 48 (GS1 General Specifications max)
Changes
-------
@@ -66,8 +67,7 @@ Changes
- GUI: use "OCRB" font for EAN/UPC and "Arimo" for all others (was "Helvetica"
for both); add preview background colour option (default light grey) so as
whitespace will show up in contrast (access via preview context menu)
-- CODE128/common: move `c128_hrt_cpy_iso8859_1()` to `hrt_cpy_iso8859_1()` and
- add `ZINT_WARN_HRT_TRUNCATED` warning (for future use)
+- CODE128/common: add `ZINT_WARN_HRT_TRUNCATED` warning
- QRCODE: better assert(), removing a NOLINT (2 left)
- CLI: add some more barcode synonyms for DBAR
- CMake: don't include png.c unless ZINT_USE_PNG (avoids clang warning)
@@ -80,7 +80,12 @@ Changes
- CODE39/EXCODE39/LOGMARS: new hidden check digit option
- GUI: move some symbology-specific options into Data Tab so separate tab
unnecessary
+- DATAMATRIX: add `DM_ISO_144` (--dmiso144) option for ISO placement of ECC
+ codewords instead of default "de facto"
- manual: add annexes on Qt and Tcl backends
+- CODE128: increase no. symbol chars max 60 -> 99
+- frontend: truncate overlong `--primary` instead of ignoring
+- man page: list size detail for matrix symbols (`--vers`)
Bugs
----
@@ -103,6 +108,7 @@ Bugs
shifting
- GUI: fix not enabling font combo "Small Bold (vector only)" by default
- CODEONE: fix S/T quiet zone 1X bottom (props BWIPP issue #245 doc)
+- EAN-2/EAN-5: fix `BARCODE_BIND_TOP/BIND/BOX` output
Version 2.12.0 (2022-12-12)
diff --git a/backend/2of5.c b/backend/2of5.c
index 49324e39..4a8fc458 100644
--- a/backend/2of5.c
+++ b/backend/2of5.c
@@ -232,7 +232,7 @@ INTERNAL int c25inter(struct zint_symbol *symbol, unsigned char source[], int le
/* Interleaved 2-of-5 (ITF-14) */
INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length) {
- int i, error_number, warn_number = 0, zeroes;
+ int i, error_number, zeroes;
unsigned char localstr[16] = {0};
if (length > 13) {
@@ -272,13 +272,13 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
/* GS1 General Specifications 21.0.1 5.12.3.2 table 2, including footnote (**): (note bind/box additional
to symbol->height), same as GS1-128: "in case of further space constraints"
height 5.8mm / 1.016mm (X max) ~ 5.7; default 31.75mm / 0.495mm ~ 64.14 */
- warn_number = set_height(symbol, stripf(5.8f / 1.016f), stripf(31.75f / 0.495f), 0.0f, 0 /*no_errtxt*/);
+ error_number = set_height(symbol, stripf(5.8f / 1.016f), stripf(31.75f / 0.495f), 0.0f, 0 /*no_errtxt*/);
} else {
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
}
}
- return error_number ? error_number : warn_number;
+ return error_number;
}
/* Deutsche Post Leitcode */
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index 277164c4..7ab2b365 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -70,8 +70,10 @@ endif()
if(ZINT_USE_PNG AND PNG_FOUND)
zint_target_link_libraries(PNG::PNG)
+ message(STATUS "Using PNG")
else()
zint_target_compile_definitions(PRIVATE ZINT_NO_PNG)
+ message(STATUS "Not using PNG")
endif()
if(ZINT_TEST)
diff --git a/backend/bmp.c b/backend/bmp.c
index 28855061..8f0093d1 100644
--- a/backend/bmp.c
+++ b/backend/bmp.c
@@ -53,29 +53,25 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
FILE *bmp_file;
bitmap_file_header_t file_header;
bitmap_info_header_t info_header;
- color_ref_t bg_color_ref;
- color_ref_t fg_color_ref;
- color_ref_t ultra_color_ref[8];
+ color_ref_t bg;
+ color_ref_t fg;
+ color_ref_t palette[8];
int ultra_fg_index = 9;
unsigned char map[128];
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; /* Suppress gcc -fanalyzer warning */
- (void) out_colour_get_rgb(symbol->fgcolour, &fg_color_ref.red, &fg_color_ref.green, &fg_color_ref.blue,
- NULL /*alpha*/);
- fg_color_ref.reserved = 0x00;
+ (void) out_colour_get_rgb(symbol->fgcolour, &fg.red, &fg.green, &fg.blue, NULL /*alpha*/);
+ fg.reserved = 0x00;
- (void) out_colour_get_rgb(symbol->bgcolour, &bg_color_ref.red, &bg_color_ref.green, &bg_color_ref.blue,
- NULL /*alpha*/);
- bg_color_ref.reserved = 0x00;
+ (void) out_colour_get_rgb(symbol->bgcolour, &bg.red, &bg.green, &bg.blue, NULL /*alpha*/);
+ bg.reserved = 0x00;
if (symbol->symbology == BARCODE_ULTRA) {
- static const int ultra_chars[8] = { 'C', 'B', 'M', 'R', 'Y', 'G', 'K', 'W' };
+ static const unsigned char ultra_chars[8] = { 'C', 'B', 'M', 'R', 'Y', 'G', 'K', 'W' };
for (i = 0; i < 8; i++) {
- ultra_color_ref[i].red = colour_to_red(i + 1);
- ultra_color_ref[i].green = colour_to_green(i + 1);
- ultra_color_ref[i].blue = colour_to_blue(i + 1);
- ultra_color_ref[i].reserved = 0x00;
- if (memcmp(&ultra_color_ref[i], &fg_color_ref, sizeof(fg_color_ref)) == 0) {
+ out_colour_char_to_rgb(ultra_chars[i], &palette[i].red, &palette[i].green, &palette[i].blue);
+ palette[i].reserved = 0x00;
+ if (memcmp(&palette[i], &fg, sizeof(fg)) == 0) {
ultra_fg_index = i + 1;
}
map[ultra_chars[i]] = i + 1;
@@ -106,14 +102,14 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
bitmap = bitmap_file_start + data_offset;
/* Pixel Plotting */
- if (symbol->symbology == BARCODE_ULTRA) {
+ if (bits_per_pixel == 4) {
for (row = 0; row < symbol->bitmap_height; row++) {
const unsigned char *pb = pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1));
for (column = 0; column < symbol->bitmap_width; column++) {
bitmap[(column >> 1) + (row * row_size)] |= map[pb[column]] << (!(column & 1) << 2);
}
}
- } else {
+ } else { /* bits_per_pixel == 1 */
for (row = 0; row < symbol->bitmap_height; row++) {
const unsigned char *pb = pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1));
for (column = 0; column < symbol->bitmap_width; column++) {
@@ -144,21 +140,22 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
memcpy(bitmap_file_start, &file_header, sizeof(bitmap_file_header_t));
bmp_posn += sizeof(bitmap_file_header_t);
memcpy(bmp_posn, &info_header, sizeof(bitmap_info_header_t));
-
bmp_posn += sizeof(bitmap_info_header_t);
- memcpy(bmp_posn, &bg_color_ref, sizeof(color_ref_t));
- if (symbol->symbology == BARCODE_ULTRA) {
+
+ memcpy(bmp_posn, &bg, sizeof(color_ref_t));
+ bmp_posn += sizeof(color_ref_t);
+ if (bits_per_pixel == 4) {
for (i = 0; i < 8; i++) {
+ memcpy(bmp_posn, &palette[i], sizeof(color_ref_t));
bmp_posn += sizeof(color_ref_t);
- memcpy(bmp_posn, &ultra_color_ref[i], sizeof(color_ref_t));
}
if (ultra_fg_index == 9) {
- bmp_posn += sizeof(color_ref_t);
- memcpy(bmp_posn, &fg_color_ref, sizeof(color_ref_t));
+ memcpy(bmp_posn, &fg, sizeof(color_ref_t));
+ /* bmp_posn += sizeof(color_ref_t); */ /* Not needed as long as last */
}
} else {
- bmp_posn += sizeof(color_ref_t);
- memcpy(bmp_posn, &fg_color_ref, sizeof(color_ref_t));
+ memcpy(bmp_posn, &fg, sizeof(color_ref_t));
+ /* bmp_posn += sizeof(color_ref_t); */ /* Not needed as long as last */
}
/* Open output file in binary mode */
diff --git a/backend/codablock.c b/backend/codablock.c
index 5c0857cf..f71c8b6c 100644
--- a/backend/codablock.c
+++ b/backend/codablock.c
@@ -555,7 +555,7 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int
/* option1: rows <= 0: automatic, 1..44 */
rows = symbol->option_1;
if (rows == 1) {
- error_number = code128(symbol, source, length); /* Only returns errors, not warnings */
+ error_number = code128(symbol, source, length);
if (error_number < ZINT_ERROR) {
symbol->output_options |= BARCODE_BIND;
if (symbol->border_width == 0) { /* Allow override if non-zero */
@@ -565,7 +565,11 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* AIM ISS-X-24 Section 4.6.1 minimum row height 8X (for compatibility with CODABLOCKF, not specced
for CODE128) */
- error_number = set_height(symbol, 8.0f, 10.0f, 0.0f, 0 /*no_errtxt*/);
+ if (error_number == 0) {
+ error_number = set_height(symbol, 8.0f, 10.0f, 0.0f, 0 /*no_errtxt*/);
+ } else {
+ (void) set_height(symbol, 8.0f, 10.0f, 0.0f, 1 /*no_errtxt*/);
+ }
} else {
(void) set_height(symbol, 0.0f, 5.0f, 0.0f, 1 /*no_errtxt*/);
}
diff --git a/backend/code128.c b/backend/code128.c
index 9104b72c..f4cc3284 100644
--- a/backend/code128.c
+++ b/backend/code128.c
@@ -37,6 +37,8 @@
#include "code128.h"
#include "gs1.h"
+#define C128_SYMBOL_MAX 99
+
static const char KRSET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#define KRSET_F (IS_NUM_F | IS_UPR_F)
@@ -343,7 +345,7 @@ INTERNAL void c128_put_in_set(int list[2][C128_MAX], const int indexliste, char
/* Handle Code 128, 128B and HIBC 128 */
INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int length) {
int i, j, k, values[C128_MAX] = {0}, bar_characters = 0, read, total_sum;
- int error_number = 0, indexchaine, indexliste, f_state = 0;
+ int error_number, indexchaine, indexliste, f_state = 0;
unsigned char src_buf[C128_MAX + 1];
unsigned char *src = source;
char manual_set[C128_MAX] = {0};
@@ -555,8 +557,8 @@ INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int len
glyph_count += 2;
}
}
- if (glyph_count > 120) { /* 60 * 2 */
- strcpy(symbol->errtxt, "341: Input too long (60 symbol character maximum)");
+ if (glyph_count > C128_SYMBOL_MAX * 2) {
+ sprintf(symbol->errtxt, "341: Input too long (%d symbol character maximum)", C128_SYMBOL_MAX);
return ZINT_ERROR_TOO_LONG;
}
@@ -709,7 +711,7 @@ INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int len
for (i = 1; i < bar_characters; i++, d += 6) {
memcpy(d, C128Table[values[i]], 6);
- total_sum += values[i] * i; /* Note can't overflow as 106 * 60 * 60 = 381600 */
+ total_sum += values[i] * i; /* Note can't overflow as 106 * C128_SYMBOL_MAX * C128_SYMBOL_MAX = 1038906 */
}
total_sum %= 103;
memcpy(d, C128Table[total_sum], 6);
@@ -740,7 +742,7 @@ INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int len
/* ISO/IEC 15417:2007 leaves dimensions/height as application specification */
- (void) hrt_cpy_iso8859_1(symbol, src, length); /* Truncation can't happen */
+ error_number = hrt_cpy_iso8859_1(symbol, src, length);
return error_number;
}
@@ -749,7 +751,7 @@ INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int len
INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_mode,
const int cc_rows) {
int i, values[C128_MAX] = {0}, bar_characters = 0, read, total_sum;
- int error_number, warn_number = 0, indexchaine, indexliste;
+ int error_number, indexchaine, indexliste;
int list[2][C128_MAX] = {{0}};
char set[C128_MAX] = {0}, mode, last_set;
int glyph_count = 0; /* Codeword estimate times 2 */
@@ -831,8 +833,8 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
glyph_count += 2;
}
}
- if (glyph_count > 120) { /* 60 * 2 */
- strcpy(symbol->errtxt, "344: Input too long (60 symbol character maximum)");
+ if (glyph_count > C128_SYMBOL_MAX * 2) {
+ sprintf(symbol->errtxt, "344: Input too long (%d symbol character maximum)", C128_SYMBOL_MAX);
return ZINT_ERROR_TOO_LONG;
}
@@ -939,7 +941,7 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
for (i = 1; i < bar_characters; i++, d += 6) {
memcpy(d, C128Table[values[i]], 6);
- total_sum += values[i] * i; /* Note can't overflow as 106 * 60 * 60 = 381600 */
+ total_sum += values[i] * i; /* Note can't overflow as 106 * C128_SYMBOL_MAX * C128_SYMBOL_MAX = 1038906 */
}
total_sum %= 103;
memcpy(d, C128Table[total_sum], 6);
@@ -976,6 +978,13 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
}
}
+ if (reduced_length > 48) { /* GS1 General Specifications 5.4.4.3 */
+ if (error_number == 0) { /* Don't overwrite any `gs1_verify()` warning */
+ strcpy(symbol->errtxt, "843: GS1-128 input too long (48 character maximum)");
+ error_number = ZINT_WARN_NONCOMPLIANT;
+ }
+ }
+
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* GS1 General Specifications 21.0.1 5.12.3.2 table 2, including footnote (**):
same as ITF-14: "in case of further space constraints" height 5.8mm / 1.016mm (X max) ~ 5.7;
@@ -986,7 +995,11 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
/* Pass back via temporary linear structure */
symbol->height = symbol->height ? min_height : default_height;
} else {
- warn_number = set_height(symbol, min_height, default_height, 0.0f, 0 /*no_errtxt*/);
+ if (error_number == 0) { /* Don't overwrite any `gs1_verify()` warning */
+ error_number = set_height(symbol, min_height, default_height, 0.0f, 0 /*no_errtxt*/);
+ } else {
+ (void) set_height(symbol, min_height, default_height, 0.0f, 1 /*no_errtxt*/);
+ }
}
} else {
const float height = 50.0f;
@@ -997,7 +1010,7 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
}
}
- for (i = 0; i < length; i++) {
+ for (i = 0; i < length && i < (int) sizeof(symbol->text); i++) {
if (source[i] == '[') {
symbol->text[i] = '(';
} else if (source[i] == ']') {
@@ -1006,8 +1019,15 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int
symbol->text[i] = source[i];
}
}
+ if (i == sizeof(symbol->text)) {
+ /* Trumps all other warnings */
+ strcpy(symbol->errtxt, "844: Human Readable Text truncated");
+ error_number = ZINT_WARN_HRT_TRUNCATED;
+ i--;
+ }
+ symbol->text[i] = '\0';
- return error_number ? error_number : warn_number;
+ return error_number;
}
/* Handle EAN-128 (Now known as GS1-128) */
@@ -1119,84 +1139,80 @@ INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length)
return ZINT_ERROR_INVALID_DATA;
}
- error_number = code128(symbol, local_source, length); /* Only returns errors, not warnings */
+ (void) code128(symbol, local_source, length); /* Only error returned is for large text which can't happen */
- if (error_number < ZINT_ERROR) {
- if (!(symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
- /* If no option has been selected then uses default bind top option */
- symbol->output_options |= BARCODE_BIND_TOP; /* Note won't extend over quiet zones for DPD */
- if (symbol->border_width == 0) { /* Allow override if non-zero */
- symbol->border_width = 3; /* From examples, not mentioned in spec */
- }
+ if (!(symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
+ /* If no option has been selected then uses default bind top option */
+ symbol->output_options |= BARCODE_BIND_TOP; /* Note won't extend over quiet zones for DPD */
+ if (symbol->border_width == 0) { /* Allow override if non-zero */
+ symbol->border_width = 3; /* From examples, not mentioned in spec */
}
+ }
- if (symbol->output_options & COMPLIANT_HEIGHT) {
- /* DPD Parcel Label Specification Version 2.4.1 (19.01.2021) Section 4.6.1.2
- 25mm / 0.4mm (X max) = 62.5 min, 25mm / 0.375 (X) ~ 66.66 default */
- if (relabel) { /* If relabel then half-size */
- error_number = set_height(symbol, 31.25f, stripf(12.5f / 0.375f), 0.0f, 0 /*no_errtxt*/);
- } else {
- error_number = set_height(symbol, 62.5f, stripf(25.0f / 0.375f), 0.0f, 0 /*no_errtxt*/);
- }
+ if (symbol->output_options & COMPLIANT_HEIGHT) {
+ /* DPD Parcel Label Specification Version 2.4.1 (19.01.2021) Section 4.6.1.2
+ 25mm / 0.4mm (X max) = 62.5 min, 25mm / 0.375 (X) ~ 66.66 default */
+ if (relabel) { /* If relabel then half-size */
+ error_number = set_height(symbol, 31.25f, stripf(12.5f / 0.375f), 0.0f, 0 /*no_errtxt*/);
} else {
- (void) set_height(symbol, 0.0f, relabel ? 25.0f : 50.0f, 0.0f, 1 /*no_errtxt*/);
+ error_number = set_height(symbol, 62.5f, stripf(25.0f / 0.375f), 0.0f, 0 /*no_errtxt*/);
}
+ } else {
+ (void) set_height(symbol, 0.0f, relabel ? 25.0f : 50.0f, 0.0f, 1 /*no_errtxt*/);
+ }
- cd = mod;
+ cd = mod;
- p = 0;
- for (i = !relabel; i < length; i++) {
- symbol->text[p] = local_source[i];
- p++;
-
- cd += posn(KRSET, local_source[i]);
- if (cd > mod) cd -= mod;
- cd *= 2;
- if (cd >= (mod + 1)) cd -= mod + 1;
-
- switch (i + relabel) {
- case 4:
- case 7:
- case 11:
- case 15:
- case 19:
- case 21:
- case 24:
- case 27:
- symbol->text[p] = ' ';
- p++;
- break;
- }
- }
-
- cd = mod + 1 - cd;
- if (cd == mod) cd = 0;
-
- if (cd < 10) {
- symbol->text[p] = cd + '0';
- } else {
- symbol->text[p] = (cd - 10) + 'A';
- }
+ p = 0;
+ for (i = !relabel; i < length; i++) {
+ symbol->text[p] = local_source[i];
p++;
- symbol->text[p] = '\0';
+ cd += posn(KRSET, local_source[i]);
+ if (cd > mod) cd -= mod;
+ cd *= 2;
+ if (cd >= (mod + 1)) cd -= mod + 1;
- if (error_number == 0) {
- /* Some compliance checks */
- if (!is_sane(NEON_F, local_source + length - 16, 16)) {
- if (!is_sane(NEON_F, local_source + length - 3, 3)) { /* 3-digit Country Code (ISO 3166-1) */
- strcpy(symbol->errtxt, "831: Destination Country Code (last 3 characters) should be numeric");
- } else if (!is_sane(NEON_F, local_source + length - 6, 3)) { /* 3-digit Service Code */
- strcpy(symbol->errtxt, "832: Service Code (characters 6-4 from end) should be numeric");
- } else { /* Last 10 characters of Tracking No. */
- strcpy(symbol->errtxt,
- "833: Last 10 characters of Tracking Number (characters 16-7 from end) should be numeric");
- }
- error_number = ZINT_WARN_NONCOMPLIANT;
- }
+ switch (i + relabel) {
+ case 4:
+ case 7:
+ case 11:
+ case 15:
+ case 19:
+ case 21:
+ case 24:
+ case 27:
+ symbol->text[p] = ' ';
+ p++;
+ break;
}
}
+ cd = mod + 1 - cd;
+ if (cd == mod) cd = 0;
+
+ if (cd < 10) {
+ symbol->text[p] = cd + '0';
+ } else {
+ symbol->text[p] = (cd - 10) + 'A';
+ }
+ p++;
+
+ symbol->text[p] = '\0';
+
+ /* Some compliance checks */
+ if (!is_sane(NEON_F, local_source + length - 16, 16)) {
+ if (!is_sane(NEON_F, local_source + length - 3, 3)) { /* 3-digit Country Code (ISO 3166-1) */
+ strcpy(symbol->errtxt, "831: Destination Country Code (last 3 characters) should be numeric");
+ } else if (!is_sane(NEON_F, local_source + length - 6, 3)) { /* 3-digit Service Code */
+ strcpy(symbol->errtxt, "832: Service Code (characters 6-4 from end) should be numeric");
+ } else { /* Last 10 characters of Tracking No. */
+ strcpy(symbol->errtxt,
+ "833: Last 10 characters of Tracking Number (characters 16-7 from end) should be numeric");
+ }
+ error_number = ZINT_WARN_NONCOMPLIANT;
+ }
+
return error_number;
}
@@ -1208,7 +1224,7 @@ INTERNAL int upu_s10(struct zint_symbol *symbol, unsigned char source[], int len
unsigned char have_check_digit = '\0';
int check_digit;
static const char weights[8] = { 8, 6, 4, 2, 3, 5, 9, 7 };
- int error_number = 0, warn_number = 0;
+ int error_number = 0;
if (length != 12 && length != 13) {
strcpy(symbol->errtxt, "834: Input must be 12 or 13 characters long");
@@ -1270,7 +1286,7 @@ INTERNAL int upu_s10(struct zint_symbol *symbol, unsigned char source[], int len
error_number = ZINT_WARN_NONCOMPLIANT;
}
- (void) code128(symbol, local_source, 13); /* Only error returned is TOO_LONG which can't happen */
+ (void) code128(symbol, local_source, 13); /* Only error returned is for large text which can't happen */
j = 0;
for (i = 0; i < 13; i++) {
@@ -1289,12 +1305,17 @@ INTERNAL int upu_s10(struct zint_symbol *symbol, unsigned char source[], int len
min_height = min_height_min;
}
/* Using 50 as default as none recommended */
- warn_number = set_height(symbol, min_height, min_height > 50.0f ? min_height : 50.0f, 0.0f, 0 /*no_errtxt*/);
+ if (error_number == 0) {
+ error_number = set_height(symbol, min_height, min_height > 50.0f ? min_height : 50.0f, 0.0f,
+ 0 /*no_errtxt*/);
+ } else {
+ (void) set_height(symbol, min_height, min_height > 50.0f ? min_height : 50.0f, 0.0f, 1 /*no_errtxt*/);
+ }
} else {
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
}
- return error_number ? error_number : warn_number;
+ return error_number;
}
/* vim: set ts=4 sw=4 et : */
diff --git a/backend/code128.h b/backend/code128.h
index aebcfe54..4b1c573c 100644
--- a/backend/code128.h
+++ b/backend/code128.h
@@ -36,7 +36,8 @@
extern "C" {
#endif /* __cplusplus */
-#define C128_MAX 160
+/* Allow for a reasonable number of special Code Set escapes and for GS1 AI delimiters */
+#define C128_MAX 256
#define C128_LATCHA 'A'
#define C128_LATCHB 'B'
diff --git a/backend/common.c b/backend/common.c
index a3054a74..9a8fee60 100644
--- a/backend/common.c
+++ b/backend/common.c
@@ -269,8 +269,8 @@ INTERNAL int is_stackable(const int symbology) {
return 0;
}
-/* Whether `symbology` can have add-on (EAN-2 and EAN-5) */
-INTERNAL int is_extendable(const int symbology) {
+/* Whether `symbology` is EAN/UPC */
+INTERNAL int is_upcean(const int symbology) {
switch (symbology) {
case BARCODE_EANX:
@@ -592,54 +592,6 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s
}
}
-/* Returns red component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_red(const int colour) {
- int return_val = 0;
-
- switch (colour) {
- case 8: /* White */
- case 3: /* Magenta */
- case 4: /* Red */
- case 5: /* Yellow */
- return_val = 255;
- break;
- }
-
- return return_val;
-}
-
-/* Returns green component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_green(const int colour) {
- int return_val = 0;
-
- switch (colour) {
- case 8: /* White */
- case 1: /* Cyan */
- case 5: /* Yellow */
- case 6: /* Green */
- return_val = 255;
- break;
- }
-
- return return_val;
-}
-
-/* Returns blue component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_blue(const int colour) {
- int return_val = 0;
-
- switch (colour) {
- case 8: /* White */
- case 1: /* Cyan */
- case 2: /* Blue */
- case 3: /* Magenta */
- return_val = 255;
- break;
- }
-
- return return_val;
-}
-
#ifdef ZINT_TEST
/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length) {
diff --git a/backend/common.h b/backend/common.h
index decc77b5..12043c4f 100644
--- a/backend/common.h
+++ b/backend/common.h
@@ -218,8 +218,8 @@ INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int le
/* Whether `symbology` can have row binding */
INTERNAL int is_stackable(const int symbology);
-/* Whether `symbology` can have add-on (EAN-2 and EAN-5) */
-INTERNAL int is_extendable(const int symbology);
+/* Whether `symbology` is EAN/UPC */
+INTERNAL int is_upcean(const int symbology);
/* Whether `symbology` can have composite 2D component data */
INTERNAL int is_composite(const int symbology);
@@ -272,16 +272,6 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s
struct zint_seg local_segs[]);
-/* Returns red component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_red(const int colour);
-
-/* Returns green component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_green(const int colour);
-
-/* Returns blue component if any of ultra colour indexing "0CBMRYGKW" */
-INTERNAL int colour_to_blue(const int colour);
-
-
#ifdef ZINT_TEST
/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length);
diff --git a/backend/composite.c b/backend/composite.c
index 5220d60d..2646ac59 100644
--- a/backend/composite.c
+++ b/backend/composite.c
@@ -1249,7 +1249,7 @@ static int linear_dummy_run(int input_mode, unsigned char *source, const int len
static const char in_linear_comp[] = " in linear component";
INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
- int error_number, warn_number = 0, cc_mode, cc_width = 0, ecc_level = 0;
+ int error_number, cc_mode, cc_width = 0, ecc_level = 0;
int j, i, k;
/* Allow for 8 bits + 5-bit latch per char + 1000 bits overhead/padding */
const unsigned int bs = 13 * length + 1000 + 1;
@@ -1581,10 +1581,19 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
if (symbol->output_options & COMPLIANT_HEIGHT) {
if (symbol->symbology == BARCODE_DBAR_STK_CC) {
/* Databar Stacked needs special treatment due to asymmetric rows */
- warn_number = dbar_omnstk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/);
+ error_number = dbar_omnstk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/);
+ } else if (symbol->symbology == BARCODE_DBAR_EXP_CC || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) {
+ /* If symbol->height given then min row height was returned, else default height */
+ if (error_number == 0) { /* Avoid overwriting any `gs1_verify()` warning */
+ error_number = set_height(symbol, symbol->height ? linear->height : 0.0f,
+ symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/);
+ } else {
+ (void) set_height(symbol, symbol->height ? linear->height : 0.0f,
+ symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/);
+ }
} else {
/* If symbol->height given then min row height was returned, else default height */
- warn_number = set_height(symbol, symbol->height ? linear->height : 0.0f,
+ error_number = set_height(symbol, symbol->height ? linear->height : 0.0f,
symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/);
}
} else {
@@ -1600,7 +1609,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
ZBarcode_Delete(linear);
- return error_number ? error_number : warn_number;
+ return error_number;
}
/* vim: set ts=4 sw=4 et : */
diff --git a/backend/emf.c b/backend/emf.c
index 94ae47ae..384ea42f 100644
--- a/backend/emf.c
+++ b/backend/emf.c
@@ -46,7 +46,7 @@
#include "emf.h"
/* Multiply truncating to 3 decimal places (avoids rounding differences on various platforms) */
-#define mul3dpf(m, arg) stripf(roundf((m) * (arg) * 1000.0) / 1000.0f)
+#define mul3dpf(m, arg) stripf(roundf((m) * (arg) * 1000.0f) / 1000.0f)
static int emf_count_rectangles(const struct zint_symbol *symbol) {
int rectangles = 0;
@@ -367,6 +367,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
recordcount++;
if (symbol->symbology == BARCODE_ULTRA) {
+ static const char ultra_chars[] = "0CBMRYGKW";
for (i = 0; i < 9; i++) {
emr_createbrushindirect_colour[i].type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */
emr_createbrushindirect_colour[i].size = 24;
@@ -377,9 +378,10 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
emr_createbrushindirect_colour[i].log_brush.color.green = fggrn;
emr_createbrushindirect_colour[i].log_brush.color.blue = fgblu;
} else {
- emr_createbrushindirect_colour[i].log_brush.color.red = colour_to_red(i);
- emr_createbrushindirect_colour[i].log_brush.color.green = colour_to_green(i);
- emr_createbrushindirect_colour[i].log_brush.color.blue = colour_to_blue(i);
+ out_colour_char_to_rgb(ultra_chars[i],
+ &emr_createbrushindirect_colour[i].log_brush.color.red,
+ &emr_createbrushindirect_colour[i].log_brush.color.green,
+ &emr_createbrushindirect_colour[i].log_brush.color.blue);
}
emr_createbrushindirect_colour[i].log_brush.color.reserved = 0;
emr_createbrushindirect_colour[i].log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */
@@ -479,7 +481,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
causes various different rendering issues for LibreOffice Draw and Inkscape, so using following hack */
if (previous_diameter != circ->diameter + circ->width) { /* Drawing MaxiCode bullseye using overlayed discs */
previous_diameter = circ->diameter + circ->width;
- radius = mul3dpf(0.5, previous_diameter);
+ radius = mul3dpf(0.5f, previous_diameter);
}
circle[this_circle].type = 0x0000002a; /* EMR_ELLIPSE */
circle[this_circle].size = 24;
@@ -518,9 +520,9 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
if (previous_diameter != hex->diameter) {
previous_diameter = hex->diameter;
- radius = mul3dpf(0.5, previous_diameter);
- half_radius = mul3dpf(0.25, previous_diameter);
- half_sqrt3_radius = mul3dpf(0.43301270189221932338, previous_diameter);
+ radius = mul3dpf(0.5f, previous_diameter);
+ half_radius = mul3dpf(0.25f, previous_diameter);
+ half_sqrt3_radius = mul3dpf(0.43301270189221932338f, previous_diameter);
}
/* Note rotation done via world transform */
@@ -549,7 +551,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
/* Create font records, alignment records and text color */
if (symbol->vector->strings) {
- bold = (symbol->output_options & BOLD_TEXT) && !is_extendable(symbol->symbology);
+ bold = (symbol->output_options & BOLD_TEXT) && !is_upcean(symbol->symbology);
memset(&emr_extcreatefontindirectw, 0, sizeof(emr_extcreatefontindirectw));
emr_extcreatefontindirectw.type = 0x00000052; /* EMR_EXTCREATEFONTINDIRECTW */
emr_extcreatefontindirectw.size = 104;
diff --git a/backend/gif.c b/backend/gif.c
index e6b52a19..64dbcd8c 100644
--- a/backend/gif.c
+++ b/backend/gif.c
@@ -376,33 +376,12 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
case '1': /* standard foreground */
RGBCur[0] = RGBfg[0]; RGBCur[1] = RGBfg[1]; RGBCur[2] = RGBfg[2];
break;
- case 'W': /* white */
- RGBCur[0] = 255; RGBCur[1] = 255; RGBCur[2] = 255;
+ default: /* Colour or error case */
+ if (!out_colour_char_to_rgb(pixelColour, &RGBCur[0], &RGBCur[1], &RGBCur[2])) {
+ strcpy(symbol->errtxt, "612: unknown pixel colour");
+ return ZINT_ERROR_INVALID_DATA;
+ }
break;
- case 'C': /* cyan */
- RGBCur[0] = 0; RGBCur[1] = 255; RGBCur[2] = 255;
- break;
- case 'B': /* blue */
- RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 255;
- break;
- case 'M': /* magenta */
- RGBCur[0] = 255; RGBCur[1] = 0; RGBCur[2] = 255;
- break;
- case 'R': /* red */
- RGBCur[0] = 255; RGBCur[1] = 0; RGBCur[2] = 0;
- break;
- case 'Y': /* yellow */
- RGBCur[0] = 255; RGBCur[1] = 255; RGBCur[2] = 0;
- break;
- case 'G': /* green */
- RGBCur[0] = 0; RGBCur[1] = 255; RGBCur[2] = 0;
- break;
- case 'K': /* black */
- RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 0;
- break;
- default: /* error case - return */
- strcpy(symbol->errtxt, "612: unknown pixel colour");
- return ZINT_ERROR_INVALID_DATA;
}
/* Search, if RGB value is already present */
fFound = 0;
diff --git a/backend/imail.c b/backend/imail.c
index 01b5a8b6..4dd2e7a5 100644
--- a/backend/imail.c
+++ b/backend/imail.c
@@ -33,7 +33,6 @@
/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence"
is Copyright (C) 2006 United States Postal Service */
-#include
#include "common.h"
#include "large.h"
@@ -266,11 +265,9 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
return ZINT_ERROR_INVALID_DATA;
}
- strcpy(zip, "");
- strcpy(tracker, "");
-
/* separate the tracking code from the routing code */
+ tracker[0] = zip[0] = '\0';
read = 0;
j = 0;
for (i = 0; i < length; i++) {
@@ -407,7 +404,7 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
}
}
- strcpy(data_pattern, "");
+ data_pattern[0] = '\0';
temp[1] = '\0';
for (i = 0; i < 65; i++) {
j = 0;
diff --git a/backend/library.c b/backend/library.c
index 1181f4c9..9960a455 100644
--- a/backend/library.c
+++ b/backend/library.c
@@ -73,6 +73,7 @@ struct zint_symbol *ZBarcode_Create(void) {
symbol->input_mode = DATA_MODE;
symbol->eci = 0; /* Default 0 uses ECI 3 */
symbol->dot_size = 4.0f / 5.0f;
+ symbol->text_gap = 1.0f;
symbol->guard_descent = 5.0f;
symbol->warn_level = WARN_DEFAULT;
symbol->bitmap = NULL;
@@ -1100,8 +1101,8 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[
if ((symbol->guard_descent < 0.0f) || (symbol->guard_descent > 50.0f)) {
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "769: Guard bar descent out of range (0 to 50)");
}
- if ((symbol->text_gap < 0.0f) || (symbol->text_gap > 10.0f)) {
- return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "219: Text gap out of range (0 to 10)");
+ if ((symbol->text_gap < -5.0f) || (symbol->text_gap > 10.0f)) {
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "219: Text gap out of range (-5 to 10)");
}
if ((symbol->whitespace_width < 0) || (symbol->whitespace_width > 100)) {
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "766: Whitespace width out of range (0 to 100)");
@@ -1786,8 +1787,8 @@ unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) {
if ((cap_flag & ZINT_CAP_STACKABLE) && is_stackable(symbol_id)) {
result |= ZINT_CAP_STACKABLE;
}
- if ((cap_flag & ZINT_CAP_EXTENDABLE) && is_extendable(symbol_id)) {
- result |= ZINT_CAP_EXTENDABLE;
+ if ((cap_flag & ZINT_CAP_EANUPC) && is_upcean(symbol_id)) {
+ result |= ZINT_CAP_EANUPC;
}
if ((cap_flag & ZINT_CAP_COMPOSITE) && is_composite(symbol_id)) {
result |= ZINT_CAP_COMPOSITE;
diff --git a/backend/output.c b/backend/output.c
index d30712d2..665dcf56 100644
--- a/backend/output.c
+++ b/backend/output.c
@@ -189,6 +189,38 @@ INTERNAL int out_colour_get_cmyk(const char *colour, int *cyan, int *magenta, in
return 1 + have_alpha;
}
+/* Convert internal colour chars "WCBMRYGK" to RGB */
+INTERNAL int out_colour_char_to_rgb(const char ch, unsigned char *red, unsigned char *green, unsigned char *blue) {
+ static const char chars[] = "WCBMRYGK";
+ static const unsigned char colours[8][3] = {
+ { 0xff, 0xff, 0xff, }, /* White */
+ { 0, 0xff, 0xff, }, /* Cyan */
+ { 0, 0, 0xff, }, /* Blue */
+ { 0xff, 0, 0xff, }, /* Magenta */
+ { 0xff, 0, 0, }, /* Red */
+ { 0xff, 0xff, 0, }, /* Yellow */
+ { 0, 0xff, 0, }, /* Green */
+ { 0, 0, 0, }, /* Black */
+ };
+ int i = posn(chars, ch);
+ int ret = i != -1;
+
+ if (i == -1) {
+ i = 7; /* Black (zeroize) */
+ }
+ if (red) {
+ *red = colours[i][0];
+ }
+ if (green) {
+ *green = colours[i][1];
+ }
+ if (blue) {
+ *blue = colours[i][2];
+ }
+
+ return ret;
+}
+
/* Return minimum quiet zones for each symbology */
static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, const int comp_xoffset,
float *left, float *right, float *top, float *bottom) {
@@ -654,50 +686,60 @@ INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hi
}
#endif
-/* Set left (x), top (y), right and bottom offsets for whitespace */
+/* Set left (x), top (y), right and bottom offsets for whitespace, also right quiet zone */
INTERNAL void out_set_whitespace_offsets(const struct zint_symbol *symbol, const int hide_text,
- const int comp_xoffset, float *xoffset, float *yoffset, float *roffset, float *boffset,
- const float scaler, int *xoffset_si, int *yoffset_si, int *roffset_si, int *boffset_si) {
+ const int comp_xoffset, float *p_xoffset, float *p_yoffset, float *p_roffset, float *p_boffset,
+ float *p_qz_right, const float scaler, int *p_xoffset_si, int *p_yoffset_si, int *p_roffset_si,
+ int *p_boffset_si, int *p_qz_right_si) {
float qz_left, qz_right, qz_top, qz_bottom;
out_quiet_zones(symbol, hide_text, comp_xoffset, &qz_left, &qz_right, &qz_top, &qz_bottom);
- *xoffset = symbol->whitespace_width + qz_left;
- *roffset = symbol->whitespace_width + qz_right;
+ *p_xoffset = symbol->whitespace_width + qz_left;
+ *p_roffset = symbol->whitespace_width + qz_right;
if (symbol->output_options & BARCODE_BOX) {
- *xoffset += symbol->border_width;
- *roffset += symbol->border_width;
+ *p_xoffset += symbol->border_width;
+ *p_roffset += symbol->border_width;
}
- *yoffset = symbol->whitespace_height + qz_top;
- *boffset = symbol->whitespace_height + qz_bottom;
+ *p_yoffset = symbol->whitespace_height + qz_top;
+ *p_boffset = symbol->whitespace_height + qz_bottom;
if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP)) {
- *yoffset += symbol->border_width;
- *boffset += symbol->border_width;
+ *p_yoffset += symbol->border_width;
+ if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND)) {
+ *p_boffset += symbol->border_width;
+ }
+ }
+
+ if (p_qz_right) {
+ *p_qz_right = qz_right;
}
if (scaler) {
- if (xoffset_si) {
- *xoffset_si = (int) (*xoffset * scaler);
+ if (p_xoffset_si) {
+ *p_xoffset_si = (int) (*p_xoffset * scaler);
}
- if (yoffset_si) {
- *yoffset_si = (int) (*yoffset * scaler);
+ if (p_yoffset_si) {
+ *p_yoffset_si = (int) (*p_yoffset * scaler);
}
- if (roffset_si) {
- *roffset_si = (int) (*roffset * scaler);
+ if (p_roffset_si) {
+ *p_roffset_si = (int) (*p_roffset * scaler);
}
- if (boffset_si) {
- *boffset_si = (int) (*boffset * scaler);
+ if (p_boffset_si) {
+ *p_boffset_si = (int) (*p_boffset * scaler);
+ }
+ if (p_qz_right_si) {
+ *p_qz_right_si = (int) (qz_right * scaler);
}
}
}
/* Set composite offset and main width excluding add-on (for start of add-on calc) and add-on text, returning
- UPC/EAN type */
+ EAN/UPC type */
INTERNAL int out_process_upcean(const struct zint_symbol *symbol, const int comp_xoffset, int *p_main_width,
- unsigned char addon[6], int *p_addon_gap) {
+ unsigned char addon[6], int *p_addon_len, int *p_addon_gap) {
int main_width; /* Width of main linear symbol, excluding add-on */
- int upceanflag; /* UPC/EAN type flag */
+ int upceanflag; /* EAN/UPC type flag */
int i, j, latch;
const int text_length = (int) ustrlen(symbol->text);
@@ -715,6 +757,7 @@ INTERNAL int out_process_upcean(const struct zint_symbol *symbol, const int comp
}
addon[j] = '\0';
if (latch) {
+ *p_addon_len = (int) ustrlen(addon);
if (symbol->symbology == BARCODE_UPCA || symbol->symbology == BARCODE_UPCA_CHK
|| symbol->symbology == BARCODE_UPCA_CC) {
*p_addon_gap = symbol->option_2 >= 9 && symbol->option_2 <= 12 ? symbol->option_2 : 9;
@@ -836,66 +879,6 @@ INTERNAL float out_large_bar_height(struct zint_symbol *symbol, const int si, in
return large_bar_height;
}
-/* Split UPC/EAN add-on text into various constituents */
-INTERNAL void out_upcean_split_text(const int upceanflag, const unsigned char text[], unsigned char textparts[4][7]) {
- int i;
-
- if (upceanflag == 6) { /* UPC-E */
- textparts[0][0] = text[0];
- textparts[0][1] = '\0';
-
- for (i = 0; i < 6; i++) {
- textparts[1][i] = text[i + 1];
- }
- textparts[1][6] = '\0';
-
- textparts[2][0] = text[7];
- textparts[2][1] = '\0';
-
- } else if (upceanflag == 8) { /* EAN-8 */
- for (i = 0; i < 4; i++) {
- textparts[0][i] = text[i];
- }
- textparts[0][4] = '\0';
-
- for (i = 0; i < 4; i++) {
- textparts[1][i] = text[i + 4];
- }
- textparts[1][4] = '\0';
-
- } else if (upceanflag == 12) { /* UPC-A */
- textparts[0][0] = text[0];
- textparts[0][1] = '\0';
-
- for (i = 0; i < 5; i++) {
- textparts[1][i] = text[i + 1];
- }
- textparts[1][5] = '\0';
-
- for (i = 0; i < 5; i++) {
- textparts[2][i] = text[i + 6];
- }
- textparts[2][5] = '\0';
-
- textparts[3][0] = text[11];
- textparts[3][1] = '\0';
-
- } else if (upceanflag == 13) { /* EAN-13 */
- textparts[0][0] = text[0];
- textparts[0][1] = '\0';
-
- for (i = 0; i < 6; i++) {
- textparts[1][i] = text[i + 1];
- }
- textparts[1][6] = '\0';
-
- for (i = 0; i < 6; i++) {
- textparts[2][i] = text[i + 7];
- }
- textparts[2][6] = '\0';
- }
-}
-
#ifdef _WIN32
/* Convert UTF-8 to Windows wide chars. Ticket #288, props Marcel */
#define utf8_to_wide(u, w, r) \
diff --git a/backend/output.h b/backend/output.h
index a6cd1b19..03080b43 100644
--- a/backend/output.h
+++ b/backend/output.h
@@ -49,15 +49,19 @@ INTERNAL int out_colour_get_rgb(const char *colour, unsigned char *red, unsigned
INTERNAL int out_colour_get_cmyk(const char *colour, int *cyan, int *magenta, int *yellow, int *black,
unsigned char *rgb_alpha);
-/* Set left (x), top (y), right and bottom offsets for whitespace */
+/* Convert internal colour chars "WCBMRYGK" to RGB */
+INTERNAL int out_colour_char_to_rgb(const char ch, unsigned char *red, unsigned char *green, unsigned char *blue);
+
+/* Set left (x), top (y), right and bottom offsets for whitespace, also right quiet zone */
INTERNAL void out_set_whitespace_offsets(const struct zint_symbol *symbol, const int hide_text,
- const int comp_xoffset, float *xoffset, float *yoffset, float *roffset, float *boffset,
- const float scaler, int *xoffset_si, int *yoffset_si, int *roffset_si, int *boffset_si);
+ const int comp_xoffset, float *p_xoffset, float *p_yoffset, float *p_roffset, float *p_boffset,
+ float *p_qz_right, const float scaler, int *p_xoffset_si, int *p_yoffset_si, int *p_roffset_si,
+ int *p_boffset_si, int *p_qz_right_si);
/* Set composite offset and main width excluding add-on (for start of add-on calc) and add-on text, returning
- UPC/EAN type */
+ EAN/UPC type */
INTERNAL int out_process_upcean(const struct zint_symbol *symbol, const int comp_xoffset, int *p_main_width,
- unsigned char addon[6], int *p_addon_gap);
+ unsigned char addon[6], int *p_addon_len, int *p_addon_gap);
/* Calculate large bar height i.e. linear bars with zero row height that respond to the symbol height.
If scaler `si` non-zero (raster), then large_bar_height if non-zero or else row heights will be rounded
@@ -65,9 +69,6 @@ INTERNAL int out_process_upcean(const struct zint_symbol *symbol, const int comp
INTERNAL float out_large_bar_height(struct zint_symbol *symbol, const int si, int *row_heights_si,
int *symbol_height_si);
-/* Split UPC/EAN add-on text into various constituents */
-INTERNAL void out_upcean_split_text(const int upceanflag, const unsigned char text[], unsigned char textparts[4][7]);
-
/* Create output file, creating sub-directories if necessary. Returns `fopen()` FILE pointer */
INTERNAL FILE *out_fopen(const char filename[256], const char *mode);
diff --git a/backend/pcx.c b/backend/pcx.c
index 6c73a1f5..8a286e95 100644
--- a/backend/pcx.c
+++ b/backend/pcx.c
@@ -111,69 +111,24 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
const unsigned char ch = pb[column];
switch (colour) {
case 0:
- switch (ch) {
- case 'W': /* White */
- case 'M': /* Magenta */
- case 'R': /* Red */
- case 'Y': /* Yellow */
- rle_row[column] = 255;
- break;
- case 'C': /* Cyan */
- case 'B': /* Blue */
- case 'G': /* Green */
- case 'K': /* Black */
- rle_row[column] = 0;
- break;
- case '1':
- rle_row[column] = fgred;
- break;
- default:
- rle_row[column] = bgred;
- break;
+ if (ch == '0' || ch == '1') {
+ rle_row[column] = ch != '0' ? fgred : bgred;
+ } else {
+ out_colour_char_to_rgb(ch, &rle_row[column], NULL, NULL);
}
break;
case 1:
- switch (ch) {
- case 'W': /* White */
- case 'C': /* Cyan */
- case 'Y': /* Yellow */
- case 'G': /* Green */
- rle_row[column] = 255;
- break;
- case 'B': /* Blue */
- case 'M': /* Magenta */
- case 'R': /* Red */
- case 'K': /* Black */
- rle_row[column] = 0;
- break;
- case '1':
- rle_row[column] = fggrn;
- break;
- default:
- rle_row[column] = bggrn;
- break;
+ if (ch == '0' || ch == '1') {
+ rle_row[column] = ch != '0' ? fggrn : bggrn;
+ } else {
+ out_colour_char_to_rgb(ch, NULL, &rle_row[column], NULL);
}
break;
case 2:
- switch (ch) {
- case 'W': /* White */
- case 'C': /* Cyan */
- case 'B': /* Blue */
- case 'M': /* Magenta */
- rle_row[column] = 255;
- break;
- case 'R': /* Red */
- case 'Y': /* Yellow */
- case 'G': /* Green */
- case 'K': /* Black */
- rle_row[column] = 0;
- break;
- case '1':
- rle_row[column] = fgblu;
- break;
- default:
- rle_row[column] = bgblu;
- break;
+ if (ch == '0' || ch == '1') {
+ rle_row[column] = ch != '0' ? fgblu : bgblu;
+ } else {
+ out_colour_char_to_rgb(ch, NULL, NULL, &rle_row[column]);
}
break;
case 3:
diff --git a/backend/png.c b/backend/png.c
index 950e2931..f028a72e 100644
--- a/backend/png.c
+++ b/backend/png.c
@@ -105,7 +105,7 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
png_color palette[32];
int num_palette;
unsigned char trans_alpha[32];
- int num_trans;
+ int num_trans = 0;
int bit_depth;
int compression_strategy;
const unsigned char *pb;
@@ -117,22 +117,11 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
(void) out_colour_get_rgb(symbol->fgcolour, &fg.red, &fg.green, &fg.blue, &fg_alpha);
(void) out_colour_get_rgb(symbol->bgcolour, &bg.red, &bg.green, &bg.blue, &bg_alpha);
- num_trans = 0;
if (symbol->symbology == BARCODE_ULTRA) {
- static const int ultra_chars[8] = { 'W', 'C', 'B', 'M', 'R', 'Y', 'G', 'K' };
- static const png_color ultra_colours[8] = {
- { 0xff, 0xff, 0xff, }, /* White */
- { 0, 0xff, 0xff, }, /* Cyan */
- { 0, 0, 0xff, }, /* Blue */
- { 0xff, 0, 0xff, }, /* Magenta */
- { 0xff, 0, 0, }, /* Red */
- { 0xff, 0xff, 0, }, /* Yellow */
- { 0, 0xff, 0, }, /* Green */
- { 0, 0, 0, }, /* Black */
- };
+ static const unsigned char ultra_chars[8] = { 'W', 'C', 'B', 'M', 'R', 'Y', 'G', 'K' };
for (i = 0; i < 8; i++) {
map[ultra_chars[i]] = i;
- palette[i] = ultra_colours[i];
+ out_colour_char_to_rgb(ultra_chars[i], &palette[i].red, &palette[i].green, &palette[i].blue);
if (fg_alpha != 0xff) {
trans_alpha[i] = fg_alpha;
}
@@ -170,10 +159,11 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
palette[num_palette++] = bg;
} else {
/* Alpha and no foreground alpha - add to front & move white to end */
+ png_color white = palette[0]; /* Take copy */
map['0'] = 0;
palette[0] = bg;
map['W'] = num_palette;
- palette[num_palette++] = ultra_colours[0];
+ palette[num_palette++] = white;
}
if (bg_alpha != 0xff) {
trans_alpha[num_trans++] = bg_alpha;
diff --git a/backend/postal.c b/backend/postal.c
index 5ca6dc61..51ef1b67 100644
--- a/backend/postal.c
+++ b/backend/postal.c
@@ -593,7 +593,7 @@ INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length
symbol->height = 8.0f;
}
symbol->row_height[1] = stripf(symbol->height * t_ratio);
- symbol->row_height[0] = stripf((symbol->height - symbol->row_height[1]) / 2.0);
+ symbol->row_height[0] = stripf((symbol->height - symbol->row_height[1]) / 2.0f);
} else {
symbol->row_height[0] = 3.0f;
symbol->row_height[1] = 2.0f;
diff --git a/backend/ps.c b/backend/ps.c
index 48a16822..8e9ac42d 100644
--- a/backend/ps.c
+++ b/backend/ps.c
@@ -83,14 +83,14 @@ static void ps_convert(const unsigned char *string, unsigned char *ps_string) {
*p++ = '\\';
*p++ = *s;
break;
- case 0xC2: /* See `to_iso8859_1()` in raster.c */
- *p++ = *++s;
+ case 0xC2:
+ *p++ = *++s; /* C2 80-BF -> 80-BF */
break;
case 0xC3:
- *p++ = *++s + 64;
+ *p++ = *++s + 0x40; /* C3 80-BF -> C0-FF */
break;
default:
- if (*s < 0x80) {
+ if (*s < 0x80) { /* ASCII - all other Unicode points > U+00FF ignored */
*p++ = *s;
}
break;
@@ -189,7 +189,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
int ps_len = 0;
int iso_latin1 = 0;
int have_circles_with_width = 0, have_circles_without_width = 0;
- const int extendable = is_extendable(symbol->symbology);
+ const int upcean = is_upcean(symbol->symbology);
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT;
const int is_rgb = (symbol->output_options & CMYK_COLOUR) == 0;
@@ -400,9 +400,9 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
float hy = symbol->vector->height - hex->y;
if (previous_diameter != hex->diameter) {
previous_diameter = hex->diameter;
- out_putsf("", 4, (float) (0.5 * previous_diameter) /*radius*/, feps);
- out_putsf(" ", 4, (float) (0.43301270189221932338 * previous_diameter) /*half_sqrt3_radius*/, feps);
- out_putsf(" ", 4, (float) (0.25 * previous_diameter) /*half_radius*/, feps);
+ out_putsf("", 4, 0.5f * previous_diameter /*radius*/, feps);
+ out_putsf(" ", 4, 0.43301270189221932338f * previous_diameter /*half_sqrt3_radius*/, feps);
+ out_putsf(" ", 4, 0.25f * previous_diameter /*half_radius*/, feps);
fputc('\n', feps);
}
if (hex->next) {
@@ -420,7 +420,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
for (circle = symbol->vector->circles; circle; circle = circle->next) {
if (previous_diameter != circle->diameter - circle->width) {
previous_diameter = circle->diameter - circle->width;
- radius = (float) (0.5 * previous_diameter);
+ radius = 0.5f * previous_diameter;
}
if (circle->colour) { /* Legacy - no longer used */
/* A 'white' circle */
@@ -458,7 +458,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
const char *font;
unsigned char *ps_string = (unsigned char *) z_alloca(ps_len + 1);
- if ((symbol->output_options & BOLD_TEXT) && !extendable) {
+ if ((symbol->output_options & BOLD_TEXT) && !upcean) {
font = "Helvetica-Bold";
} else {
font = "Helvetica";
@@ -479,7 +479,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
if (string->fsize != previous_fsize) {
fprintf(feps, "/%s findfont", font);
/* Compensate for Helvetica being smaller than Zint's OCR-B */
- out_putsf( " ", 2, extendable ? string->fsize * 1.07f : string->fsize, feps);
+ out_putsf( " ", 2, upcean ? string->fsize * 1.07f : string->fsize, feps);
fputs(" scalefont setfont\n", feps);
previous_fsize = string->fsize;
}
diff --git a/backend/qr.c b/backend/qr.c
index bc70c1aa..2c9834bf 100644
--- a/backend/qr.c
+++ b/backend/qr.c
@@ -1014,12 +1014,11 @@ static void qr_populate_grid(unsigned char *grid, const int h_size, const int v_
}
#ifdef ZINTLOG
-
-static int append_log(char log) {
+static int append_log(unsigned char log) {
FILE *file;
file = fopen("zintlog.txt", "a+");
- fprintf(file, "%c", log);
+ fprintf(file, "%02X", log);
(void) fclose(file);
return 0;
}
@@ -1028,8 +1027,7 @@ static int write_log(char log[]) {
FILE *file;
file = fopen("zintlog.txt", "a+");
- fprintf(file, log); /*writes*/
- fprintf(file, "\r\n"); /*writes*/
+ fprintf(file, "%s\n", log); /*writes*/
(void) fclose(file);
return 0;
}
@@ -1055,14 +1053,11 @@ static int qr_evaluate(unsigned char *local, const int size) {
#ifdef ZINTLOG
/* bitmask output */
for (y = 0; y < size; y++) {
- strcpy(str, "");
for (x = 0; x < size; x++) {
- state = local[(y * size) + x];
- append_log(state);
+ append_log(local[(y * size) + x]);
}
write_log("");
}
- write_log("");
#endif
/* Test 1: Adjacent modules in row/column in same colour */
@@ -1297,6 +1292,9 @@ static int qr_apply_bitmask(unsigned char *grid, const int size, const int ecc_l
int size_squared = size * size;
unsigned char *mask = (unsigned char *) z_alloca(size_squared);
unsigned char *local = (unsigned char *) z_alloca(size_squared);
+#ifdef ZINTLOG
+ char str[15];
+#endif
/* Perform data masking */
memset(mask, 0, size_squared);
@@ -1382,8 +1380,7 @@ static int qr_apply_bitmask(unsigned char *grid, const int size, const int ecc_l
}
#ifdef ZINTLOG
- char str[15];
- sprintf(str, "%d", best_val);
+ sprintf(str, "%d", best_pattern);
write_log("chose pattern:");
write_log(str);
#endif
diff --git a/backend/raster.c b/backend/raster.c
index 192fe533..9c1f0681 100644
--- a/backend/raster.c
+++ b/backend/raster.c
@@ -47,7 +47,11 @@
#define DEFAULT_INK '1' /* Black */
#define DEFAULT_PAPER '0' /* White */
-#define UPCEAN_TEXT 1 /* Helper flag for `draw_string()`/`draw_letter()` to indicate dealing with UPC/EAN */
+/* Flags for `draw_string()`/`draw_letter()` */
+#define ZFONT_HALIGN_CENTRE 0
+#define ZFONT_HALIGN_LEFT 1
+#define ZFONT_HALIGN_RIGHT 2
+#define ZFONT_UPCEAN_TEXT 4 /* Helper flag to indicate dealing with EAN/UPC */
#ifndef ZINT_NO_PNG
INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf);
@@ -260,7 +264,7 @@ static void draw_pt(unsigned char *buf, const int buf_width, const int buf_heigh
/* Draw the first line of a bar, to be completed by `copy_bar_line()`; more performant than multiple `draw_bar()`s */
static void draw_bar_line(unsigned char *pixelbuf, const int xpos, const int xlen, const int ypos,
- const int image_width, const char fill) {
+ const int image_width, const int fill) {
unsigned char *pb = pixelbuf + ((size_t) image_width * ypos) + xpos;
memset(pb, fill, xlen);
@@ -282,7 +286,7 @@ static void copy_bar_line(unsigned char *pixelbuf, const int xpos, const int xle
/* Draw a rectangle */
static void draw_bar(unsigned char *pixelbuf, const int xpos, const int xlen, const int ypos, const int ylen,
- const int image_width, const int image_height, const char fill) {
+ const int image_width, const int image_height, const int fill) {
int y;
const int ye = ypos + ylen > image_height ? image_height : ypos + ylen; /* Defensive, should never happen */
unsigned char *pb = pixelbuf + ((size_t) image_width * ypos) + xpos;
@@ -306,7 +310,7 @@ static void draw_letter(unsigned char *pixelbuf, const unsigned char letter, int
int font_y;
int half_si;
int odd_si;
- unsigned char *linePtr, *maxPtr;
+ unsigned char *linePtr;
int x_start = 0;
if (letter < 33) {
@@ -330,7 +334,7 @@ static void draw_letter(unsigned char *pixelbuf, const unsigned char letter, int
glyph_no = letter - 33;
}
- if (textflags & UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */
+ if (textflags & ZFONT_UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */
/* No bold for UPCEAN */
if (textflags & SMALL_TEXT) {
font_table = upcean_small_font;
@@ -375,8 +379,8 @@ static void draw_letter(unsigned char *pixelbuf, const unsigned char letter, int
unsigned char *pixelPtr = linePtr; /* Avoid warning */
for (y_si = 0; y_si < half_si; y_si++) {
int extra_dot = 0;
+ unsigned char *const maxPtr = linePtr + image_width - xposn;
pixelPtr = linePtr;
- maxPtr = linePtr + image_width - xposn;
for (x = x_start; x < max_x && pixelPtr < maxPtr; x++) {
unsigned set = font_table[font_y + y] & (glyph_mask >> x);
for (x_si = 0; x_si < half_si && pixelPtr < maxPtr; x_si++) {
@@ -409,12 +413,13 @@ static void draw_letter(unsigned char *pixelbuf, const unsigned char letter, int
}
/* Plot a string into the pixel buffer */
-static void draw_string(unsigned char *pixbuf, const unsigned char input_string[], const int xposn, const int yposn,
- const int textflags, const int image_width, const int image_height, const int si) {
- int i, string_length, string_left_hand, letter_width, letter_gap;
- int half_si = si / 2, odd_si = si & 1, x_incr;
+static void draw_string(unsigned char *pixelbuf, const unsigned char input_string[], int length, const int xposn,
+ const int yposn, const int textflags, const int image_width, const int image_height, const int si) {
+ int i, string_left_hand, letter_width, letter_gap;
+ const int half_si = si / 2, odd_si = si & 1;
+ int x_incr;
- if (textflags & UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */
+ if (textflags & ZFONT_UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */
/* No bold for UPCEAN */
letter_width = textflags & SMALL_TEXT ? UPCEAN_SMALL_FONT_WIDTH : UPCEAN_FONT_WIDTH;
letter_gap = 4;
@@ -431,18 +436,26 @@ static void draw_string(unsigned char *pixbuf, const unsigned char input_string[
}
letter_width += letter_gap;
- string_length = (int) ustrlen(input_string);
-
- string_left_hand = xposn - ((letter_width * string_length - letter_gap) * half_si) / 2;
- if (odd_si) {
- string_left_hand -= (letter_width * string_length - letter_gap) / 4;
+ if (length == -1) {
+ length = (int) ustrlen(input_string);
}
- for (i = 0; i < string_length; i++) {
+
+ if (textflags & ZFONT_HALIGN_LEFT) {
+ string_left_hand = xposn;
+ } else if (textflags & ZFONT_HALIGN_RIGHT) {
+ string_left_hand = xposn - ((letter_width * length - letter_gap) * half_si);
+ } else {
+ string_left_hand = xposn - (int) roundf(((letter_width * length - letter_gap) * half_si) / 2.0f);
+ }
+ if (odd_si) {
+ string_left_hand -= (letter_width * length - letter_gap) / 4;
+ }
+ for (i = 0; i < length; i++) {
x_incr = i * letter_width * half_si;
if (odd_si) {
x_incr += i * letter_width / 2;
}
- draw_letter(pixbuf, input_string[i], string_left_hand + x_incr, yposn, textflags, image_width, image_height,
+ draw_letter(pixelbuf, input_string[i], string_left_hand + x_incr, yposn, textflags, image_width, image_height,
si);
}
}
@@ -647,7 +660,8 @@ static void plot_hexagon(unsigned char *scaled_hexagon, const int hex_width, con
/* Draw binding or box */
static void draw_bind_box(const struct zint_symbol *symbol, unsigned char *pixelbuf,
const int xoffset_si, const int yoffset_si, const int symbol_height_si, const int dot_overspill_si,
- const int image_width, const int image_height, const int si) {
+ const int upceanflag, const int textoffset_si, const int image_width, const int image_height,
+ const int si) {
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
const int no_extend = symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF
|| symbol->symbology == BARCODE_DPD;
@@ -658,6 +672,9 @@ static void draw_bind_box(const struct zint_symbol *symbol, unsigned char *pixel
if (horz_outside) {
ybind_top = 0;
ybind_bot = image_height - bwidth_si;
+ } else if (upceanflag == 2 || upceanflag == 5) {
+ ybind_top += textoffset_si;
+ ybind_bot += textoffset_si;
}
/* Horizontal boundary bars */
if ((symbol->output_options & BARCODE_BOX) || !no_extend) {
@@ -683,6 +700,8 @@ static void draw_bind_box(const struct zint_symbol *symbol, unsigned char *pixel
if (horz_outside) {
box_top = bwidth_si;
box_height = image_height - bwidth_si * 2;
+ } else if (upceanflag == 2 || upceanflag == 5) {
+ box_top += textoffset_si;
}
draw_bar(pixelbuf, 0, bwidth_si, box_top, box_height, image_width, image_height, DEFAULT_INK);
draw_bar(pixelbuf, xbox_right, bwidth_si, box_top, box_height, image_width, image_height, DEFAULT_INK);
@@ -714,7 +733,7 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang
scaler *= 10.0f;
out_set_whitespace_offsets(symbol, 0 /*hide_text*/, 0 /*comp_xoffset*/, &xoffset, &yoffset, &roffset, &boffset,
- scaler, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si);
+ NULL /*qz_right*/, scaler, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si, NULL /*qz_right_si*/);
hex_width = (int) roundf(scaler); /* Short diameter, X in ISO/IEC 16023:2000 Figure 8 (same as W) */
hex_height = (int) roundf(scaler * two_div_sqrt3); /* Long diameter, V in Figure 8 */
@@ -772,7 +791,7 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang
xoffset_si, yoffset_si);
draw_bind_box(symbol, pixelbuf, xoffset_si, yoffset_si, hex_image_height, 0 /*dot_overspill_si*/,
- image_width, image_height, (int) scaler);
+ 0 /*upceanflag*/, 0 /*textoffset_si*/, image_width, image_height, (int) scaler);
error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, file_type);
free(scaled_hexagon);
@@ -812,7 +831,7 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle,
dot_radius_si = (int) dot_radius_s;
out_set_whitespace_offsets(symbol, 0 /*hide_text*/, 0 /*comp_xoffset*/, &xoffset, &yoffset, &roffset, &boffset,
- scaler, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si);
+ NULL /*qz_right*/, scaler, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si, NULL /*qz_right_si*/);
/* TODO: Revisit this overspill stuff, it's hacky */
if (symbol->dot_size < 1.0f) {
@@ -850,7 +869,7 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle,
}
draw_bind_box(symbol, scaled_pixelbuf, xoffset_si, yoffset_si, symbol_height_si, dot_overspill_si,
- scale_width, scale_height, (int) scaler);
+ 0 /*upceanflag*/, 0 /*textoffset_si*/, scale_width, scale_height, (int) scaler);
error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle,
file_type);
@@ -905,26 +924,25 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
int main_width;
int comp_xoffset = 0;
unsigned char addon[6];
+ int addon_len = 0;
int addon_gap = 0;
float addon_text_yposn = 0.0f;
float xoffset, yoffset, roffset, boffset;
float textoffset;
int upceanflag = 0;
int addon_latch = 0;
- unsigned char textparts[4][7];
int hide_text;
int i, r;
int block_width = 0;
int font_height; /* Font pixel size (so whole integers) */
- float text_gap; /* Gap between barcode and text */
float guard_descent;
const int upcean_guard_whitespace = !(symbol->output_options & BARCODE_NO_QUIET_ZONES)
&& (symbol->output_options & EANUPC_GUARD_WHITESPACE);
const int is_codablockf = symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF;
int textflags = 0;
- int xoffset_si, yoffset_si, roffset_si, boffset_si;
- int comp_xoffset_si;
+ int xoffset_si, yoffset_si, roffset_si, boffset_si, qz_right_si;
+ int xoffset_comp_si;
int row_heights_si[200];
int symbol_height_si;
int image_width, image_height;
@@ -955,28 +973,28 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
comp_xoffset++;
}
}
- if (is_extendable(symbol->symbology)) {
- upceanflag = out_process_upcean(symbol, comp_xoffset, &main_width, addon, &addon_gap);
+ if (is_upcean(symbol->symbology)) {
+ upceanflag = out_process_upcean(symbol, comp_xoffset, &main_width, addon, &addon_len, &addon_gap);
}
hide_text = ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0) || scaler < 1.0f);
- out_set_whitespace_offsets(symbol, hide_text, comp_xoffset, &xoffset, &yoffset, &roffset, &boffset, si,
- &xoffset_si, &yoffset_si, &roffset_si, &boffset_si);
+ out_set_whitespace_offsets(symbol, hide_text, comp_xoffset, &xoffset, &yoffset, &roffset, &boffset,
+ NULL /*qz_right*/, si, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si, &qz_right_si);
- comp_xoffset_si = xoffset_si + comp_xoffset * si;
+ xoffset_comp_si = xoffset_si + comp_xoffset * si;
+
+ image_width = symbol->width * si + xoffset_si + roffset_si;
/* Note font sizes halved as in pixels */
if (upceanflag) {
- textflags = UPCEAN_TEXT | (symbol->output_options & SMALL_TEXT); /* Bold not available for UPC/EAN */
+ textflags = ZFONT_UPCEAN_TEXT | (symbol->output_options & SMALL_TEXT); /* Bold not available for EAN/UPC */
font_height = (UPCEAN_FONT_HEIGHT + 1) / 2;
- text_gap = symbol->text_gap ? symbol->text_gap : 1.0f;
/* Height of guard bar descent (none for EAN-2 and EAN-5) */
guard_descent = upceanflag >= 6 ? symbol->guard_descent : 0.0f;
} else {
textflags = symbol->output_options & (SMALL_TEXT | BOLD_TEXT);
font_height = textflags & SMALL_TEXT ? (SMALL_FONT_HEIGHT + 1) / 2 : (NORMAL_FONT_HEIGHT + 1) / 2;
- text_gap = symbol->text_gap ? symbol->text_gap : 1.0f;
guard_descent = 0.0f;
}
@@ -984,17 +1002,16 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
textoffset = guard_descent;
} else {
if (upceanflag) {
- textoffset = font_height + text_gap;
+ textoffset = font_height + symbol->text_gap;
if (textoffset < guard_descent) {
textoffset = guard_descent;
}
} else {
- textoffset = font_height + text_gap;
+ textoffset = font_height + symbol->text_gap;
}
}
- image_width = symbol->width * si + xoffset_si + roffset_si;
- image_height = symbol_height_si + textoffset * si + yoffset_si + boffset_si;
+ image_height = symbol_height_si + (int) ceilf(textoffset * si) + yoffset_si + boffset_si;
assert(image_width && image_height);
if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) {
@@ -1035,12 +1052,12 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
&& module_is_set(symbol, r, i + block_width) == fill; block_width++);
if ((r == (symbol->rows - 1)) && (i > main_width) && (addon_latch == 0)) {
int addon_row_height_si;
- const int text_offset_si = (font_height + text_gap) * si;
+ const int addon_row_adj_si = (int) ceilf((font_height + symbol->text_gap) * si);
copy_bar_line(pixelbuf, xoffset_si, main_width * si, yposn_si, row_height_si, image_width,
image_height);
addon_text_yposn = yposn_si;
- yposn_si += text_offset_si;
- addon_row_height_si = row_height_si - text_offset_si;
+ yposn_si += addon_row_adj_si;
+ addon_row_height_si = row_height_si - addon_row_adj_si;
if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E add-ons don't descend */
addon_row_height_si += guard_descent * si;
}
@@ -1069,10 +1086,13 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
} else {
if (upceanflag && !hide_text) { /* EAN-2, EAN-5 (standalone add-ons) */
- yposn_si += (int) (font_height + text_gap) * si;
+ yposn_si += (int) ceilf((font_height + symbol->text_gap) * si);
}
for (r = 0; r < symbol->rows; r++) {
- const int row_height_si = row_heights_si[r];
+ int row_height_si = row_heights_si[r];
+ if (upceanflag && !hide_text) { /* EAN-2, EAN-5 (standalone add-ons) */
+ row_height_si += textoffset * si - (yposn_si - yoffset_si);
+ }
for (i = 0; i < symbol->width; i += block_width) {
const int fill = module_is_set(symbol, r, i);
@@ -1096,19 +1116,19 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
const int guard_descent_si = guard_descent * si;
if (upceanflag == 6) { /* UPC-E */
- draw_bar_line(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 50 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 0 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 2 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 46 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 48 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 50 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
} else if (upceanflag == 8) { /* EAN-8 */
- draw_bar_line(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 32 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 34 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 64 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 66 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 0 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 2 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 32 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 34 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 64 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 66 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
} else if (upceanflag == 12) { /* UPC-A */
for (i = 0 + comp_xoffset; i < 11 + comp_xoffset; i += block_width) {
@@ -1121,8 +1141,8 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
DEFAULT_INK);
}
}
- draw_bar_line(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 46 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 48 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
for (i = 85 + comp_xoffset; i < 96 + comp_xoffset; i += block_width) {
const int fill = module_is_set(symbol, symbol->rows - 1, i);
for (block_width = 1; (i + block_width < symbol->width)
@@ -1135,150 +1155,154 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
}
} else { /* EAN-13 */
- draw_bar_line(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 92 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
- draw_bar_line(pixelbuf, 94 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 0 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 2 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 46 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 48 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 92 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
+ draw_bar_line(pixelbuf, 94 * si + xoffset_comp_si, 1 * si, guard_yoffset_si, image_width, DEFAULT_INK);
}
- copy_bar_line(pixelbuf, comp_xoffset_si, image_width - comp_xoffset_si - roffset_si, guard_yoffset_si,
+ copy_bar_line(pixelbuf, xoffset_comp_si, image_width - xoffset_comp_si - roffset_si, guard_yoffset_si,
guard_descent_si, image_width, image_height);
}
/* Add the text */
if (!hide_text) {
- int text_yposn = yoffset_si + symbol_height_si + (int) (text_gap * si); /* Calculated to top of text */
- if (upceanflag == 2 || upceanflag == 5) { /* EAN-2/5 */
- text_yposn = yoffset_si;
- }
- if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) {
- text_yposn += symbol->border_width * si; /* Note not needed for BARCODE_BIND_TOP */
- }
if (upceanflag >= 6) { /* UPC-E, EAN-8, UPC-A, EAN-13 */
- const int addon_len = (int) ustrlen(addon);
/* Note font sizes halved as in pixels */
-
- /* Halved again to get middle position that draw_string() expects */
- const int upcea_width_adj = (UPCEAN_SMALL_FONT_WIDTH + 3) / 4;
const int upcea_height_adj = ((UPCEAN_FONT_HEIGHT - UPCEAN_SMALL_FONT_HEIGHT) * si + 1) / 2;
- /* Halved again to get middle position that draw_string() expects */
- const int ean_width_adj = (UPCEAN_FONT_WIDTH + 3) / 4;
- out_upcean_split_text(upceanflag, symbol->text, textparts);
+ int text_yposn = yoffset_si + symbol_height_si + (int) (symbol->text_gap * si);
+ if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) {
+ text_yposn += symbol->border_width * si; /* Note not needed for BARCODE_BIND_TOP */
+ }
if (upceanflag == 6) { /* UPC-E */
- int text_xposn = -(5 + upcea_width_adj) * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[0], text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT,
- image_width, image_height, si);
- text_xposn = 24 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[1], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = (51 + 3 + upcea_width_adj) * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[2], text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT,
- image_width, image_height, si);
+ int text_xposn = -5 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text, 1, text_xposn, text_yposn + upcea_height_adj,
+ textflags | SMALL_TEXT | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
+ text_xposn = 24 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 1, 6, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
+ text_xposn = (51 + 3) * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 7, 1, text_xposn, text_yposn + upcea_height_adj,
+ textflags | SMALL_TEXT | ZFONT_HALIGN_LEFT, image_width, image_height, si);
if (addon_len) {
- text_xposn = ((addon_len == 2 ? 61 : 75) + addon_gap) * si + comp_xoffset_si;
- draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags,
+ text_xposn = ((addon_len == 2 ? 61 : 75) + addon_gap) * si + xoffset_comp_si;
+ draw_string(pixelbuf, addon, addon_len, text_xposn, addon_text_yposn, textflags,
image_width, image_height, si);
if (upcean_guard_whitespace) {
- text_xposn = (int) (((addon_len == 2 ? 70 : 97) + 1.5f + upcea_width_adj + addon_gap) * si)
- + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, addon_text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
}
} else if (upceanflag == 8) { /* EAN-8 */
int text_xposn;
if (upcean_guard_whitespace) {
- text_xposn = -(ean_width_adj + 2) * si + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) "<", text_xposn, text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = -7 * si + xoffset_comp_si;
+ draw_string(pixelbuf, (const unsigned char *) "<", 1, text_xposn, text_yposn,
+ textflags | ZFONT_HALIGN_LEFT, image_width, image_height, si);
}
- text_xposn = 17 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[0], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = 50 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[1], text_xposn, text_yposn, textflags, image_width, image_height, si);
+ text_xposn = 17 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text, 4, text_xposn, text_yposn, textflags, image_width, image_height,
+ si);
+ text_xposn = 50 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 4, 4, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
if (addon_len) {
- text_xposn = ((addon_len == 2 ? 77 : 91) + addon_gap) * si + comp_xoffset_si;
- draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags,
+ text_xposn = ((addon_len == 2 ? 77 : 91) + addon_gap) * si + xoffset_comp_si;
+ draw_string(pixelbuf, addon, addon_len, text_xposn, addon_text_yposn, textflags,
image_width, image_height, si);
if (upcean_guard_whitespace) {
- text_xposn = (int) (((addon_len == 2 ? 86 : 113) + 0.5f + ean_width_adj + addon_gap) * si)
- + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, addon_text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
} else if (upcean_guard_whitespace) {
- text_xposn = (int) ((68 + 0.5f + ean_width_adj) * si) + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
} else if (upceanflag == 12) { /* UPC-A */
- int text_xposn = (-(5 + upcea_width_adj)) * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[0], text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT,
- image_width, image_height, si);
- text_xposn = 27 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[1], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = 67 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[2], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = (95 + 5 + upcea_width_adj) * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[3], text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT,
- image_width, image_height, si);
+ int text_xposn = -5 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text, 1, text_xposn, text_yposn + upcea_height_adj,
+ textflags | SMALL_TEXT | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
+ text_xposn = 28 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 1, 5, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
+ text_xposn = 67 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 6, 5, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
+ text_xposn = (95 + 5) * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 11, 1, text_xposn, text_yposn + upcea_height_adj,
+ textflags | SMALL_TEXT | ZFONT_HALIGN_LEFT, image_width, image_height, si);
if (addon_len) {
- text_xposn = ((addon_len == 2 ? 105 : 119) + addon_gap) * si + comp_xoffset_si;
- draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags,
+ text_xposn = ((addon_len == 2 ? 105 : 119) + addon_gap) * si + xoffset_comp_si;
+ draw_string(pixelbuf, addon, addon_len, text_xposn, addon_text_yposn, textflags,
image_width, image_height, si);
if (upcean_guard_whitespace) {
- text_xposn = (int) (((addon_len == 2 ? 114 : 141) + 0.5f + ean_width_adj + addon_gap) * si)
- + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, addon_text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
}
} else { /* EAN-13 */
- int text_xposn = (-(5 + ean_width_adj)) * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[0], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = 24 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[1], text_xposn, text_yposn, textflags, image_width, image_height, si);
- text_xposn = 71 * si + comp_xoffset_si;
- draw_string(pixelbuf, textparts[2], text_xposn, text_yposn, textflags, image_width, image_height, si);
+ int text_xposn = -5 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text, 1, text_xposn, text_yposn, textflags | ZFONT_HALIGN_RIGHT,
+ image_width, image_height, si);
+ text_xposn = 24 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 1, 6, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
+ text_xposn = 71 * si + xoffset_comp_si;
+ draw_string(pixelbuf, symbol->text + 7, 6, text_xposn, text_yposn, textflags, image_width,
+ image_height, si);
if (addon_len) {
- text_xposn = ((addon_len == 2 ? 105 : 119) + addon_gap) * si + comp_xoffset_si;
- draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags,
+ text_xposn = ((addon_len == 2 ? 105 : 119) + addon_gap) * si + xoffset_comp_si;
+ draw_string(pixelbuf, addon, addon_len, text_xposn, addon_text_yposn, textflags,
image_width, image_height, si);
if (upcean_guard_whitespace) {
- text_xposn = (int) (((addon_len == 2 ? 114 : 141) + 0.5f + ean_width_adj + addon_gap) * si)
- + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, addon_text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
} else if (upcean_guard_whitespace) {
- text_xposn = (int) ((96 + 0.5f + ean_width_adj) * si) + comp_xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, text_yposn, textflags,
- image_width, image_height, si);
+ text_xposn = symbol->width * si + qz_right_si + xoffset_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
}
}
+ } else if (upceanflag) { /* EAN-2, EAN-5 (standalone add-ons) */
+ int text_xposn = (int) ((main_width / 2.0f) * si) + xoffset_si;
+ int text_yposn = yoffset_si;
+ if (symbol->border_width > 0
+ && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
+ text_yposn -= symbol->border_width * si;
+ }
+ /* Put the human readable text at the top */
+ draw_string(pixelbuf, symbol->text, -1, text_xposn, text_yposn, textflags, image_width, image_height, si);
+ if (upcean_guard_whitespace) {
+ text_xposn = symbol->width * si + qz_right_si + xoffset_comp_si;
+ draw_string(pixelbuf, (const unsigned char *) ">", 1, text_xposn, text_yposn,
+ textflags | ZFONT_HALIGN_RIGHT, image_width, image_height, si);
+ }
} else {
- int text_xposn = (main_width / 2) * si + xoffset_si;
/* Suppress clang-analyzer-core.CallAndMessage warning */
unsigned char local_text[sizeof(symbol->text)] = {0};
- to_iso8859_1(symbol->text, local_text);
- /* Put the human readable text at the bottom (or top if EAN-2/5) */
- draw_string(pixelbuf, local_text, text_xposn, text_yposn, textflags, image_width, image_height, si);
- /* EAN-2/5 */
- if (upceanflag && upcean_guard_whitespace) {
- const int ean_width_adj = (UPCEAN_FONT_WIDTH + 3) / 4;
- const int addon_len = (int) ustrlen(symbol->text);
- text_xposn = (int) (((addon_len == 2 ? 19 : 46) + 0.5f + ean_width_adj) * si) + xoffset_si;
- draw_string(pixelbuf, (const unsigned char *) ">", text_xposn, text_yposn, textflags,
- image_width, image_height, si);
+ int text_xposn = (int) ((main_width / 2.0f) * si) + xoffset_si;
+ int text_yposn = yoffset_si + symbol_height_si + (int) (symbol->text_gap * si);
+ if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) {
+ text_yposn += symbol->border_width * si; /* Note not needed for BARCODE_BIND_TOP */
}
+ to_iso8859_1(symbol->text, local_text);
+ /* Put the human readable text at the bottom */
+ draw_string(pixelbuf, local_text, -1, text_xposn, text_yposn, textflags, image_width, image_height, si);
}
}
@@ -1306,7 +1330,7 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
}
draw_bind_box(symbol, pixelbuf, xoffset_si, yoffset_si, symbol_height_si, 0 /*dot_overspill_si*/,
- image_width, image_height, si);
+ upceanflag, (int) (textoffset * si), image_width, image_height, si);
if (!half_int_scaling) {
size_t prev_image_row;
@@ -1317,7 +1341,7 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
/* Apply scale options by creating another pixel buffer */
if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) {
free(pixelbuf);
- strcpy(symbol->errtxt, "659: Insufficient memory for pixel buffer");
+ strcpy(symbol->errtxt, "659: Insufficient memory for scaled pixel buffer");
return ZINT_ERROR_MEMORY;
}
memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height);
diff --git a/backend/rss.c b/backend/rss.c
index 8c34cbdb..4c54d2c1 100644
--- a/backend/rss.c
+++ b/backend/rss.c
@@ -1260,7 +1260,7 @@ static void dbar_exp_hrt(struct zint_symbol *symbol, unsigned char source[], con
/* GS1 DataBar Expanded, setting linkage for composite if `cc_rows` set */
INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_rows) {
- int error_number, warn_number = 0;
+ int error_number, warn_number;
int i, j, k, p, codeblocks, data_chars, vs, group, v_odd, v_even;
int latch;
int char_widths[21][8], checksum, check_widths[8], c_group;
@@ -1592,17 +1592,17 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int
symbol->height = symbol->height ? 34.0f : 34.0f * stack_rows; /* Pass back min row or default height */
} else {
if (symbol->output_options & COMPLIANT_HEIGHT) {
- if (warn_number) {
- (void) set_height(symbol, 34.0f, 34.0f * stack_rows, 0.0f, 0 /*no_errtxt*/);
- } else {
+ if (warn_number == 0) {
warn_number = set_height(symbol, 34.0f, 34.0f * stack_rows, 0.0f, 0 /*no_errtxt*/);
+ } else {
+ (void) set_height(symbol, 34.0f, 34.0f * stack_rows, 0.0f, 1 /*no_errtxt*/);
}
} else {
(void) set_height(symbol, 0.0f, 34.0f * stack_rows, 0.0f, 1 /*no_errtxt*/);
}
}
- return error_number ? error_number : warn_number;
+ return warn_number;
}
/* GS1 DataBar Expanded */
diff --git a/backend/svg.c b/backend/svg.c
index e3b1c47e..ebd396f7 100644
--- a/backend/svg.c
+++ b/backend/svg.c
@@ -112,8 +112,8 @@ static void svg_put_opacity_close(const unsigned char alpha, const float val, co
}
INTERNAL int svg_plot(struct zint_symbol *symbol) {
- static const char normal_font_family[] = "Arimo, Arial, sans-serif";
- static const char upcean_font_family[] = "OCRB, monospace";
+ static const char normal_font_family[] = "Arimo";
+ static const char upcean_font_family[] = "OCRB";
FILE *fsvg;
int error_number = 0;
float previous_diameter;
@@ -134,7 +134,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
char colour_code[7];
int len, html_len;
- const int extendable = is_extendable(symbol->symbology);
+ const int upcean = is_upcean(symbol->symbology);
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT;
char *html_string;
@@ -193,7 +193,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
fputs(" Zint Generated Symbol\n", fsvg);
if ((symbol->output_options & EMBED_VECTOR_FONT) && symbol->vector->strings) {
fprintf(fsvg, " \n",
- extendable ? "OCRB" : "Arimo", extendable ? upcean_woff2 : normal_woff2);
+ upcean ? "OCRB" : "Arimo", upcean ? upcean_woff2 : normal_woff2);
}
fprintf(fsvg, " \n", fgcolour_string);
@@ -241,9 +241,9 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
while (hex) {
if (previous_diameter != hex->diameter) {
previous_diameter = hex->diameter;
- radius = (float) (0.5 * previous_diameter);
- half_radius = (float) (0.25 * previous_diameter);
- half_sqrt3_radius = (float) (0.43301270189221932338 * previous_diameter);
+ radius = 0.5f * previous_diameter;
+ half_radius = 0.25f * previous_diameter;
+ half_sqrt3_radius = 0.43301270189221932338f * previous_diameter;
}
if ((hex->rotation == 0) || (hex->rotation == 180)) {
out_putsf("M", 2, hex->x, fsvg);
@@ -284,7 +284,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
while (circle) {
if (previous_diameter != circle->diameter) {
previous_diameter = circle->diameter;
- radius = (float) (0.5 * previous_diameter);
+ radius = 0.5f * previous_diameter;
}
fputs(" x, fsvg);
@@ -312,7 +312,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
circle = circle->next;
}
- bold = (symbol->output_options & BOLD_TEXT) && !extendable;
+ bold = (symbol->output_options & BOLD_TEXT) && !upcean;
string = symbol->vector->strings;
while (string) {
const char *const halign = string->halign == 2 ? "end" : string->halign == 1 ? "start" : "middle";
@@ -320,7 +320,11 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
svg_put_fattrib(" x=\"", 2, string->x, fsvg);
svg_put_fattrib(" y=\"", 2, string->y, fsvg);
fprintf(fsvg, " text-anchor=\"%s\"", halign);
- fprintf(fsvg, " font-family=\"%s\"", extendable ? upcean_font_family : normal_font_family);
+ if (upcean) {
+ fprintf(fsvg, " font-family=\"%s, monospace\"", upcean_font_family);
+ } else {
+ fprintf(fsvg, " font-family=\"%s, Arial, sans-serif\"", normal_font_family);
+ }
svg_put_fattrib(" font-size=\"", 1, string->fsize, fsvg);
if (bold) {
fputs(" font-weight=\"bold\"", fsvg);
diff --git a/backend/tests/data/gif/dpd_compliant.gif b/backend/tests/data/gif/dpd_compliant.gif
index c269549d..1cacc7ed 100644
Binary files a/backend/tests/data/gif/dpd_compliant.gif and b/backend/tests/data/gif/dpd_compliant.gif differ
diff --git a/backend/tests/data/gif/itf14_height0.5_1.1.gif b/backend/tests/data/gif/itf14_height0.5_1.1.gif
index 3696cac9..396bae1e 100644
Binary files a/backend/tests/data/gif/itf14_height0.5_1.1.gif and b/backend/tests/data/gif/itf14_height0.5_1.1.gif differ
diff --git a/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif b/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif
index 91154bdf..a443cd3e 100644
Binary files a/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif and b/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif differ
diff --git a/backend/tests/data/pcx/code11_fgbgtrans.pcx b/backend/tests/data/pcx/code11_fgbgtrans.pcx
index 38674d8c..67b53a87 100644
Binary files a/backend/tests/data/pcx/code11_fgbgtrans.pcx and b/backend/tests/data/pcx/code11_fgbgtrans.pcx differ
diff --git a/backend/tests/data/png/code128_egrave_bold.png b/backend/tests/data/png/code128_egrave_bold.png
index 53fe08d4..71925a04 100644
Binary files a/backend/tests/data/png/code128_egrave_bold.png and b/backend/tests/data/png/code128_egrave_bold.png differ
diff --git a/backend/tests/data/png/code128_egrave_bold_box3.png b/backend/tests/data/png/code128_egrave_bold_box3.png
index ac9fb05d..ee6949ef 100644
Binary files a/backend/tests/data/png/code128_egrave_bold_box3.png and b/backend/tests/data/png/code128_egrave_bold_box3.png differ
diff --git a/backend/tests/data/png/code128_egrave_bold_hvwsp2_box2.png b/backend/tests/data/png/code128_egrave_bold_hvwsp2_box2.png
index 2149dbb4..0c6382e4 100644
Binary files a/backend/tests/data/png/code128_egrave_bold_hvwsp2_box2.png and b/backend/tests/data/png/code128_egrave_bold_hvwsp2_box2.png differ
diff --git a/backend/tests/data/png/code39_small.png b/backend/tests/data/png/code39_small.png
index 45d9813f..772f35c9 100644
Binary files a/backend/tests/data/png/code39_small.png and b/backend/tests/data/png/code39_small.png differ
diff --git a/backend/tests/data/png/dbar_ltd.png b/backend/tests/data/png/dbar_ltd.png
index 0f2b2a76..4aaa7310 100644
Binary files a/backend/tests/data/png/dbar_ltd.png and b/backend/tests/data/png/dbar_ltd.png differ
diff --git a/backend/tests/data/png/dpd_compliant.png b/backend/tests/data/png/dpd_compliant.png
index 16ef4964..3c919106 100644
Binary files a/backend/tests/data/png/dpd_compliant.png and b/backend/tests/data/png/dpd_compliant.png differ
diff --git a/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png b/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png
index 3d8a4377..dd3ec1e9 100644
Binary files a/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png and b/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png differ
diff --git a/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2_gws.png b/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2_gws.png
index e2f9c3c5..68c37a59 100644
Binary files a/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2_gws.png and b/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2_gws.png differ
diff --git a/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2.png b/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2.png
index 878d837f..d201c0ad 100644
Binary files a/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2.png and b/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2.png differ
diff --git a/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2_gws.png b/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2_gws.png
index 1cf66fd8..d18716ef 100644
Binary files a/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2_gws.png and b/backend/tests/data/png/ean13_5addon_ggs_5.2.2.5.2-2_gws.png differ
diff --git a/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png b/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png
index 053015a7..a41a9ffb 100644
Binary files a/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png and b/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png differ
diff --git a/backend/tests/data/png/ean13_cc_2addon_cca_4x4_gws.png b/backend/tests/data/png/ean13_cc_2addon_cca_4x4_gws.png
index 301cf7ea..da079812 100644
Binary files a/backend/tests/data/png/ean13_cc_2addon_cca_4x4_gws.png and b/backend/tests/data/png/ean13_cc_2addon_cca_4x4_gws.png differ
diff --git a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png
index 134ccabb..68e108aa 100644
Binary files a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png and b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png differ
diff --git a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_gws.png b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_gws.png
index 13de53ea..a539bf98 100644
Binary files a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_gws.png and b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_gws.png differ
diff --git a/backend/tests/data/png/ean13_cc_cca_5x4.png b/backend/tests/data/png/ean13_cc_cca_5x4.png
index 6979fe29..4b540986 100644
Binary files a/backend/tests/data/png/ean13_cc_cca_5x4.png and b/backend/tests/data/png/ean13_cc_cca_5x4.png differ
diff --git a/backend/tests/data/png/ean13_cc_cca_5x4_gws.png b/backend/tests/data/png/ean13_cc_cca_5x4_gws.png
index 5baea87d..75a604e3 100644
Binary files a/backend/tests/data/png/ean13_cc_cca_5x4_gws.png and b/backend/tests/data/png/ean13_cc_cca_5x4_gws.png differ
diff --git a/backend/tests/data/png/ean13_ggs_5.2.2.1-1.png b/backend/tests/data/png/ean13_ggs_5.2.2.1-1.png
index e199d482..f9335ec6 100644
Binary files a/backend/tests/data/png/ean13_ggs_5.2.2.1-1.png and b/backend/tests/data/png/ean13_ggs_5.2.2.1-1.png differ
diff --git a/backend/tests/data/png/ean13_ggs_5.2.2.1-1_gws.png b/backend/tests/data/png/ean13_ggs_5.2.2.1-1_gws.png
index dfa0c5ba..5edb720f 100644
Binary files a/backend/tests/data/png/ean13_ggs_5.2.2.1-1_gws.png and b/backend/tests/data/png/ean13_ggs_5.2.2.1-1_gws.png differ
diff --git a/backend/tests/data/png/ean2_box1.png b/backend/tests/data/png/ean2_box1.png
new file mode 100644
index 00000000..08e27c6d
Binary files /dev/null and b/backend/tests/data/png/ean2_box1.png differ
diff --git a/backend/tests/data/png/ean5_bind2.png b/backend/tests/data/png/ean5_bind2.png
new file mode 100644
index 00000000..5449192a
Binary files /dev/null and b/backend/tests/data/png/ean5_bind2.png differ
diff --git a/backend/tests/data/png/ean8_5addon.png b/backend/tests/data/png/ean8_5addon.png
index 3175a8f2..5453beac 100644
Binary files a/backend/tests/data/png/ean8_5addon.png and b/backend/tests/data/png/ean8_5addon.png differ
diff --git a/backend/tests/data/png/ean8_5addon_gws.png b/backend/tests/data/png/ean8_5addon_gws.png
index 341c9ad1..04a3cdb7 100644
Binary files a/backend/tests/data/png/ean8_5addon_gws.png and b/backend/tests/data/png/ean8_5addon_gws.png differ
diff --git a/backend/tests/data/png/ean8_cc_5addon_ccb_8x3.png b/backend/tests/data/png/ean8_cc_5addon_ccb_8x3.png
index 6c8d8f2c..7218b52d 100644
Binary files a/backend/tests/data/png/ean8_cc_5addon_ccb_8x3.png and b/backend/tests/data/png/ean8_cc_5addon_ccb_8x3.png differ
diff --git a/backend/tests/data/png/ean8_cc_5addon_ccb_8x3_gws.png b/backend/tests/data/png/ean8_cc_5addon_ccb_8x3_gws.png
index 93b9745c..d42212b3 100644
Binary files a/backend/tests/data/png/ean8_cc_5addon_ccb_8x3_gws.png and b/backend/tests/data/png/ean8_cc_5addon_ccb_8x3_gws.png differ
diff --git a/backend/tests/data/png/ultra_fgalpha_hvwsp1_bindtop1.png b/backend/tests/data/png/ultra_fgalpha_hvwsp1_bindtop1.png
index 2b0b07b3..76993026 100644
Binary files a/backend/tests/data/png/ultra_fgalpha_hvwsp1_bindtop1.png and b/backend/tests/data/png/ultra_fgalpha_hvwsp1_bindtop1.png differ
diff --git a/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png b/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png
index 6d4637ac..470e7c8e 100644
Binary files a/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png and b/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png differ
diff --git a/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5_gws.png b/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5_gws.png
index 4a5f978b..cf9c8d55 100644
Binary files a/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5_gws.png and b/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5_gws.png differ
diff --git a/backend/tests/data/png/upca_5addon.png b/backend/tests/data/png/upca_5addon.png
index 4727c528..76b4e836 100644
Binary files a/backend/tests/data/png/upca_5addon.png and b/backend/tests/data/png/upca_5addon.png differ
diff --git a/backend/tests/data/png/upca_5addon_bind3.png b/backend/tests/data/png/upca_5addon_bind3.png
index b6b976ff..76d9f8dc 100644
Binary files a/backend/tests/data/png/upca_5addon_bind3.png and b/backend/tests/data/png/upca_5addon_bind3.png differ
diff --git a/backend/tests/data/png/upca_5addon_gws.png b/backend/tests/data/png/upca_5addon_gws.png
index 1fec4fa6..024ff1c2 100644
Binary files a/backend/tests/data/png/upca_5addon_gws.png and b/backend/tests/data/png/upca_5addon_gws.png differ
diff --git a/backend/tests/data/png/upca_cc_2addon_cca_3x4.png b/backend/tests/data/png/upca_cc_2addon_cca_3x4.png
index 9ac85d77..2cde13bb 100644
Binary files a/backend/tests/data/png/upca_cc_2addon_cca_3x4.png and b/backend/tests/data/png/upca_cc_2addon_cca_3x4.png differ
diff --git a/backend/tests/data/png/upca_cc_2addon_cca_3x4_gws.png b/backend/tests/data/png/upca_cc_2addon_cca_3x4_gws.png
index 83c9b2df..9c94f855 100644
Binary files a/backend/tests/data/png/upca_cc_2addon_cca_3x4_gws.png and b/backend/tests/data/png/upca_cc_2addon_cca_3x4_gws.png differ
diff --git a/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png b/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png
index e29f97d7..ec9c175e 100644
Binary files a/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png and b/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png differ
diff --git a/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png b/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png
index 867a9df9..bd67e2fb 100644
Binary files a/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png and b/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png differ
diff --git a/backend/tests/data/png/upce_5addon.png b/backend/tests/data/png/upce_5addon.png
index a136d3d7..a43ee44b 100644
Binary files a/backend/tests/data/png/upce_5addon.png and b/backend/tests/data/png/upce_5addon.png differ
diff --git a/backend/tests/data/png/upce_5addon_small_gws.png b/backend/tests/data/png/upce_5addon_small_gws.png
index e8acd60a..8736c345 100644
Binary files a/backend/tests/data/png/upce_5addon_small_gws.png and b/backend/tests/data/png/upce_5addon_small_gws.png differ
diff --git a/backend/tests/data/png/upce_cc_5addon_ccb_8x2.png b/backend/tests/data/png/upce_cc_5addon_ccb_8x2.png
index f72a1310..aba27385 100644
Binary files a/backend/tests/data/png/upce_cc_5addon_ccb_8x2.png and b/backend/tests/data/png/upce_cc_5addon_ccb_8x2.png differ
diff --git a/backend/tests/data/png/upce_cc_5addon_ccb_8x2_gws.png b/backend/tests/data/png/upce_cc_5addon_ccb_8x2_gws.png
index b560b99f..7e8e5a17 100644
Binary files a/backend/tests/data/png/upce_cc_5addon_ccb_8x2_gws.png and b/backend/tests/data/png/upce_cc_5addon_ccb_8x2_gws.png differ
diff --git a/backend/tests/data/print/bmp/code128_aim.bmp b/backend/tests/data/print/bmp/code128_aim.bmp
index 60469426..54af89bd 100644
Binary files a/backend/tests/data/print/bmp/code128_aim.bmp and b/backend/tests/data/print/bmp/code128_aim.bmp differ
diff --git a/backend/tests/data/print/gif/code128_aim.gif b/backend/tests/data/print/gif/code128_aim.gif
index d51ac5a7..c7e7f7b4 100644
Binary files a/backend/tests/data/print/gif/code128_aim.gif and b/backend/tests/data/print/gif/code128_aim.gif differ
diff --git a/backend/tests/data/print/pcx/code128_aim.pcx b/backend/tests/data/print/pcx/code128_aim.pcx
index 899c3d35..99df00f8 100644
Binary files a/backend/tests/data/print/pcx/code128_aim.pcx and b/backend/tests/data/print/pcx/code128_aim.pcx differ
diff --git a/backend/tests/data/print/png/code128_aim.png b/backend/tests/data/print/png/code128_aim.png
index 252dcade..e59669ac 100644
Binary files a/backend/tests/data/print/png/code128_aim.png and b/backend/tests/data/print/png/code128_aim.png differ
diff --git a/backend/tests/data/print/tif/code128_aim.tif b/backend/tests/data/print/tif/code128_aim.tif
index 5cc663a5..a8f640a4 100644
Binary files a/backend/tests/data/print/tif/code128_aim.tif and b/backend/tests/data/print/tif/code128_aim.tif differ
diff --git a/backend/tests/data/svg/dpd_compliant.svg b/backend/tests/data/svg/dpd_compliant.svg
index 3f469a00..d9088fad 100644
--- a/backend/tests/data/svg/dpd_compliant.svg
+++ b/backend/tests/data/svg/dpd_compliant.svg
@@ -1,11 +1,11 @@
-
+
The scale is multiplied by 2 (with the exception of MaxiCode) before
+being applied to the X-dimension. For MaxiCode, it is multiplied by 10
+for raster output, by 40 for EMF vector output, and by 2 otherwise
+(non-EMF vector output).
For non-Maxicode raster output, the default scale of 1 results in an
X-dimension of 2 pixels. For example for non-Maxicode PNG images a scale
of 5 will increase the X-dimension to 10 pixels. For Maxicode, see
+0.5, giving a minimum X-dimension of 1 pixel. For MaxiCode, it is 0.2.
+The minimum scale for raster output in dotty mode is 1 (see 4.15 Working with Dots). For raster
+output, text will not be printed for scales less than 1.
The minimum scale for vector output is 0.1, giving a minimum
-X-dimension of 0.2 (or for Maxicode EMF output, 4).
-
The maximum scale for both raster and vector is 200.
-
Using measurable units to specify the X-dimension is often more
-useful, as discussed in the next section.
+X-dimension of 0.2 (or for Maxicode EMF output, 4). The maximum scale
+for both raster and vector is 200.
+
To summarize the more intricate details:
+
+
+
Table : Scaling Multipliers and Minima
+
+
+
+
+
+
+
+
+
+
MaxiCode?
+
Output
+
Multiplier
+
Min. Scale (non-dotty)
+
Min. Scale (dotty)
+
+
+
+
+
No
+
Raster
+
2
+
0.5
+
1
+
+
+
No
+
Vector
+
2
+
0.1
+
0.1
+
+
+
Yes
+
Raster
+
10
+
0.2
+
N/A
+
+
+
Yes
+
Vector (non-EMF)
+
2
+
0.1
+
N/A
+
+
+
Yes
+
EMF
+
40
+
0.1
+
N/A
+
+
+
+
4.9.1 Scaling by
X-dimension and Resolution
-
An alternative way to specify the scale which takes the above details
-into account and uses measurable units is to use the
+
An alternative way to specify the scale, which takes the above
+details into account, is to specify measurable units using the
--scalexdimdp option, which has the format
--scalexdimdp=X[,R]
where X is the X-dimension (in mm by default) and
@@ -2321,9 +2379,10 @@ alt="zint --bold -d "This Text" --small" />
aria-hidden="true">zint --bold -d "This Text" --small
The gap between the barcode and the text can be adjusted using the
---textgap option, where the gap is given in X-dimensions
-(maximum 10X). A zero value uses the default gap (1X). Note that a very
-small gap may cause accented texts to overlap with the barcode:
+--textgap option, where the gap is given in X-dimensions,
+and may be negative (minimum -5X, maximum 10X). The default gap is 1X.
+Note that a very small gap may cause accented texts to overlap with the
+barcode: