diff --git a/backend/code.c b/backend/code.c index 74005a92..ae3d31a0 100644 --- a/backend/code.c +++ b/backend/code.c @@ -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 */ diff --git a/backend/code128.c b/backend/code128.c index 65dae265..96fd272e 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -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; } diff --git a/backend/library.c b/backend/library.c index 3576b6ee..811462e9 100644 --- a/backend/library.c +++ b/backend/library.c @@ -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); diff --git a/backend/raster.c b/backend/raster.c index c15c26d8..569783d3 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -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); diff --git a/backend/tests/test_code.c b/backend/tests/test_code.c index 50cd81a9..3c287b12 100644 --- a/backend/tests/test_code.c +++ b/backend/tests/test_code.c @@ -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" }, diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index acbb2a31..627a4d51 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -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 }, diff --git a/backend/tests/test_raster.c b/backend/tests/test_raster.c index 2efb8d33..003933d3 100644 --- a/backend/tests/test_raster.c +++ b/backend/tests/test_raster.c @@ -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); diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index ac690b8a..75678f5b 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -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); diff --git a/backend/vector.c b/backend/vector.c index 2c1a91bd..b1a28b34 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -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 diff --git a/backend/zint.h b/backend/zint.h index 4d28369d..f261bbe3 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -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 */ - diff --git a/docs/manual.txt b/docs/manual.txt index 8afccfc6..525e6d63 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -812,72 +812,76 @@ program, of course, these options can be altered. The way this is done is by altering the contents of the zint_symbol structure between the creation and encoding stages. The zint_symbol structure consists of the following variables: -------------------------------------------------------------------------------- -Variable Name | Type | Meaning | Default Value -------------------------------------------------------------------------------- -symbology | integer | Symbol to use (see section | BARCODE_CODE128 - | | 5.7). | -height | integer | Symbol height. [1] | 50 -whitespace_width | integer | Whtespace width. | 0 -border_width | integer | Border width. | 0 -output_options | integer | Set various output file | (none) - | | parameters (see section | - | | 5.8). | -fgcolour | character | Foreground (ink) colour as | "000000" - | string | RGB hexadecimal string. | - | | Must be 6 characters | - | | followed by terminating | - | | \0 character. | -bgcolour | character | Background (paper) colour | "ffffff" - | string | as RGB hexadecimal | - | | string. Must be 6 chara- | - | | ters followed by termin- | - | | ating \0 character. | -outfile | character | Contains the name of the | "out.png" - | string | file to output a result- | - | | ing barcode symbol to. | - | | Must end in .png, .gif, | - | | .bmp, .emf, .eps, .pcx, | - | | .svg, .tif or .txt | -option_1 | integer | Symbol specific options. | (automatic) -option_2 | integer | Symbol specific options. | (automatic) -option_3 | integer | Symbol specific options. | (automatic) -scale | float | Scale factor for adjusting | 1.0 - | | size of image. | -input_mode | integer | Set encoding of input data | UNICODE_MODE - | | (see section 5.9) | -eci | integer | Extended Channel Interpre- | 0 (none) - | | tation code. | -primary | character | Primary message data for | NULL - | string | more complex symbols. | -text | unsigned | Human readable text, which | NULL - | character | usually consists of in- | - | string | put data plus one more | - | | check digit. Uses UTF-8 | - | | formatting. | -show_hrt | integer | Set to 0 to hide text. | 1 -dot_size | float | Size of dots used in dotty | 4.0 / 5.0 - | | mode. | -rows | integer | Number of rows used by the | (output only) - | | the symbol. | -width | integer | Width of the generated sym- | (output only) - | | bol. | -encoding_data | array of | Representation of the | (output only) - | character | encoded data. | - | strings | | -row_height | array of | Representation of the | (output only) - | integers | height of a row. | -errtxt | character | Error message in the event | (output only) - | string | that an error ocurred. | -bitmap | pointer to | Pointer to stored bitmap | (output only) - | unsigned | image. | - | character | | - | array | | -bitmap_width | integer | Width of stored bitmap | (output only) - | | image (in pixels). | -bitmap_height | integer | Height of stored bitmap | (output only) - | | image (in pixels). | -------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +Variable Name | Type | Meaning | Default Value +-------------------------------------------------------------------------------- +symbology | integer | Symbol to use (see section | BARCODE_CODE128 + | | 5.7). | +height | integer | Symbol height. [1] | 50 +whitespace_width | integer | Whtespace width. | 0 +border_width | integer | Border width. | 0 +output_options | integer | Set various output file | 0 (none) + | | parameters (see section | + | | 5.8). | +fgcolour | character | Foreground (ink) colour as | "000000" + | string | RGB hexadecimal string. | + | | Must be 6 characters | + | | followed by terminating | + | | \0 character. | +bgcolour | character | Background (paper) colour | "ffffff" + | string | as RGB hexadecimal | + | | string. Must be 6 chara- | + | | ters followed by termin- | + | | ating \0 character. | +outfile | character | Contains the name of the | "out.png" + | string | file to output a result- | + | | ing barcode symbol to. | + | | Must end in .png, .gif, | + | | .bmp, .emf, .eps, .pcx, | + | | .svg, .tif or .txt | +scale | float | Scale factor for adjusting | 1.0 + | | size of image. | +option_1 | integer | Symbol specific options. | -1 +option_2 | integer | Symbol specific options. | 0 +option_3 | integer | Symbol specific options. | 0 +show_hrt | integer | Set to 0 to hide text. | 1 +input_mode | integer | Set encoding of input data | DATA_MODE + | | (see section 5.9) | +eci | integer | Extended Channel Interpre- | 0 (none) + | | tation code. | +text | unsigned | Human readable text, which | "" (empty) + | character | usually consists of in- | + | string | put data plus one more | + | | check digit. Uses UTF-8 | + | | formatting. | +primary | character | Primary message data for | "" (empty) + | string | more complex symbols. | +dot_size | float | Size of dots used in dotty | 4.0 / 5.0 + | | mode. | +rows | integer | Number of rows used by the | (output only) + | | the symbol. | +width | integer | Width of the generated sym- | (output only) + | | bol. | +encoding_data | array of | Representation of the | (output only) + | character | encoded data. | + | strings | | +row_height | array of | Representation of the | (output only) + | integers | height of a row. | +errtxt | character | Error message in the event | (output only) + | string | that an error ocurred. | +bitmap | pointer to | Pointer to stored bitmap | (output only) + | unsigned | image. | + | character | | + | array | | +bitmap_width | integer | Width of stored bitmap | (output only) + | | image (in pixels). | +bitmap_height | integer | Height of stored bitmap | (output only) + | | image (in pixels). | +bitmap_byte_length| integer | Size of BMP bitmap data. | (output only) +vector | pointer to | Pointer to vector header | (output only) + | vector | containing pointers to | + | structure | vector elements. | +-------------------------------------------------------------------------------- To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and @@ -1127,14 +1131,14 @@ GS1_MODE | Encodes GS1 data using FNC1 characters. ESCAPE_MODE | Process input data for escape sequences. ----------------------------------------------------------------------------- -DATA_MODE, UNICODE_MODE and GS1_MODE are mutually exclusive, whereas -ESCAPE_MODE is optional. So, for example, you can set +DATA_MODE, UNICODE_MODE and GS1_MODE are mutually exclusive, whereas ESCAPE_MODE +is optional. So, for example, you can set -my_symbol->input_mode = UNICODE_MODE + ESCAPE_MODE; +my_symbol->input_mode = UNICODE_MODE | ESCAPE_MODE; whereas -my_symbol->input_mode = DATA_MODE + GS1_MODE; +my_symbol->input_mode = DATA_MODE | GS1_MODE; is not valid. Permissible escape sequences are listed in section 4.1. diff --git a/frontend_qt/mainWindow.ui b/frontend_qt/mainWindow.ui index 558524e6..3957df64 100644 --- a/frontend_qt/mainWindow.ui +++ b/frontend_qt/mainWindow.ui @@ -322,14 +322,28 @@ p, li { white-space: pre-wrap; } - - - Parse Escape Sequences - - - false - - + + + + + Parse Escape Sequences + + + false + + + + + + + Data (binary) &Mode + + + false + + + + diff --git a/frontend_qt/mainwindow.cpp b/frontend_qt/mainwindow.cpp index 61dcb1ea..35457038 100644 --- a/frontend_qt/mainwindow.cpp +++ b/frontend_qt/mainwindow.cpp @@ -161,6 +161,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags fl) connect(chkComposite, SIGNAL(stateChanged( int )), SLOT(update_preview())); connect(cmbCompType, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(chkEscape, SIGNAL(stateChanged( int )), SLOT(update_preview())); + connect(chkData, SIGNAL(stateChanged( int )), SLOT(update_preview())); connect(spnWhitespace, SIGNAL(valueChanged( int )), SLOT(update_preview())); connect(btnAbout, SIGNAL(clicked( bool )), SLOT(about())); connect(btnSave, SIGNAL(clicked( bool )), SLOT(save())); @@ -860,6 +861,16 @@ void MainWindow::upcean_addon_gap(QComboBox *comboBox, QLabel* label, int base) } } +void MainWindow::set_gs1_mode(bool gs1_mode) +{ + if (gs1_mode) { + m_bc.bc.setInputMode(GS1_MODE | (m_bc.bc.inputMode() & ~0x07)); // Keep upper bits + chkData->setEnabled(false); + } else { + chkData->setEnabled(true); + } +} + void MainWindow::update_preview() { int symbology = metaObject()->enumerator(0).value(bstyle->currentIndex()); @@ -878,7 +889,12 @@ void MainWindow::update_preview() m_bc.bc.setSecurityLevel(0); m_bc.bc.setOption2(0); m_bc.bc.setOption3(0); - m_bc.bc.setInputMode(UNICODE_MODE); + chkData->setEnabled(true); + if (chkData->isChecked()) { + m_bc.bc.setInputMode(DATA_MODE); + } else { + m_bc.bc.setInputMode(UNICODE_MODE); + } if (chkEscape->isChecked()) { m_bc.bc.setInputMode(m_bc.bc.inputMode() | ESCAPE_MODE); } @@ -1008,8 +1024,7 @@ void MainWindow::update_preview() case BARCODE_DOTCODE: m_bc.bc.setSymbol(BARCODE_DOTCODE); m_bc.bc.setOption2(m_optionWidget->findChild("cmbDotCols")->currentIndex()); - if(m_optionWidget->findChild("radDotGS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radDotGS1")->isChecked()); m_bc.bc.setDotSize(m_optionWidget->findChild("txtDotSize")->text().toFloat()); break; @@ -1021,8 +1036,7 @@ void MainWindow::update_preview() if(m_optionWidget->findChild("radAztecECC")->isChecked()) m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbAztecECC")->currentIndex() + 1); - if(m_optionWidget->findChild("radAztecGS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radAztecGS1")->isChecked()); if(m_optionWidget->findChild("radAztecHIBC")->isChecked()) m_bc.bc.setSymbol(BARCODE_HIBC_AZTEC); break; @@ -1068,10 +1082,7 @@ void MainWindow::update_preview() case BARCODE_CODE16K: m_bc.bc.setSymbol(BARCODE_CODE16K); - if(m_optionWidget->findChild("radC16kStand")->isChecked()) - m_bc.bc.setInputMode(UNICODE_MODE); - else - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radC16kStand")->isChecked()); // Row separator height selection uses option 3 in zint_symbol item_val = m_optionWidget->findChild("cmbC16kRowSepHeight")->currentIndex(); if (item_val) { @@ -1116,13 +1127,14 @@ void MainWindow::update_preview() m_bc.bc.setSymbol(BARCODE_DATAMATRIX); if (m_optionWidget->findChild("radDM200GS1")->isChecked()) { - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(true); checkBox = m_optionWidget->findChild("chkDMGSSep"); checkBox->setEnabled(true); if (checkBox->isChecked()) { m_bc.bc.setGSSep(true); } } else { + set_gs1_mode(false); m_optionWidget->findChild("chkDMGSSep")->setEnabled(false); } @@ -1153,8 +1165,7 @@ void MainWindow::update_preview() else m_bc.bc.setSymbol(BARCODE_QRCODE); - if(m_optionWidget->findChild("radQRGS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radQRGS1")->isChecked()); item_val = m_optionWidget->findChild("cmbQRSize")->currentIndex(); if (item_val) { @@ -1181,8 +1192,7 @@ void MainWindow::update_preview() case BARCODE_RMQR: m_bc.bc.setSymbol(BARCODE_RMQR); - if(m_optionWidget->findChild("radRMQRGS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radRMQRGS1")->isChecked()); item_val = m_optionWidget->findChild("cmbRMQRSize")->currentIndex(); if (item_val) { @@ -1227,15 +1237,13 @@ void MainWindow::update_preview() case BARCODE_CODEONE: m_bc.bc.setSymbol(BARCODE_CODEONE); - if(m_optionWidget->findChild("radC1GS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radC1GS1")->isChecked()); m_bc.bc.setOption2(m_optionWidget->findChild("cmbC1Size")->currentIndex()); break; case BARCODE_CODE49: m_bc.bc.setSymbol(BARCODE_CODE49); - if(m_optionWidget->findChild("radC49GS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radC49GS1")->isChecked()); // Row separator height selection uses option 3 in zint_symbol item_val = m_optionWidget->findChild("cmbC49RowSepHeight")->currentIndex(); if (item_val) { @@ -1259,8 +1267,7 @@ void MainWindow::update_preview() m_bc.bc.setSymbol(BARCODE_ULTRA); if(m_optionWidget->findChild("radUltraEcc")->isChecked()) m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbUltraEcc")->currentIndex() + 1); - if(m_optionWidget->findChild("radUltraGS1")->isChecked()) - m_bc.bc.setInputMode(GS1_MODE); + set_gs1_mode(m_optionWidget->findChild("radUltraGS1")->isChecked()); break; case BARCODE_VIN: diff --git a/frontend_qt/mainwindow.h b/frontend_qt/mainwindow.h index 8c71eb9b..377762aa 100644 --- a/frontend_qt/mainwindow.h +++ b/frontend_qt/mainwindow.h @@ -130,6 +130,7 @@ public slots: protected: void resizeEvent(QResizeEvent *event); void upcean_addon_gap(QComboBox *comboBox, QLabel* label, int base); + void set_gs1_mode(bool gs1_mode); private slots: bool save();