CODE128: hrt always UTF-8; CODE128/EXCODE39/CODE93: blank same NUL/ctrl/DEL chars

This commit is contained in:
gitlost 2020-07-19 00:13:03 +01:00
parent 020a125de6
commit dd2bdb4335
14 changed files with 233 additions and 133 deletions

View file

@ -391,7 +391,7 @@ INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length
error_number = c39(symbol, buffer, ustrlen(buffer));
for (i = 0; i < length; i++)
symbol->text[i] = source[i] ? source[i] : ' ';
symbol->text[i] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' ';
symbol->text[length] = '\0';
return error_number;
@ -426,7 +426,7 @@ INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length)
return ZINT_ERROR_INVALID_DATA;
}
strcat(buffer, C93Ctrl[source[i]]);
symbol->text[i] = source[i] ? source[i] : ' ';
symbol->text[i] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' ';
}
/* Now we can check the true length of the barcode */

View file

@ -259,6 +259,39 @@ static void c128_set_c(unsigned char source_a, unsigned char source_b, char dest
(*bar_chars)++;
}
/* Treats source as ISO 8859-1 and copies into symbol->text, converting to UTF-8. Returns length of symbol->text */
STATIC_UNLESS_ZINT_TEST int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, int source_len) {
int i, j;
for (i = 0, j = 0; i < source_len && j < (int) sizeof(symbol->text); i++) {
if (source[i] < 0x80) {
symbol->text[j++] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' ';
} else if (source[i] < 0xC0) {
if (source[i] >= 0xA0) { /* 0x80-0x9F not valid ISO 8859-1 */
if (j + 2 >= (int) sizeof(symbol->text)) {
break;
}
symbol->text[j++] = 0xC2;
symbol->text[j++] = source[i];
} else {
symbol->text[j++] = ' ';
}
} else {
if (j + 2 >= (int) sizeof(symbol->text)) {
break;
}
symbol->text[j++] = 0xC3;
symbol->text[j++] = source[i] - 0x40;
}
}
if (j == sizeof(symbol->text)) {
j--;
}
symbol->text[j] = '\0';
return j;
}
/* Handle Code 128, 128B and HIBC 128 */
INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length) {
int i, j, k, values[C128_MAX] = {0}, bar_characters, read, total_sum;
@ -656,6 +689,9 @@ INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[],
#endif
expand(symbol, dest);
hrt_cpy_iso8859_1(symbol, source, length);
return error_number;
}

View file

@ -970,7 +970,7 @@ static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_
}
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int in_length) {
int error_number, error_buffer, i;
int error_number, error_buffer;
#ifdef _MSC_VER
unsigned char* local_source;
#endif
@ -1206,15 +1206,6 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
}
if (error_number == 0) {
if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) {
for (i = 0; i < in_length; i++) {
if (local_source[i] == '\0') {
symbol->text[i] = ' ';
} else {
symbol->text[i] = local_source[i];
}
}
}
error_number = error_buffer;
}
error_tag(symbol->errtxt, error_number);

View file

