zint.h: increase symbol->text size 160 -> 200;

rename `ZINT_CAP_EXTENDABLE` -> `ZINT_CAP_EANUPC`
  (`ZINT_CAP_EXTENDABLE` marked as legacy)
CODE128: increase no. symbol chars max 60 -> 99
EAN-2/EAN-5: fix `BARCODE_BIND_TOP/BIND/BOX` output
GS1_128: warn if data > 48 (GS1 General Specifications max)
common: `is_extendable()` -> `is_ucpean()`
raster: add `ZFONT_HALIGN_CENTRE/LEFT/RIGHT` flags and process
  in `draw_string()` (for drawing EAN/UPC outside digits), and
  for `ZFONT_HALIGN_CENTRE` round when calculating centre
  (shifts some texts 1 pixel left)
raster/vector: use offsets into `symbol->text` for EAN/UPC
  instead of `out_upcean_split_text()` (removed)
BMP/EMF/GIF/PCX/PNG/PS/SVG/TIF: use new `out_colour_get_rgb()`
  routine (replaces `colour_to_XXX()`)
general: simplify/fix some `error_number` handling/returning
frontend: truncate overlong `--primary` instead of ignoring;
  negative floating pt option (for `--textgap`)
man page: list size detail for matrix symbols (`--vers`)
manual: further fiddling with scaling text; some typos
This commit is contained in:
gitlost
2023-11-19 19:39:54 +00:00
parent ca964f9098
commit 323b34502b
113 changed files with 2016 additions and 1550 deletions

View File

@ -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 : */