@ -643,8 +643,8 @@ static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int d
return error_number;
}
/* Convert UTF-8 to Latin1 Codepage for the interpretation line */
static void to_latin1(const unsigned char source[], unsigned char preprocessed[]) {
/* Convert UTF-8 to ISO 8859-1 for draw_string() human readable text */
static void to_iso8859_1(const unsigned char source[], unsigned char preprocessed[]) {
int j, i, input_length;
input_length = ustrlen(source);
@ -959,7 +959,7 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int
#else
unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1);
#endif
to_latin1(symbol->text, local_text);
to_iso8859_1(symbol->text, local_text);
/* Put the human readable text at the bottom */
textpos = 2 * (main_width / 2 + xoffset);
draw_string(pixelbuf, local_text, textpos, default_text_posn, textflags, image_width, image_height);

View file

@ -126,14 +126,14 @@ static void test_hrt(int index, int debug) {
/* 7*/ { BARCODE_EXCODE39, -1, "ABC1234", -1, "ABC1234" },
/* 8*/ { BARCODE_EXCODE39, -1, "abc1234", -1, "abc1234" },
/* 9*/ { BARCODE_EXCODE39, 1, "abc1234", -1, "abc1234" }, // With checksum (not displayed)
/* 10*/ { BARCODE_EXCODE39, -1, "a%\000\001$\177z\033\037!+/\\@A~", 16, "a% \001$\177z\033\037!+/\\@A~" }, // NUL replaced with space
/* 10*/ { BARCODE_EXCODE39, -1, "a%\000\001$\177z\033\037!+/\\@A~", 16, "a% $ z !+/\\@A~" }, // NUL, ctrls and DEL replaced with spaces
/* 11*/ { BARCODE_LOGMARS, -1, "ABC1234", -1, "ABC1234" },
/* 12*/ { BARCODE_LOGMARS, -1, "abc1234", -1, "ABC1234" }, // Converts to upper
/* 13*/ { BARCODE_LOGMARS, 1, "abc1234", -1, "ABC12340" }, // With checksum
/* 14*/ { BARCODE_LOGMARS, 1, "12345/ABCDE", -1, "12345/ABCDET" }, // With checksum
/* 15*/ { BARCODE_CODE93, -1, "ABC1234", -1, "ABC1234S5" }, // 2 checksums added (note check digits not shown by bwipp or tec-it)
/* 16*/ { BARCODE_CODE93, -1, "abc1234", -1, "abc1234ZG" },
/* 17*/ { BARCODE_CODE93, -1, "A\001a\000b\177d\037e", 9, "A\001a b\177d\037e1R" }, // NUL replaced with space
/* 17*/ { BARCODE_CODE93, -1, "A\001a\000b\177d\037e", 9, "A a b d e1R" }, // NUL, ctrls and DEL replaced with spaces
/* 18*/ { BARCODE_PZN, -1, "12345", -1, "PZN -00123458" }, // Pads with zeroes if length < 7
/* 19*/ { BARCODE_PZN, -1, "123456", -1, "PZN -01234562" },
/* 20*/ { BARCODE_PZN, -1, "1234567", -1, "PZN -12345678" },

View file

@ -100,6 +100,64 @@ static void test_large(int index, int debug) {
testFinish();
}
int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, int source_len);
static void test_hrt_cpy_iso8859_1(int index, int debug) {
testStart("");
int ret;
struct item {
unsigned char *data;
int length;
int ret;
char *expected;
char *comment;
};
// NBSP U+00A0 (\240, 160), UTF-8 C2A0 (\302\240)
// é U+00E9 (\351, 233), UTF-8 C3A9
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "", -1, 0, "", "" },
/* 1*/ { "abc", -1, 3, "abc", "" },
/* 2*/ { "\000A\001B\002\036\037C ~\177", 11, 11, " A B C ~ ", "" },
/* 3*/ { "~\177\200\201\237\240", -1, 7, "~ \302\240", "" },
/* 4*/ { "\241\242\243\244\257\260", -1, 12, "¡¢£¤¯°", "" },
/* 5*/ { "\276\277\300\337\377", -1, 10, "¾¿Àßÿ", "" },
/* 6*/ { "\351", -1, 2, "é", "" },
/* 7*/ { "\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351", -1, 126, "ééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "126 \351" },
/* 8*/ { "a\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351", -1, 127, "aééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "a + 126 \351" },
/* 9*/ { "\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351a", -1, 127, "éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééa", "126 \351 + a" },
/* 10*/ { "\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351", -1, 126, "ééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "127 \351 (truncated)" },
/* 11*/ { "a\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351", -1, 127, "aééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "a + 127 \351 (truncated)" },
/* 12*/ { "\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351a", -1, 126, "ééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "127 \351 + a (truncated)" },
/* 13*/ { "\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351\351", -1, 126, "ééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé", "128 \351 (truncated)" },
};
int data_size = ARRAY_SIZE(data);
int vals[20];
struct zint_symbol symbol;
symbol.debug |= debug;
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
int length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
ret = hrt_cpy_iso8859_1(&symbol, data[i].data, length);
for (int j = 0; j < ret; j++) {
//fprintf(stderr, "symbol.text[%d] %2X\n", j, symbol.text[j]);
}
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
assert_equal(ret, (int) strlen(symbol.text), "i:%d ret %d != strlen %d\n", i, ret, (int) strlen(symbol.text));
assert_nonzero(testUtilIsValidUTF8(symbol.text, strlen(symbol.text)), "i:%d testUtilIsValidUTF8(%s) != 1\n", i, symbol.text);
assert_zero(strcmp(symbol.text, data[i].expected), "i:%d symbol.text (%s) != expected (%s)\n", i, symbol.text, data[i].expected);
}
testFinish();
}
static void test_hrt(int index, int debug) {
testStart("");
@ -119,11 +177,11 @@ static void test_hrt(int index, int debug) {
/* 0*/ { BARCODE_CODE128, UNICODE_MODE, "1234567890", -1, "1234567890" },
/* 1*/ { BARCODE_CODE128, UNICODE_MODE, "\000ABC\000DEF\000", 9, " ABC DEF " },
/* 2*/ { BARCODE_CODE128B, UNICODE_MODE, "12345\00067890", 11, "12345 67890" },
/* 3*/ { BARCODE_CODE128, UNICODE_MODE, "12345\01167890\037\177", -1, "12345\01167890\037\177" },
/* 3*/ { BARCODE_CODE128, UNICODE_MODE, "12345\01167890\037\177", -1, "12345 67890 " },
/* 4*/ { BARCODE_CODE128, UNICODE_MODE, "abcdé", -1, "abcdé" },
/* 5*/ { BARCODE_CODE128, DATA_MODE, "abcd\351", -1, "abcd\351" },
/* 5*/ { BARCODE_CODE128, DATA_MODE, "abcd\351", -1, "abcdé" },
/* 6*/ { BARCODE_CODE128B, UNICODE_MODE, "abcdé", -1, "abcdé" },
/* 7*/ { BARCODE_CODE128B, DATA_MODE, "abcd\351", -1, "abcd\351" },
/* 7*/ { BARCODE_CODE128B, DATA_MODE, "abcd\351", -1, "abcdé" },
/* 8*/ { BARCODE_HIBC_128, UNICODE_MODE, "1234567890", -1, "*+12345678900*" },
/* 9*/ { BARCODE_HIBC_128, UNICODE_MODE, "a99912345", -1, "*+A999123457*" }, // Converts to upper
// BARCODE_EAN128, BARCODE_EAN14, BARCODE_NVE18 hrt tested in test_gs1.c
@ -627,6 +685,7 @@ int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_large", test_large, 1, 0, 1 },
{ "test_hrt_cpy_iso8859_1", test_hrt_cpy_iso8859_1, 1, 0, 1 },
{ "test_hrt", test_hrt, 1, 0, 1 },
{ "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 },

View file

@ -448,7 +448,7 @@ static void test_row_separator(int index, int debug) {
/* 4*/ { BARCODE_CODABLOCKF, -1, 3, "A", 0, 20, 2, 101, 242, 44, 19, 42, 6 },
/* 5*/ { BARCODE_CODABLOCKF, -1, 4, "A", 0, 20, 2, 101, 242, 44, 18, 42, 8 },
/* 6*/ { BARCODE_CODABLOCKF, -1, 5, "A", 0, 20, 2, 101, 242, 44, 21, 42, 2 }, // > 4 ignored, same as default
/* 7*/ { BARCODE_CODABLOCKF, 1, -1, "A", 0, 5, 1, 46, 132, 14, 0, 20 + 2, 2 }, // CODE128 top separator, add 2 to skip over end of start char
/* 7*/ { BARCODE_CODABLOCKF, 1, -1, "A", 0, 5, 1, 46, 132, 32, 0, 20 + 2, 2 }, // CODE128 top separator, add 2 to skip over end of start char; note now includes HRT
};
int data_size = ARRAY_SIZE(data);

View file

@ -83,6 +83,7 @@ char *testUtilInputModeName(int input_mode);
char *testUtilOption3Name(int option_3);
char *testUtilOutputOptionsName(int output_options);
int testUtilDAFTConvert(const struct zint_symbol *symbol, char *buffer, int buffer_size);
int testUtilIsValidUTF8(const unsigned char str[], const size_t length);
char *testUtilEscape(char *buffer, int length, char *escaped, int escaped_size);
char *testUtilReadCSVField(char *buffer, char *field, int field_size);
void testUtilStrCpyRepeat(char *buffer, char *repeat, int size);

View file

@ -294,7 +294,6 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
struct zint_vector_hexagon *last_hexagon = NULL;
struct zint_vector_string *last_string = NULL;
struct zint_vector_circle *last_circle = NULL;
struct zint_vector_string *string;
(void)rotate_angle; /* Not currently implemented */
@ -629,17 +628,6 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
/* Put normal human readable text at the bottom (and centered) */
// calculate start xoffset to center text
vector_plot_add_string(symbol, symbol->text, main_width / 2.0 + xoffset, default_text_posn, text_height, symbol->width, &last_string);
// Remove control characters from readable text
// This only applies to Code 128
string = symbol->vector->strings;
if (string) {
for (i = 0; i < string->length; i++) {
if (string->text[i] < ' ') {
string->text[i] = ' ';
}
}
}
}
xoffset -= comp_offset; // Restore xoffset

View file

@ -118,7 +118,7 @@ extern "C" {
int fontsize;
int input_mode;
int eci;
unsigned char text[128];
unsigned char text[128]; /* UTF-8 */
int rows;
int width;
char primary[128];
@ -337,4 +337,3 @@ extern "C" {
#endif /* __cplusplus */
#endif /* ZINT_H */