diff --git a/CMakeLists.txt b/CMakeLists.txt index 25780dc6..d4e5d98b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,9 +145,9 @@ elseif($ENV{CMAKE_PREFIX_PATH} MATCHES "6[.][0-9][.][0-9]") find_package(Qt6Widgets) find_package(Qt6Gui) find_package(Qt6UiTools) - find_package(Qt6Xml) + find_package(Qt6Svg) - if(Qt6Widgets_FOUND AND Qt6Gui_FOUND AND Qt6UiTools_FOUND AND Qt6Xml_FOUND) + if(Qt6Widgets_FOUND AND Qt6Gui_FOUND AND Qt6UiTools_FOUND AND Qt6Svg_FOUND) message(STATUS "Qt version: " ${Qt6Core_VERSION_MAJOR}.${Qt6Core_VERSION_MINOR}.${Qt6Core_VERSION_PATCH}) add_subdirectory(backend_qt) add_subdirectory(frontend_qt) @@ -159,9 +159,9 @@ else() find_package(Qt5Widgets) find_package(Qt5Gui) find_package(Qt5UiTools) - find_package(Qt5Xml) + find_package(Qt5Svg) - if(Qt5Widgets_FOUND AND Qt5Gui_FOUND AND Qt5UiTools_FOUND AND Qt5Xml_FOUND) + if(Qt5Widgets_FOUND AND Qt5Gui_FOUND AND Qt5UiTools_FOUND AND Qt5Svg_FOUND) message(STATUS "Qt version: " ${Qt5Core_VERSION_STRING}) # Old Qt does not provide QT_VERSION_MAJOR if (NOT QT_VERSION_MAJOR) diff --git a/ChangeLog b/ChangeLog index fc2fd9cb..b80dd491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,10 +7,18 @@ Changes - eci.c: replace libiconv-adapted code with own implementations so as to fully comply with libzint's BSD license - GUI: CODE39/EXCODE39: show/hide HIBC check digit option +- RMQR: update to ISO/IEC 23941:2022 - R13x77 numeric cclens change 8 -> 7 +- QRCODE: use stricter interpretation of ZINT_FULL_MULTIBYTE, excluding + certain trailing bytes +- GUI: foreground/background colours -> text boxes and icon buttons, add swap + button, independently movable picker (NULL parent), preview colour changes, + preview Data Window changes, add clear data (del) buttons, add zap button + and Factory Reset menu option, various other fixes Bugs ---- - frontend/test_args.c: don't use WIFEXITED(), WEXITSTATUS() on Windows +- libzint: fix some confusing error messages introduced by segment stuff Version 2.11.0 (2022-05-24) diff --git a/README.linux b/README.linux index bf0a2b83..d00a8b87 100644 --- a/README.linux +++ b/README.linux @@ -1,5 +1,5 @@ -Prerequisites for building zint -------------------------------- +1. Prerequisites for building zint +================================== Prerequisites are git, cmake, make, gcc and gcc-c++, e.g. Ubuntu/Debian @@ -17,26 +17,24 @@ or Fedora sudo dnf install libpng-devel -Prerequisites for building zint-qt ----------------------------------- +Then either download the source code tarball -Sign up and download the Qt Maintenance Tool from - https://www.qt.io/download-qt-installer + wget -O zint-2.11.0-src.tar.gz \ + https://sourceforge2.11.0net/projects/zint/files/zint/2.11.0/zint-2.11.0-src.tar.gz/download + tar xf zint-2.11.0-src.tar.gz + cd zint-2.11.0-src -On Ubuntu/Debian you may need to install xinerama to run the tool: +or clone the latest source - sudo apt install libxcb-xinerama0 + git clone https://git.code.sf.net/p/zint/code zint + cd zint -Launch the tool and install the "Desktop gcc 64-bit" component for either Qt -5.15.2 or Qt 6 (>= 6.1). -Once Qt is installed you may need to tell CMake where it is: +2. Prerequisites for building zint-qt +===================================== - export CMAKE_PREFIX_PATH=/gcc_64 - -e.g. export CMAKE_PREFIX_PATH=/opt/Qt/5.15.2/gcc_64 - -To build zint-qt you also need to install mesa (for OpenGL), e.g. Ubuntu/Debian +zint-qt can be built with either Qt5 (preferred) or Qt6. First, install mesa (for OpenGL), e.g. +Ubuntu/Debian sudo apt install mesa-common-dev libglu1-mesa-dev @@ -44,13 +42,59 @@ or Fedora sudo dnf install mesa-libGL mesa-libGL-devel -Build ------ +2.1. Using Qt packages +---------------------- + +If packages for Qt exist for your distro, it might be easiest to use them, although knowing +what their ever-changing names and contents are isn't. A complication is that zint-qt uses 2 Qt +components beyond the basic setup: Qt UI Tools (for dynamically loading the symbology-specific +tabs), and Qt SVG (for rendering icons). + +E.g. on Ubuntu 22.04 + + sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools libqt5svg5-dev + +or Ubuntu 20.04 + + sudo apt install qt5-default qt5-uitools + +or Fedora 36 (Qt6 NOT recommended, currently uses 6.3.0 which is flaky) + + sudo dnf install qt5-qtbase-devel qt5-qttools-devel qt5-qttools-static qt5-qtsvg-devel + +You may need to tell CMake where to find the ".cmake" modules: + + export CMAKE_MODULE_PATH=/Qt5 + +e.g. CMAKE_MODULE_PATH=/usr/lib/x86_64-linux-gnu/cmake/Qt5 + +2.2. Using the Qt Maintenance Tool +---------------------------------- + +Alternatively, for a more consistent, dependable, flexible experience, sign up and download the +Qt Maintenance Tool from + + https://www.qt.io/download-qt-installer + +On Ubuntu/Debian you may need to install xinerama to run the tool: + + sudo apt install libxcb-xinerama0 + +Launch the tool and install the "Desktop gcc 64-bit" component for either Qt 5.15.2 or Qt 6 +(>= 6.1, and not 6.3.0). + +Once Qt is installed you may need to tell CMake where it is: + + export CMAKE_PREFIX_PATH=/gcc_64 + +e.g. export CMAKE_PREFIX_PATH=/opt/Qt/5.15.2/gcc_64 + + +3. Build +======== The rest is standard CMake - git clone https://git.code.sf.net/p/zint/code zint - cd zint mkdir build cd build @@ -58,8 +102,9 @@ The rest is standard CMake make sudo make install -CMake options -------------- + +4. CMake options +================ A number of options are available: @@ -76,5 +121,4 @@ which can be set by doing e.g. cmake -DZINT_SANITIZE=ON .. -For details on ZINT_TEST and building the zint test suite, see -"backend/tests/README". +For details on ZINT_TEST and building the zint test suite, see "backend/tests/README". diff --git a/backend/big5.h b/backend/big5.h index ebaa1288..a12e98c0 100644 --- a/backend/big5.h +++ b/backend/big5.h @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_BIG5_H #define Z_BIG5_H diff --git a/backend/code128.c b/backend/code128.c index 38103bdf..d842f15b 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #ifdef _MSC_VER @@ -341,8 +342,7 @@ INTERNAL void c128_put_in_set(int list[2][C128_MAX], const int indexliste, char } /* 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 c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], - const int length) { +static int c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length) { int i, j; for (i = 0, j = 0; i < length && j < (int) sizeof(symbol->text); i++) { @@ -374,6 +374,12 @@ STATIC_UNLESS_ZINT_TEST int c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, c return j; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int c128_hrt_cpy_iso8859_1_test(struct zint_symbol *symbol, const unsigned char source[], const int length) { + return c128_hrt_cpy_iso8859_1(symbol, source, length); +} +#endif + /* 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, read, total_sum; diff --git a/backend/common.h b/backend/common.h index 76418447..7aafe634 100644 --- a/backend/common.h +++ b/backend/common.h @@ -29,6 +29,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_COMMON_H #define Z_COMMON_H @@ -115,12 +116,6 @@ # define INTERNAL_DATA #endif -#ifdef ZINT_TEST -#define STATIC_UNLESS_ZINT_TEST INTERNAL -#else -#define STATIC_UNLESS_ZINT_TEST static -#endif - #define Z_COMMON_INLINE 1 #ifdef Z_COMMON_INLINE diff --git a/backend/composite.c b/backend/composite.c index 463bcdac..4807429a 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -1299,7 +1299,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l pri_len = (int) strlen(symbol->primary); if (pri_len == 0) { strcpy(symbol->errtxt, "445: No primary (linear) message in 2D composite"); - return ZINT_ERROR_INVALID_OPTION; + return ZINT_ERROR_INVALID_OPTION; /* TODO: change to more appropiate ZINT_ERROR_INVALID_DATA */ } if (length > 2990) { diff --git a/backend/dmatrix.c b/backend/dmatrix.c index aba1da82..7c89e213 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -37,6 +37,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #include @@ -1483,8 +1484,8 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate Supports encoding FNC1 in supporting systems */ -STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[], - const int length, const int eci, const int gs1, unsigned char target[], int *p_tp) { +static int dm_encode(struct zint_symbol *symbol, const unsigned char source[], const int length, const int eci, + const int gs1, unsigned char target[], int *p_tp) { int sp = 0; int tp = *p_tp; int current_mode = DM_ASCII; @@ -1658,6 +1659,13 @@ STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned return 0; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int dm_encode_test(struct zint_symbol *symbol, const unsigned char source[], const int length, const int eci, + const int gs1, unsigned char target[], int *p_tp) { + return dm_encode(symbol, source, length, eci, gs1, target, p_tp); +} +#endif + /* Call `dm_encode()` for each segment, dealing with Structured Append, GS1, READER_INIT and macro headers beforehand */ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, diff --git a/backend/eci.c b/backend/eci.c index 32944362..80914dc2 100644 --- a/backend/eci.c +++ b/backend/eci.c @@ -28,6 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #ifdef _MSC_VER @@ -66,7 +67,7 @@ static int u_iso8859(const unsigned int u, const unsigned short *tab_s, const un s = 0; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (tab_u[m] < u) { s = m + 1; } else if (tab_u[m] > u) { @@ -97,7 +98,7 @@ static int u_cp125x(const unsigned int u, const unsigned short *tab_s, const uns s = 0; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (tab_u[m] < u) { s = m + 1; } else if (tab_u[m] > u) { @@ -244,7 +245,7 @@ static int u_sjis_int(const unsigned int u, unsigned int *d) { s = 0; e = ARRAY_SIZE(sjis_u) - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (sjis_u[m] < u) { s = m + 1; } else if (sjis_u[m] > u) { @@ -298,7 +299,7 @@ static int u_big5(const unsigned int u, unsigned char *dest) { s = 0; e = ARRAY_SIZE(big5_u) - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (big5_u[m] < u) { s = m + 1; } else if (big5_u[m] > u) { @@ -339,7 +340,7 @@ static int u_ksx1001(const unsigned int u, unsigned char *dest) { s = ksx1001_u_ind[(u - ksx1001_u[0]) >> 8]; e = s + 0x100 > ARRAY_SIZE(ksx1001_u) ? ARRAY_SIZE(ksx1001_u) - 1 : s + 0x100 - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (ksx1001_u[m] < u) { s = m + 1; } else if (ksx1001_u[m] > u) { @@ -380,7 +381,7 @@ static int u_gb2312_int(const unsigned int u, unsigned int *d) { s = gb2312_u_ind[(u - gb2312_u[0]) >> 8]; e = s + 0x100 > ARRAY_SIZE(gb2312_u) ? ARRAY_SIZE(gb2312_u) - 1 : s + 0x100 - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (gb2312_u[m] < u) { s = m + 1; } else if (gb2312_u[m] > u) { @@ -449,7 +450,7 @@ static int u_gbk_int(const unsigned int u, unsigned int *d) { s = 0; e = ARRAY_SIZE(gbk_u) - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (gbk_u[m] < u) { s = m + 1; } else if (gbk_u[m] > u) { @@ -561,7 +562,7 @@ static int u_gb18030_int(const unsigned int u, unsigned int *d1, unsigned int *d s = 0; e = ARRAY_SIZE(gb18030_2_u) - 1; while (s <= e) { - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (gb18030_2_u[m] < u) { s = m + 1; } else if (gb18030_2_u[m] > u) { @@ -581,7 +582,7 @@ static int u_gb18030_int(const unsigned int u, unsigned int *d1, unsigned int *d s = 0; e = ARRAY_SIZE(gb18030_4_u_e) - 1; while (s < e) { /* Lower bound */ - const int m = (s + e) / 2; + const int m = (s + e) >> 1; if (gb18030_4_u_e[m] < u) { s = m + 1; } else { @@ -861,24 +862,25 @@ INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[], /* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match QR Kanji mode in * a single entry. If `full_multibyte` not set, do a straight copy */ INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte) { - unsigned int i, j, jis, length; - unsigned char c; + unsigned int i, j, length; + unsigned char c1, c2; if (full_multibyte) { for (i = 0, j = 0, length = *p_length; i < length; i++, j++) { - c = source[i]; - if (((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xEB)) && length - i >= 2) { - jis = (c << 8) | source[i + 1]; - if ((jis >= 0x8140 && jis <= 0x9FFC) || (jis >= 0xE040 && jis <= 0xEBBF)) { + c1 = source[i]; + /* Now using stricter interpretation of standard, and excluding certain trailing bytes */ + if (((c1 >= 0x81 && c1 <= 0x9F) || (c1 >= 0xE0 && c1 <= 0xEB)) && length - i >= 2) { + c2 = source[i + 1]; + if ((c2 >= 0x40 && c2 <= 0xFC) && c2 != 0x7F && (c1 != 0xEB || c2 <= 0xBF)) { /* This may or may not be valid Shift JIS, but don't care as long as it can be encoded in * QR Kanji mode */ - ddata[j] = jis; + ddata[j] = (c1 << 8) | c2; i++; } else { - ddata[j] = c; + ddata[j] = c1; } } else { - ddata[j] = c; + ddata[j] = c1; } } *p_length = j; diff --git a/backend/eci_sb.h b/backend/eci_sb.h index a313546a..9de5a67a 100644 --- a/backend/eci_sb.h +++ b/backend/eci_sb.h @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_ECI_SB_H #define Z_ECI_SB_H diff --git a/backend/gb18030.h b/backend/gb18030.h index 0be215ca..89acd2f0 100644 --- a/backend/gb18030.h +++ b/backend/gb18030.h @@ -31,6 +31,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_GB18030_H #define Z_GB18030_H diff --git a/backend/gb2312.h b/backend/gb2312.h index e081bc4a..2ecb3beb 100644 --- a/backend/gb2312.h +++ b/backend/gb2312.h @@ -31,6 +31,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_GB2312_H #define Z_GB2312_H diff --git a/backend/gbk.h b/backend/gbk.h index 21b04d89..3b1b9e90 100644 --- a/backend/gbk.h +++ b/backend/gbk.h @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_GBK_H #define Z_GBK_H diff --git a/backend/ksx1001.h b/backend/ksx1001.h index 58801a87..dfe98c7d 100644 --- a/backend/ksx1001.h +++ b/backend/ksx1001.h @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_KSX1001_H #define Z_KSX1001_H diff --git a/backend/large.c b/backend/large.c index c2db31fe..11e40c22 100644 --- a/backend/large.c +++ b/backend/large.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2021 Robin Stuart + Copyright (C) 2008-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -29,7 +29,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* `large_mul_u64()` and `large_div_u64()` are adapted from articles by F. W. Jacob * https://www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring @@ -133,7 +133,7 @@ INTERNAL void large_mul_u64(large_int *t, const uint64_t s) { } /* Count leading zeroes. See Hickman `r128__clz64()` */ -STATIC_UNLESS_ZINT_TEST int clz_u64(uint64_t x) { +static int clz_u64(uint64_t x) { uint64_t n = 64, y; y = x >> 32; if (y) { n -= 32; x = y; } y = x >> 16; if (y) { n -= 16; x = y; } @@ -144,7 +144,13 @@ STATIC_UNLESS_ZINT_TEST int clz_u64(uint64_t x) { return (int) (n - x); } -/* Divide 128-bit dividend `t` by 64-bit divisor `v` +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int clz_u64_test(uint64_t x) { + return clz_u64(x); +} +#endif + +/* Divide 128-bit dividend `t` by 64-bit divisor `v`, returning 64-bit remainder * See Jacob `divmod128by128/64()` and Warren Section 9–2 (divmu64.c.txt) * Note digits are 32-bit parts */ INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v) { @@ -294,13 +300,6 @@ INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, } } -/* Output formatted large_int to stdout */ -INTERNAL void large_print(const large_int *t) { - char buf[35]; /* 2 (0x) + 32 (hex) + 1 */ - - puts(large_dump(t, buf)); -} - /* Format large_int into buffer, which should be at least 35 chars in size */ INTERNAL char *large_dump(const large_int *t, char *buf) { unsigned int tlo1 = (unsigned int) (large_lo(t) >> 32); @@ -319,3 +318,12 @@ INTERNAL char *large_dump(const large_int *t, char *buf) { } return buf; } + +/* Output formatted large_int to stdout */ +INTERNAL void large_print(const large_int *t) { + char buf[35]; /* 2 (0x) + 32 (hex) + 1 */ + + puts(large_dump(t, buf)); +} + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/large.h b/backend/large.h index 89188847..bafa6adc 100644 --- a/backend/large.h +++ b/backend/large.h @@ -29,6 +29,8 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ + #ifndef Z_LARGE_H #define Z_LARGE_H @@ -48,7 +50,7 @@ typedef struct { uint64_t lo; uint64_t hi; } large_int; #define large_hi(s) ((s)->hi) /* Set 128-bit `t` from 128-bit `s` */ -#define large_load(t, s) do { (t)->lo = (s)->lo; (t)->hi = (s)->hi; } while (0) +#define large_load(t, s) do { *(t) = *(s); } while (0) /* Set 128-bit `t` from 64-bit `s` */ #define large_load_u64(t, s) do { (t)->lo = (s); (t)->hi = 0; } while (0) @@ -69,8 +71,8 @@ INTERNAL void large_unset_bit(large_int *t, const int bit); INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, const int size, int bits); INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, const int size, int bits); -INTERNAL void large_print(const large_int *t); INTERNAL char *large_dump(const large_int *t, char *buf); +INTERNAL void large_print(const large_int *t); #ifdef __cplusplus } diff --git a/backend/library.c b/backend/library.c index e2a93c09..3672cfe7 100644 --- a/backend/library.c +++ b/backend/library.c @@ -28,6 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #include @@ -125,6 +126,7 @@ void ZBarcode_Delete(struct zint_symbol *symbol) { free(symbol); } +/* Symbology handlers */ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ @@ -197,11 +199,12 @@ INTERNAL int ultra(struct zint_symbol *symbol, struct zint_seg segs[], const int INTERNAL int rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* rMQR */ INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length); /* DPD Code */ +/* Output handlers */ INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to EPS/EMF/SVG */ /* Prefix error message with Error/Warning */ -STATIC_UNLESS_ZINT_TEST int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string) { +static int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string) { if (error_number != 0) { static const char error_fmt[] = "Error %.93s"; /* Truncate if too long */ @@ -227,6 +230,12 @@ STATIC_UNLESS_ZINT_TEST int error_tag(struct zint_symbol *symbol, int error_numb return error_number; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int error_tag_test(struct zint_symbol *symbol, int error_number, const char *error_string) { + return error_tag(symbol, error_number, error_string); +} +#endif + /* Output a hexadecimal representation of the rendered symbol */ static int dump_plot(struct zint_symbol *symbol) { FILE *f; @@ -286,6 +295,7 @@ static int dump_plot(struct zint_symbol *symbol) { return 0; } +/* Permitted HIBC characters */ static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */ /* Process health industry bar code data */ @@ -532,6 +542,8 @@ static const void *barcode_funcs[BARCODE_LAST + 1] = { static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); +/* Main dispatch, checking for barcodes which handle ECIs/character sets themselves, otherwise calling + `reduced_charset()` */ static int extended_or_reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { int error_number = 0; @@ -620,7 +632,8 @@ static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], c #pragma GCC diagnostic pop #endif -STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length) { +/* Remove Unicode BOM at start of data */ +static void strip_bom(unsigned char *source, int *input_length) { int i; /* Note if BOM is only data then not stripped */ @@ -633,11 +646,51 @@ STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length) } } -STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, - int *length) { +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL void strip_bom_test(unsigned char *source, int *input_length) { + strip_bom(source, input_length); +} +#endif + +/* Helper to convert base octal, decimal, hexadecimal escape sequence */ +static int esc_base(struct zint_symbol *symbol, unsigned char *input_string, int length, int in_posn, int base) { + int c1, c2, c3; + int min_len = base == 'x' ? 2 : 3; + + if (in_posn + min_len > length) { + sprintf(symbol->errtxt, "232: Incomplete '\\%c' escape sequence in input data", base); + return -1; + } + c1 = ctoi(input_string[in_posn]); + c2 = ctoi(input_string[in_posn + 1]); + if (base == 'd') { + c3 = ctoi(input_string[in_posn + 2]); + if ((c1 >= 0 && c1 <= 9) && (c2 >= 0 && c2 <= 9) && (c3 >= 0 && c3 <= 9)) { + return c1 * 100 + c2 * 10 + c3; + } + } else if (base == 'o') { + c3 = ctoi(input_string[in_posn + 2]); + if ((c1 >= 0 && c1 <= 7) && (c2 >= 0 && c2 <= 7) && (c3 >= 0 && c3 <= 7)) { + return (c1 << 6) | (c2 << 3) | c3; + } + } else { + if ((c1 >= 0) && (c2 >= 0)) { + return (c1 << 4) | c2; + } + } + + sprintf(symbol->errtxt, "233: Invalid character for '\\%c' escape sequence in input data (%s only)", + base, base == 'd' ? "decimal" : base == 'o' ? "octal" : "hexadecimal" ); + return -1; +} + +/* Helper to parse escape sequences */ +static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, int *length) { int in_posn, out_posn; - int hex1, hex2; - int i, unicode; + int ch; + int val; + int i; + unsigned long unicode; #ifndef _MSC_VER unsigned char escaped_string[*length + 1]; @@ -654,7 +707,9 @@ STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsi strcpy(symbol->errtxt, "236: Incomplete escape character in input data"); return ZINT_ERROR_INVALID_DATA; } - switch (input_string[in_posn + 1]) { + ch = input_string[in_posn + 1]; + /* NOTE: if add escape character, must also update regex in "frontend_qt/datawindow.php" */ + switch (ch) { case '0': escaped_string[out_posn] = 0x00; /* Null */ in_posn += 2; break; @@ -691,43 +746,47 @@ STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsi case 'R': escaped_string[out_posn] = 0x1e; /* Record Separator */ in_posn += 2; break; - case 'x': if (in_posn + 4 > *length) { - strcpy(symbol->errtxt, "232: Incomplete escape character in input data"); - return ZINT_ERROR_INVALID_DATA; - } - hex1 = ctoi(input_string[in_posn + 2]); - hex2 = ctoi(input_string[in_posn + 3]); - if ((hex1 >= 0) && (hex2 >= 0)) { - escaped_string[out_posn] = (hex1 << 4) + hex2; - in_posn += 4; - } else { - strcpy(symbol->errtxt, "233: Corrupt escape character in input data"); + case 'd': + case 'o': /* Undocumented (as not very useful for most people) */ + case 'x': + if ((val = esc_base(symbol, input_string, *length, in_posn + 2, ch)) == -1) { return ZINT_ERROR_INVALID_DATA; } + escaped_string[out_posn] = val; + in_posn += 4 + (ch != 'x'); break; case '\\': escaped_string[out_posn] = '\\'; in_posn += 2; break; case 'u': - if (in_posn + 6 > *length) { - strcpy(symbol->errtxt, "209: Incomplete Unicode escape character in input data"); + case 'U': + if (in_posn + 6 > *length || (ch == 'U' && in_posn + 8 > *length)) { + sprintf(symbol->errtxt, "209: Incomplete '\\%c' escape sequence in input data", ch); return ZINT_ERROR_INVALID_DATA; } unicode = 0; - for (i = 0; i < 4; i++) { - if (ctoi(input_string[in_posn + i + 2]) == -1) { - strcpy(symbol->errtxt, "211: Corrupt Unicode escape character in input data"); + for (i = 0; i < 6; i++) { + if ((val = ctoi(input_string[in_posn + i + 2])) == -1) { + sprintf(symbol->errtxt, + "211: Invalid character for '\\%c' escape sequence in input data (hexadecimal only)", + ch); return ZINT_ERROR_INVALID_DATA; } - unicode = unicode << 4; - unicode += ctoi(input_string[in_posn + i + 2]); + unicode = (unicode << 4) | val; + if (i == 3 && ch == 'u') { + break; + } } - /* Exclude reversed BOM and surrogates */ - if (unicode == 0xfffe || (unicode >= 0xd800 && unicode < 0xe000)) { - strcpy(symbol->errtxt, "246: Invalid Unicode BMP escape character in input data"); + /* Exclude reversed BOM and surrogates and out-of-range */ + if (unicode == 0xfffe || (unicode >= 0xd800 && unicode < 0xe000) || unicode > 0x10ffff) { + sprintf(symbol->errtxt, "246: Invalid value for '\\%c' escape sequence in input data", ch); return ZINT_ERROR_INVALID_DATA; } if (unicode >= 0x800) { + if (unicode >= 0x10000) { + escaped_string[out_posn] = 0xf0 + (unsigned char) (unicode >> 16); + out_posn++; + } escaped_string[out_posn] = 0xe0 + ((unicode & 0xf000) >> 12); out_posn++; escaped_string[out_posn] = 0x80 + ((unicode & 0x0fc0) >> 6); @@ -740,9 +799,9 @@ STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsi } else { escaped_string[out_posn] = unicode & 0x7f; } - in_posn += 6; + in_posn += 6 + (ch == 'U') * 2; break; - default: strcpy(symbol->errtxt, "234: Unrecognised escape character in input data"); + default: sprintf(symbol->errtxt, "234: Unrecognised escape character '\\%c' in input data", ch); return ZINT_ERROR_INVALID_DATA; break; } @@ -760,6 +819,12 @@ STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsi return 0; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int escape_char_process_test(struct zint_symbol *symbol, unsigned char *input_string, int *length) { + return escape_char_process(symbol, input_string, length); +} +#endif + /* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length) { struct zint_seg segs[1]; @@ -793,13 +858,15 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ if (segs == NULL) { return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "200: Input segments NULL"); } - if (seg_count <= 0) { - return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: Input segment count 0"); - } + /* `seg_count` zero dealt with via `total_len` zero below */ if (seg_count > ZINT_MAX_SEG_COUNT) { return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "771: Too many input segments (max 256)"); } + if ((symbol->input_mode & 0x07) > 2) { + symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */ + } + /* Check segment lengths */ for (i = 0; i < seg_count; i++) { local_segs[i] = segs[i]; @@ -811,7 +878,18 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ local_segs[i].length = (int) ustrlen(local_segs[i].source); } if (local_segs[i].length <= 0) { - sprintf(symbol->errtxt, "773: Input segment %d length zero", i); + if (i == 0) { + /* Note: should really be referencing the symbology only after the symbology check switch below */ + if (is_composite(symbol->symbology) && + ((symbol->input_mode & 0x07) == GS1_MODE || check_force_gs1(symbol->symbology))) { + strcpy(symbol->errtxt, "779: No composite data in 2D component"); + } else { + sprintf(symbol->errtxt, "778: No input data%s", + supports_eci(symbol->symbology) ? " (segment 0 empty)" : ""); + } + } else { + sprintf(symbol->errtxt, "773: Input segment %d empty", i); + } return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL); } if (local_segs[i].length > ZINT_MAX_DATA_LEN) { @@ -820,6 +898,10 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ total_len += local_segs[i].length; } + if (total_len == 0) { + return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: No input data"); + } + if (symbol->debug & ZINT_DEBUG_PRINT) { printf("ZBarcode_Encode_Segs: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d," " option_3: %d, scale: %g\n output_options: 0x%X, fg: %s, bg: %s," @@ -1007,10 +1089,6 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ return error_tag(symbol, ZINT_ERROR_TOO_LONG, "770: Too many stacked symbols"); } - if ((symbol->input_mode & 0x07) > 2) { - symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */ - } - if ((symbol->input_mode & 0x07) == GS1_MODE && !gs1_compliant(symbol->symbology)) { return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode"); } @@ -1058,7 +1136,7 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ } if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) { - if (gs1_compliant(symbol->symbology) == 1) { + if (gs1_compliant(symbol->symbology)) { // Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will // handle it themselves if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) { diff --git a/backend/output.c b/backend/output.c index 21ed65a3..7e23aea8 100644 --- a/backend/output.c +++ b/backend/output.c @@ -1,7 +1,7 @@ /* output.c - Common routines for raster/vector libzint - the open source barcode library - Copyright (C) 2020 - 2021 Robin Stuart + Copyright (C) 2020-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -28,7 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #include @@ -70,7 +70,7 @@ INTERNAL int out_check_colour_options(struct zint_symbol *symbol) { } /* Return minimum quiet zones for each symbology */ -STATIC_UNLESS_ZINT_TEST int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, +static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, float *left, float *right, float *top, float *bottom) { int done = 0; @@ -471,6 +471,13 @@ STATIC_UNLESS_ZINT_TEST int out_quiet_zones(const struct zint_symbol *symbol, co return done; /* For self-checking */ } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hide_text, + float *left, float *right, float *top, float *bottom) { + return out_quiet_zones(symbol, hide_text, left, right, top, bottom); +} +#endif + /* Set left (x), top (y), right and bottom offsets for whitespace */ INTERNAL void out_set_whitespace_offsets(const struct zint_symbol *symbol, const int hide_text, float *xoffset, float *yoffset, float *roffset, float *boffset, const float scaler, @@ -722,3 +729,5 @@ INTERNAL void out_upcean_split_text(int upceanflag, unsigned char text[], textpart3[6] = '\0'; } } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/png.c b/backend/png.c index 65a51f86..b5fb9c63 100644 --- a/backend/png.c +++ b/backend/png.c @@ -1,8 +1,7 @@ /* png.c - Handles output to PNG file */ - /* libzint - the open source barcode library - Copyright (C) 2009-2021 Robin Stuart + Copyright (C) 2009-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -29,7 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef NO_PNG @@ -52,7 +51,7 @@ struct wpng_error_type { jmp_buf jmpbuf; }; -STATIC_UNLESS_ZINT_TEST void wpng_error_handler(png_structp png_ptr, png_const_charp msg) { +static void wpng_error_handler(png_structp png_ptr, png_const_charp msg) { struct wpng_error_type *wpng_error_ptr; wpng_error_ptr = (struct wpng_error_type *) png_get_error_ptr(png_ptr); @@ -67,6 +66,12 @@ STATIC_UNLESS_ZINT_TEST void wpng_error_handler(png_structp png_ptr, png_const_c longjmp(wpng_error_ptr->jmpbuf, 1); } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL void wpng_error_handler_test(png_structp png_ptr, png_const_charp msg) { + wpng_error_handler(png_ptr, msg); +} +#endif + /* Guestimate best compression strategy */ static int guess_compression_strategy(struct zint_symbol *symbol, unsigned char *pixelbuf) { (void)pixelbuf; @@ -349,4 +354,5 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) #else /* https://stackoverflow.com/a/26541331 Suppresses gcc warning ISO C forbids an empty translation unit */ typedef int make_iso_compilers_happy; +/* vim: set ts=4 sw=4 et : */ #endif /* NO_PNG */ diff --git a/backend/ps.c b/backend/ps.c index 22cefd80..743fa094 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -1,8 +1,7 @@ /* ps.c - Post Script output */ - /* libzint - the open source barcode library - Copyright (C) 2009-2021 Robin Stuart + Copyright (C) 2009-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -29,7 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include #include @@ -103,7 +102,7 @@ static void colour_to_pscolor(int option, int colour, char *output) { } } -STATIC_UNLESS_ZINT_TEST void ps_convert(const unsigned char *string, unsigned char *ps_string) { +static void ps_convert(const unsigned char *string, unsigned char *ps_string) { const unsigned char *s; unsigned char *p = ps_string; @@ -132,6 +131,12 @@ STATIC_UNLESS_ZINT_TEST void ps_convert(const unsigned char *string, unsigned ch *p = '\0'; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL void ps_convert_test(const unsigned char *string, unsigned char *ps_string) { + ps_convert(string, ps_string); +} +#endif + INTERNAL int ps_plot(struct zint_symbol *symbol) { FILE *feps; int fgred, fggrn, fgblu, bgred, bggrn, bgblu; @@ -522,3 +527,5 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { return error_number; } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/qr.h b/backend/qr.h index 3c88d0c8..96a6a2f8 100644 --- a/backend/qr.h +++ b/backend/qr.h @@ -29,6 +29,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_QR_H #define Z_QR_H @@ -126,7 +127,7 @@ static const unsigned short rmqr_numeric_cci[] = { 4, 5, 6, 7, 7, 5, 6, 7, 7, 8, 4, 6, 7, 7, 8, 8, - 5, 6, 7, 8, 8, 8, // Note R13x77 (4th) 8 bits but max numerics 124 (7 bits) + 5, 6, 7, 7, 8, 8, 7, 7, 8, 8, 9, 7, 8, 8, 8, 9 }; diff --git a/backend/sjis.h b/backend/sjis.h index d211cf4c..3d3978fe 100644 --- a/backend/sjis.h +++ b/backend/sjis.h @@ -30,6 +30,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_SJIS_H #define Z_SJIS_H diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index 1c6d4d91..06ddf6a8 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* Note BARCODE_GS1_128, BARCODE_EAN14, BARCODE_NVE18 also tested in test_gs1.c */ @@ -102,7 +103,7 @@ static void test_large(int index, int debug) { testFinish(); } -int c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length); +INTERNAL int c128_hrt_cpy_iso8859_1_test(struct zint_symbol *symbol, const unsigned char source[], const int length); static void test_hrt_cpy_iso8859_1(int index, int debug) { @@ -157,7 +158,7 @@ static void test_hrt_cpy_iso8859_1(int index, int debug) { length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length; - ret = c128_hrt_cpy_iso8859_1(&symbol, (unsigned char *) data[i].data, length); + ret = c128_hrt_cpy_iso8859_1_test(&symbol, (unsigned char *) data[i].data, length); if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) { for (j = 0; j < ret; j++) { fprintf(stderr, "symbol.text[%d] %2X\n", j, symbol.text[j]); diff --git a/backend/tests/test_dmatrix.c b/backend/tests/test_dmatrix.c index ce2121ee..3664a984 100644 --- a/backend/tests/test_dmatrix.c +++ b/backend/tests/test_dmatrix.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" #include "../gs1.h" @@ -655,8 +656,8 @@ static void test_reader_init(int index, int generate, int debug) { #define ZINT_TEST_ENCODING #ifdef ZINT_TEST_ENCODING -STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[], - const int length, const int eci, const int gs1, unsigned char target[], int *p_tp); +INTERNAL int dm_encode_test(struct zint_symbol *symbol, const unsigned char source[], const int length, const int eci, + const int gs1, unsigned char target[], int *p_tp); #endif static void test_input(int index, int generate, int debug) { @@ -1019,7 +1020,7 @@ static void test_input(int index, int generate, int debug) { binlen = 0; symbol->input_mode = data[i - 1].input_mode; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, text, length, symbol->eci, gs1, binary[0], &binlen); + ret = dm_encode_test(symbol, text, length, symbol->eci, gs1, binary[0], &binlen); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[0] = binlen; @@ -1027,7 +1028,7 @@ static void test_input(int index, int generate, int debug) { binlen = 0; symbol->input_mode = data[i].input_mode; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, text, length, symbol->eci, gs1, binary[1], &binlen); + ret = dm_encode_test(symbol, text, length, symbol->eci, gs1, binary[1], &binlen); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[1] = binlen; @@ -5261,7 +5262,7 @@ static void test_encode(int index, int generate, int debug) { binlen = 0; symbol->input_mode = data[i - 1].input_mode; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[0] = binlen; @@ -5269,7 +5270,7 @@ static void test_encode(int index, int generate, int debug) { binlen = 0; symbol->input_mode = data[i].input_mode; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[1] = binlen; @@ -6627,7 +6628,7 @@ static void test_minimalenc(int index, int debug) { binlen = 0; symbol->input_mode |= FAST_MODE; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen); assert_equal(ret, data[i].ret, "i:%d dm_encode() FAST_MODE ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); binlens[0] = binlen; @@ -6635,7 +6636,7 @@ static void test_minimalenc(int index, int debug) { binlen = 0; symbol->input_mode &= ~FAST_MODE; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen); assert_equal(ret, data[i].ret, "i:%d dm_encode() minimal ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); binlens[1] = binlen; diff --git a/backend/tests/test_imail.c b/backend/tests/test_imail.c index e89c7348..df00915f 100644 --- a/backend/tests/test_imail.c +++ b/backend/tests/test_imail.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* * Intelligent Mail barcode Encoder Test Case Reference Set (csv file) * Copyright (C) 2009 U.S. Postal Service @@ -34,6 +35,12 @@ #include "testcommon.h" +#include + +#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) + +#define TEST_CSV_PERF_ITERATIONS 100 + //#define TEST_IMAIL_CSV_MAX 300 static void test_csv(int index, int debug) { @@ -52,82 +59,103 @@ static void test_csv(int index, int debug) { int ret; int lc = 0; + int j; + clock_t start; + clock_t total = 0; + int test_performance = debug & ZINT_DEBUG_TEST_PERFORMANCE; /* -d 256 */ + int perf_iterations = test_performance ? TEST_CSV_PERF_ITERATIONS : 1; + testStart("test_csv"); + if (test_performance) { + printf("test_csv perf iterations: %d\n", perf_iterations); + } + assert_nonzero(testUtilDataPath(csvfile, sizeof(csvfile), "/backend/tests/data/imail/usps/", "uspsIMbEncoderTestCases.csv"), "testUtilDataPath == 0\n"); - fd = fopen(csvfile, "r"); - assert_nonnull(fd, "fopen(%s) == NULL", csvfile); + for (j = 0; j < perf_iterations; j++) { + fd = fopen(csvfile, "r"); + assert_nonnull(fd, "fopen(%s) == NULL", csvfile); - while (fgets(buffer, sizeof(buffer), fd) != NULL) { - const char *b; - struct zint_symbol *symbol; + while (fgets(buffer, sizeof(buffer), fd) != NULL) { + const char *b; + struct zint_symbol *symbol; - lc++; + lc++; - if (index != -1 && lc != index + 1) continue; + if (index != -1 && lc != index + 1) continue; - #ifdef TEST_IMAIL_CSV_MAX - if (lc > TEST_IMAIL_CSV_MAX && index == -1) { - break; - } - #endif + #ifdef TEST_IMAIL_CSV_MAX + if (lc > TEST_IMAIL_CSV_MAX && index == -1) { + break; + } + #endif - id[0] = tracking_code[0] = routing_code[0] = expected_daft[0] = return_code[0] = '\0'; + id[0] = tracking_code[0] = routing_code[0] = expected_daft[0] = return_code[0] = '\0'; - b = testUtilReadCSVField(buffer, id, sizeof(id)); - assert_nonnull(b, "lc:%d id b == NULL", lc); - assert_equal(*b, ',', "lc:%d id *b %c != ','", lc, *b); + b = testUtilReadCSVField(buffer, id, sizeof(id)); + assert_nonnull(b, "lc:%d id b == NULL", lc); + assert_equal(*b, ',', "lc:%d id *b %c != ','", lc, *b); - b = testUtilReadCSVField(++b, tracking_code, sizeof(tracking_code)); - assert_nonnull(b, "lc:%d tracking_code b == NULL", lc); - assert_equal(*b, ',', "lc:%d tracking_code *b %c != ','", lc, *b); + b = testUtilReadCSVField(++b, tracking_code, sizeof(tracking_code)); + assert_nonnull(b, "lc:%d tracking_code b == NULL", lc); + assert_equal(*b, ',', "lc:%d tracking_code *b %c != ','", lc, *b); - b = testUtilReadCSVField(++b, routing_code, sizeof(routing_code)); - assert_nonnull(b, "lc:%d routing_code b == NULL", lc); - assert_equal(*b, ',', "lc:%d routing_code *b %c != ','", lc, *b); + b = testUtilReadCSVField(++b, routing_code, sizeof(routing_code)); + assert_nonnull(b, "lc:%d routing_code b == NULL", lc); + assert_equal(*b, ',', "lc:%d routing_code *b %c != ','", lc, *b); - b = testUtilReadCSVField(++b, expected_daft, sizeof(expected_daft)); - assert_nonnull(b, "lc:%d expected_daft b == NULL", lc); - assert_equal(*b, ',', "lc:%d expected_daft *b %c != ','", lc, *b); + b = testUtilReadCSVField(++b, expected_daft, sizeof(expected_daft)); + assert_nonnull(b, "lc:%d expected_daft b == NULL", lc); + assert_equal(*b, ',', "lc:%d expected_daft *b %c != ','", lc, *b); - b = testUtilReadCSVField(++b, return_code, sizeof(return_code)); - assert_nonnull(b, "lc:%d return_code b == NULL", lc); - assert_equal(*b, ',', "lc:%d return_code *b %c != ','", lc, *b); + b = testUtilReadCSVField(++b, return_code, sizeof(return_code)); + assert_nonnull(b, "lc:%d return_code b == NULL", lc); + assert_equal(*b, ',', "lc:%d return_code *b %c != ','", lc, *b); - strcpy(data, tracking_code); - strcat(data, "-"); - strcat(data, routing_code); + strcpy(data, tracking_code); + strcat(data, "-"); + strcat(data, routing_code); - assert_nonzero(strlen(data), "lc:%d strlen(data) == 0", lc); + assert_nonzero(strlen(data), "lc:%d strlen(data) == 0", lc); - symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); - symbol->symbology = BARCODE_USPS_IMAIL; - symbol->debug |= debug; + symbol->symbology = BARCODE_USPS_IMAIL; + symbol->debug |= debug; - ret = ZBarcode_Encode(symbol, (unsigned char *) data, (int) strlen(data)); + if (test_performance) { + start = clock(); + } + ret = ZBarcode_Encode(symbol, (unsigned char *) data, (int) strlen(data)); + if (test_performance) { + total += clock() - start; + } - if (strcmp(return_code, "00") == 0) { + if (strcmp(return_code, "00") == 0) { - assert_zero(ret, "lc:%d ZBarcode_Encode ret %d != 0\n", lc, ret); + assert_zero(ret, "lc:%d ZBarcode_Encode ret %d != 0\n", lc, ret); - assert_equal(symbol->rows, 3, "rows %d != 3", symbol->rows); + assert_equal(symbol->rows, 3, "rows %d != 3", symbol->rows); - ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft)); - assert_nonzero(ret, "lc:%d testUtilDAFTConvert == 0", lc); - assert_zero(strcmp(actual_daft, expected_daft), "lc:%d\n actual %s\nexpected %s\n", lc, actual_daft, expected_daft); - } else { - assert_nonzero(ret, "lc:%d ZBarcode_Encode ret %d == 0\n", lc, ret); - } + ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft)); + assert_nonzero(ret, "lc:%d testUtilDAFTConvert == 0", lc); + assert_zero(strcmp(actual_daft, expected_daft), "lc:%d\n actual %s\nexpected %s\n", lc, actual_daft, expected_daft); + } else { + assert_nonzero(ret, "lc:%d ZBarcode_Encode ret %d == 0\n", lc, ret); + } - ZBarcode_Delete(symbol); - } + ZBarcode_Delete(symbol); + } - assert_zero(fclose(fd), "fclose != 0\n"); + assert_zero(fclose(fd), "fclose != 0\n"); + } + if (test_performance) { + printf("test_csv perf total: %8gms\n", TEST_PERF_TIME(total)); + } testFinish(); } diff --git a/backend/tests/test_large.c b/backend/tests/test_large.c index cf766080..5f7f8a5c 100644 --- a/backend/tests/test_large.c +++ b/backend/tests/test_large.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 - 2021 Robin Stuart + Copyright (C) 2020-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" #include "../large.h" @@ -51,7 +51,7 @@ #define LI(l, h) { l, h } -int clz_u64(uint64_t x); +INTERNAL int clz_u64_test(uint64_t x); static void test_clz_u64(int index) { @@ -197,7 +197,7 @@ static void test_clz_u64(int index) { if (index != -1 && i != index) continue; - ret = clz_u64(data[i].s); + ret = clz_u64_test(data[i].s); assert_equal(ret, data[i].ret, "i:%d 0x%" LX_FMT "X ret %d != %d\n", i, data[i].s, ret, data[i].ret); } @@ -904,3 +904,5 @@ int main(int argc, char *argv[]) { return 0; } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 852e4354..bafdd49e 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" #include @@ -284,12 +285,12 @@ static void test_checks_segs(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 0, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 205: Input segment count 0" }, + /* 0*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 0, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 205: No input data" }, /* 1*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 257, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 771: Too many input segments (max 256)" }, /* 2*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 772: Input segment 0 source NULL" }, - /* 3*/ { BARCODE_CODE128, -1, { { TU(""), 0, 0 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 773: Input segment 0 length zero" }, + /* 3*/ { BARCODE_CODE128, -1, { { TU(""), 0, 0 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 778: No input data" }, /* 4*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 0 }, { NULL, 0, 0 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 772: Input segment 1 source NULL" }, - /* 4*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 0 }, { TU(""), 0, 0 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 773: Input segment 1 length zero" }, + /* 4*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 0 }, { TU(""), 0, 0 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 773: Input segment 1 empty" }, /* 5*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 0 } }, 2, -1, 4, -1, ZINT_ERROR_INVALID_OPTION, "Error 774: Symbol ECI 4 must match segment zero ECI 3" }, /* 6*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 4 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 775: Symbology does not support multiple segments" }, /* 7*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching" }, @@ -330,6 +331,63 @@ static void test_checks_segs(int index, int debug) { testFinish(); } +static void test_input_data(int index, int debug) { + + struct item { + int symbology; + int input_mode; + char *data; + int length; + char *composite; + int ret; + + char *expected; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { BARCODE_CODE128, -1, "1234", -1, "", 0, "" }, + /* 1*/ { BARCODE_GS1_128, -1, "[01]12345678901231", -1, "", 0, "" }, + /* 2*/ { BARCODE_GS1_128, -1, "", -1, "", ZINT_ERROR_INVALID_DATA, "Error 778: No input data" }, + /* 3*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", -1, "[10]121212", 0, "" }, + /* 4*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", -1, "", ZINT_ERROR_INVALID_DATA, "Error 779: No composite data in 2D component" }, + /* 5*/ { BARCODE_GS1_128_CC, -1, "", -1, "[10]121212", ZINT_ERROR_INVALID_OPTION, "Error 445: No primary (linear) message in 2D composite" }, + /* 6*/ { BARCODE_DATAMATRIX, -1, "", -1, "", ZINT_ERROR_INVALID_DATA, "Error 778: No input data (segment 0 empty)" }, + }; + int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol; + + char *text; + + testStart("test_input_data"); + + for (i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + if (is_composite(data[i].symbology)) { + text = data[i].composite; + strcpy(symbol->primary, data[i].data); + } else { + text = data[i].data; + } + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, text, -1, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) text, length); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt); + + ret = strcmp(symbol->errtxt, data[i].expected); + assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + static void test_symbologies(void) { int i, ret; struct zint_symbol symbol = {0}; @@ -416,32 +474,72 @@ static void test_escape_char_process(int index, int generate, int debug) { /* 6*/ { BARCODE_MAXICODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "(144) 04 3E 3E 00 04 07 08 09 0A 0B 03 3D 2C 24 19 1E 23 1B 18 0E 0C 0D 1E 21 3C 1E 3C 31", 0, "" }, /* 7*/ { BARCODE_PDF417, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 120, "(24) 16 901 0 23 655 318 98 18 461 639 893 122 129 92 900 900 872 438 359 646 522 773 831", 0, "" }, /* 8*/ { BARCODE_ULTRA, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 20, "(15) 257 0 4 7 8 9 10 11 12 13 27 29 30 129 92", 0, "" }, - /* 9*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character in input data", 0, "" }, - /* 10*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", 0, "" }, - /* 11*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" }, - /* 12*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" }, - /* 13*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Corrupt escape character in input data", 0, "" }, - /* 14*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xA01\\xFF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 0, "" }, - /* 15*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00A01\\u00FF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, - /* 16*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xc3\\xbF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 0, "" }, - /* 17*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00fF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, - /* 18*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\xc3\\xbF", 0, 10, "EB 80 81 47 1E 45 FC 93", 0, "" }, - /* 19*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00fF", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, - /* 20*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, - /* 21*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uF", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, - /* 22*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u0F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, - /* 23*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uFG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, - /* 24*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, - /* 25*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 211: Corrupt Unicode escape character in input data", 0, "" }, - /* 26*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ufffe", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Reversed BOM" }, - /* 27*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ud800", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" }, - /* 28*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\udfff", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" }, - /* 29*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\xE2\\x82\\xAC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 0, "Zint manual 4.10 Ex1" }, - /* 30*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\u20AC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, - /* 31*/ { BARCODE_DATAMATRIX, DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, - /* 32*/ { BARCODE_DATAMATRIX, DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" }, - /* 33*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" }, - /* 34*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u007F", 0, 10, "80 81 46 73 64 88 6A 84", 0, "" }, + /* 9*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\d129\\o201\\\\", 0, 18, "(32) 01 05 08 09 0A 0B 0C 0D 0E 1C 1E 1F E7 32 45 DB 70 5D E3 16 7B 2B 44 60 E1 55 F7 08", 0, "" }, + /* 10*/ { BARCODE_HANXIN, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\d129\\o201\\\\", 0, 23, "2F 80 10 72 09 28 B3 0D 6F F3 00 30 E8 F4 0C 0C 0A E0 00 00 00", 0, "" }, + /* 11*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character '\\c' in input data", 0, "" }, + /* 12*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", 0, "" }, + /* 13*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\x' escape sequence in input data", 0, "" }, + /* 14*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\x' escape sequence in input data", 0, "" }, + /* 15*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Invalid character for '\\x' escape sequence in input data (hexadecimal only)", 0, "" }, + /* 16*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\d' escape sequence in input data", 0, "" }, + /* 17*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\d' escape sequence in input data", 0, "" }, + /* 18*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d12", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\d' escape sequence in input data", 0, "" }, + /* 19*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d12a", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Invalid character for '\\d' escape sequence in input data (decimal only)", 0, "" }, + /* 20*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\o' escape sequence in input data", 0, "" }, + /* 21*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\o' escape sequence in input data", 0, "" }, + /* 22*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o12", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete '\\o' escape sequence in input data", 0, "" }, + /* 23*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o128", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Invalid character for '\\o' escape sequence in input data (octal only)", 0, "" }, + /* 24*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xA01\\xFF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 0, "" }, + /* 25*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d1601\\d255", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, + /* 26*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o2401\\o377", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, + /* 27*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00A01\\u00FF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, + /* 28*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\U0000A01\\U0000FF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, + /* 29*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xc3\\xbF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 0, "" }, + /* 30*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\d195\\d191", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, + /* 31*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\o303\\o277", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, + /* 32*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00fF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, + /* 33*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U0000fF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, + /* 34*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\xc3\\xbF", 0, 10, "EB 80 81 47 1E 45 FC 93", 0, "" }, + /* 35*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\d195\\d191", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, + /* 36*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\o303\\o277", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, + /* 37*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00fF", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, + /* 38*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\U0000fF", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, + /* 39*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\u' escape sequence in input data", 0, "" }, + /* 40*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uF", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\u' escape sequence in input data", 0, "" }, + /* 41*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u0F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\u' escape sequence in input data", 0, "" }, + /* 42*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uFG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\u' escape sequence in input data", 0, "" }, + /* 43*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\u' escape sequence in input data", 0, "" }, + /* 44*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 211: Invalid character for '\\u' escape sequence in input data (hexadecimal only)", 0, "" }, + /* 45*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ufffe", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid value for '\\u' escape sequence in input data", 0, "Reversed BOM" }, + /* 46*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ud800", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid value for '\\u' escape sequence in input data", 0, "Surrogate" }, + /* 47*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\udfff", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid value for '\\u' escape sequence in input data", 0, "Surrogate" }, + /* 48*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\xE2\\x82\\xAC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 0, "Zint manual 4.10 Ex1" }, + /* 49*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\u20AC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, + /* 50*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\U0020AC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, + /* 51*/ { BARCODE_DATAMATRIX, DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, + /* 52*/ { BARCODE_DATAMATRIX, DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" }, + /* 53*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" }, + /* 54*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\U005E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" }, + /* 55*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u007F", 0, 10, "80 81 46 73 64 88 6A 84", 0, "" }, + /* 56*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\U00007F", 0, 10, "80 81 46 73 64 88 6A 84", 0, "" }, + /* 57*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 58*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\UF", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 59*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U0F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 60*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\UFG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 61*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U00F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 62*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 63*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\Ufffe", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "Reversed BOM" }, + /* 64*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\Ud800", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "Surrogate" }, + /* 65*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\Udfff", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "Surrogate" }, + /* 66*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U000F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 67*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U0000F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete '\\U' escape sequence in input data", 0, "" }, + /* 68*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\U110000", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid value for '\\U' escape sequence in input data", 0, "" }, + /* 69*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 25, "\\U10FFFF", 0, 14, "F1 1A 01 01 EB 80 EB 80 3F C0 9C 0B 4B B8 DA B7 B6 1A", 0, "" }, + /* 70*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 26, "\\U10FFFF", 0, 14, "F1 1B 01 E7 EC 71 D7 6C 20 D6 B3 63 E2 18 B6 4C 7D 3E", 0, "" }, + /* 71*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 32, "\\U10FFFF", 0, 32, "F1 21 01 EB 05 32 EB 25 3A 81 7E 98 9B 50 AC 1C E0 4E 51 BA 23", 0, "" }, + /* 72*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 33, "\\U10FFFF", 0, 14, "F1 22 01 01 EB 80 EB 80 A3 E5 BE FB 1A 08 94 2E C3 74", 0, "" }, + /* 73*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 34, "\\U10FFFF", 0, 16, "F1 23 01 01 01 01 01 01 EB 80 EB 80 F6 F1 5D 2A D1 0A BF BC B8 22 65 0C", 0, "" }, + /* 74*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 35, "\\U10FFFF", 0, 16, "F1 24 01 01 01 01 EB 80 EB 80 01 01 7F 58 28 41 7F 63 0E EB A7 D8 D0 1F", 0, "" }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1026,7 +1124,7 @@ static void test_valid_id(void) { testFinish(); } -STATIC_UNLESS_ZINT_TEST int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string); +INTERNAL int error_tag_test(struct zint_symbol *symbol, int error_number, const char *error_string); static void test_error_tag(int index) { @@ -1067,13 +1165,13 @@ static void test_error_tag(int index) { symbol.warn_level = data[i].warn_level; - ret = error_tag(&symbol, data[i].error_number, data[i].data); + ret = error_tag_test(&symbol, data[i].error_number, data[i].data); assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol.errtxt, data[i].expected); if ((int) strlen(data[i].data) < 100) { strcpy(symbol.errtxt, data[i].data); - ret = error_tag(&symbol, data[i].error_number, NULL); + ret = error_tag_test(&symbol, data[i].error_number, NULL); assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol.errtxt, data[i].expected); } @@ -1082,7 +1180,7 @@ static void test_error_tag(int index) { testFinish(); } -STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length); +INTERNAL void strip_bom_test(unsigned char *source, int *input_length); static void test_strip_bom(void) { @@ -1095,7 +1193,7 @@ static void test_strip_bom(void) { strcpy(buf, data); length = (int) strlen(buf); - strip_bom(TU(buf), &length); + strip_bom_test(TU(buf), &length); assert_equal(length, 1, "length %d != 1\n", length); assert_zero(buf[1], "buf[1] %d != 0\n", buf[1]); @@ -1103,7 +1201,7 @@ static void test_strip_bom(void) { strcpy(buf, bom_only); length = (int) strlen(buf); - strip_bom(TU(buf), &length); + strip_bom_test(TU(buf), &length); assert_equal(length, 3, "BOM only length %d != 3\n", length); ret = strcmp(buf, bom_only); assert_zero(ret, "BOM only strcmp ret %d != 0\n", ret); @@ -1239,6 +1337,7 @@ int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ { "test_checks", test_checks, 1, 0, 1 }, { "test_checks_segs", test_checks_segs, 1, 0, 1 }, + { "test_input_data", test_input_data, 1, 0, 1 }, { "test_symbologies", test_symbologies, 0, 0, 0 }, { "test_input_mode", test_input_mode, 1, 0, 1 }, { "test_escape_char_process", test_escape_char_process, 1, 1, 1 }, diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c index 2b5466d2..e678e2a1 100644 --- a/backend/tests/test_output.c +++ b/backend/tests/test_output.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2021 Robin Stuart + Copyright (C) 2021-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" -STATIC_UNLESS_ZINT_TEST int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, +INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hide_text, float *left, float *right, float *top, float *bottom); static void test_quiet_zones(void) { @@ -46,7 +46,7 @@ static void test_quiet_zones(void) { if (!ZBarcode_ValidID(i)) continue; symbol.symbology = i; symbol.output_options = BARCODE_QUIET_ZONES; - ret = out_quiet_zones(&symbol, hide_text, &left, &right, &top, &bottom); + ret = out_quiet_zones_test(&symbol, hide_text, &left, &right, &top, &bottom); if (i != BARCODE_FLAT) { // Only one which isn't marked as done assert_nonzero(ret, "i:%d %s not done\n", i, testUtilBarcodeName(i)); } @@ -67,3 +67,5 @@ int main(int argc, char *argv[]) { return 0; } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 23673c74..18ab23f2 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 - 2021 Robin Stuart + Copyright (C) 2020-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" #include @@ -337,7 +337,7 @@ struct wpng_error_type { jmp_buf jmpbuf; }; -STATIC_UNLESS_ZINT_TEST void wpng_error_handler(png_structp png_ptr, png_const_charp msg); +INTERNAL void wpng_error_handler_test(png_structp png_ptr, png_const_charp msg); static void test_wpng_error_handler(void) { int ret; @@ -363,7 +363,7 @@ static void test_wpng_error_handler(void) { fp = fopen(filename, "r"); assert_nonnull(fp, "fopen(%s) for read failed\n", filename); - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &wpng_error, wpng_error_handler, NULL); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &wpng_error, wpng_error_handler_test, NULL); assert_nonnull(png_ptr, "png_create_write_struct failed\n"); info_ptr = png_create_info_struct(png_ptr); @@ -429,3 +429,5 @@ int main(int argc, char *argv[]) { return 0; } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_ps.c b/backend/tests/test_ps.c index 1a3a6a63..7c2caefc 100644 --- a/backend/tests/test_ps.c +++ b/backend/tests/test_ps.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 - 2021 Robin Stuart + Copyright (C) 2020-2022 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" #include @@ -180,7 +180,7 @@ static void test_print(int index, int generate, int debug) { testFinish(); } -void ps_convert(const unsigned char *string, unsigned char *ps_string); +INTERNAL void ps_convert_test(const unsigned char *string, unsigned char *ps_string); static void test_ps_convert(int index) { @@ -202,7 +202,7 @@ static void test_ps_convert(int index) { if (index != -1 && i != index) continue; - ps_convert((unsigned char *) data[i].data, converted); + ps_convert_test((unsigned char *) data[i].data, converted); assert_zero(strcmp((char *) converted, data[i].expected), "i:%d ps_convert(%s) %s != %s\n", i, data[i].data, converted, data[i].expected); } @@ -253,3 +253,5 @@ int main(int argc, char *argv[]) { return 0; } + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_qr.c b/backend/tests/test_qr.c index 94408898..3cdcfad8 100644 --- a/backend/tests/test_qr.c +++ b/backend/tests/test_qr.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" @@ -288,6 +289,23 @@ static void test_qr_input(int index, int generate, int debug) { /*125*/ { UNICODE_MODE, 900, 4, 8 << 8, "é", 0, 900, "78 38 44 02 C3 A9 00 EC 11", 1, 1, "ECI-900 B2 (no conversion)" }, /*126*/ { UNICODE_MODE, 16384, 4, 8 << 8, "é", 0, 16384, "7C 04 00 04 02 C3 A9 00 EC", 1, 1, "ECI-16384 B2 (no conversion)" }, /*127*/ { UNICODE_MODE, 3, 4, -1, "product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97", 0, 3, "(86) 70 34 39 70 72 6F 64 75 63 74 3A 47 6F 6F 67 6C 65 20 50 69 78 65 6C 20 34 61 20 2D", 0, 1, "ECI-3 B57 A8; BWIPP different encodation (B65)" }, + /*128*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\176", 0, 0, "80 10 1F 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0x817E)" }, + /*129*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\177", 0, 0, "40 28 17 F0 EC 11 EC 11 EC", 1, 1, "B2 (0x817F previously used Kanji mode, now excludes trailing 0x7F)" }, + /*130*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\200", 0, 0, "80 10 20 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0x8180)" }, + /*131*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\237\176", 0, 0, "80 1B 5F 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0x9F7E)" }, + /*132*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\237\177", 0, 0, "40 29 F7 F0 EC 11 EC 11 EC", 1, 1, "B2 (0x9F7F previously used Kanji mode, now excludes trailing 0x7F)" }, + /*133*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\340\176", 0, 0, "80 1B BF 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0xE07E)" }, + /*134*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\340\177", 0, 0, "40 2E 07 F0 EC 11 EC 11 EC", 1, 1, "B2 (0xE07F previously used Kanji mode, now excludes trailing 0x7F)" }, + /*135*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\352\244", 0, 0, "80 1F 92 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0xEAA4, last valid codepoint)" }, + /*136*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\353\277", 0, 0, "80 1F FF 80 EC 11 EC 11 EC", 1, 1, "K1 (0xEBBF undefined in Shift JIS but not checked and uses Kanji mode)" }, + /*137*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\353\300", 0, 0, "40 2E BC 00 EC 11 EC 11 EC", 1, 1, "B2 (0xEBC0 was always excluded)" }, + /*138*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\300", 0, 0, "80 10 40 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0x81C0)" }, + /*139*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\374", 0, 0, "80 10 5E 00 EC 11 EC 11 EC", 1, 1, "K1 (Shift JIS 0x81FC)" }, + /*140*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\375", 0, 0, "40 28 1F D0 EC 11 EC 11 EC", 1, 1, "B2 (0x81FD previously used Kanji mode, now excludes trailing 0xFD)" }, + /*141*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\376", 0, 0, "40 28 1F E0 EC 11 EC 11 EC", 1, 1, "B2 (0x81FE previously used Kanji mode, now excludes trailing 0xFE)" }, + /*142*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\377", 0, 0, "40 28 1F F0 EC 11 EC 11 EC", 1, 1, "B2 (0x81FF previously used Kanji mode, now excludes trailing 0xFF)" }, + /*143*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\377", 0, 0, "40 28 1F F0 EC 11 EC 11 EC", 1, 1, "B2 (0x81FF previously used Kanji mode, now excludes trailing 0xFF)" }, + /*144*/ { DATA_MODE, 0, 4, ZINT_FULL_MULTIBYTE, "\201\255", 0, 0, "80 10 36 80 EC 11 EC 11 EC", 1, 1, "K1 (0x81AD undefined in Shift JIS but not checked and uses Kanji mode)" }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -5854,6 +5872,576 @@ static void test_upnqr_encode(int index, int generate, int debug) { testFinish(); } +static void test_rmqr_large(int index, int debug) { + + struct item { + int option_1; + int option_2; + char *pattern; + int length; + int ret; + int expected_rows; + int expected_width; + }; + // ISO/IEC 23941:2022 Table 6 + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { 2, 1, "1", 12, 0, 7, 43 }, + /* 1*/ { 2, 1, "1", 13, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 2*/ { 2, 1, "A", 7, 0, 7, 43 }, + /* 3*/ { 2, 1, "A", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 4*/ { 2, 1, "\200", 5, 0, 7, 43 }, + /* 5*/ { 2, 1, "\200", 6, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 6*/ { 2, 1, "\201", 6, 0, 7, 43 }, // 3 Shift JIS 0x8181 + /* 7*/ { 2, 1, "\201", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, // 4 Shift JIS 0x8181 + /* 8*/ { 4, 1, "1", 5, 0, 7, 43 }, + /* 9*/ { 4, 1, "1", 6, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 10*/ { 4, 1, "A", 3, 0, 7, 43 }, + /* 11*/ { 4, 1, "A", 4, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 12*/ { 4, 1, "\200", 2, 0, 7, 43 }, + /* 13*/ { 4, 1, "\200", 3, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 14*/ { 4, 1, "\201", 2, 0, 7, 43 }, // 1 Shift JIS 0x8181 + /* 15*/ { 4, 1, "\201", 4, ZINT_ERROR_TOO_LONG, -1, -1 }, // 2 Shift JIS 0x8181 + /* 16*/ { 2, 2, "1", 26, 0, 7, 59 }, + /* 17*/ { 2, 2, "1", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 18*/ { 2, 2, "A", 16, 0, 7, 59 }, + /* 19*/ { 2, 2, "A", 17, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 20*/ { 2, 2, "\200", 11, 0, 7, 59 }, + /* 21*/ { 2, 2, "\200", 12, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 22*/ { 2, 2, "\201", 12, 0, 7, 59 }, // 6 Shift JIS 0x8181 + /* 23*/ { 2, 2, "\201", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, // 7 Shift JIS 0x8181 + /* 24*/ { 4, 2, "1", 14, 0, 7, 59 }, + /* 25*/ { 4, 2, "1", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 26*/ { 4, 2, "A", 8, 0, 7, 59 }, + /* 27*/ { 4, 2, "A", 9, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 28*/ { 4, 2, "\200", 6, 0, 7, 59 }, + /* 29*/ { 4, 2, "\200", 7, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 30*/ { 4, 2, "\201", 6, 0, 7, 59 }, // 3 Shift JIS 0x8181 + /* 31*/ { 4, 2, "\201", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, // 4 Shift JIS 0x8181 + /* 32*/ { 2, 3, "1", 45, 0, 7, 77 }, + /* 33*/ { 2, 3, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 34*/ { 2, 3, "A", 27, 0, 7, 77 }, + /* 35*/ { 2, 3, "A", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 36*/ { 2, 3, "\200", 19, 0, 7, 77 }, + /* 37*/ { 2, 3, "\200", 20, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 38*/ { 2, 3, "\201", 22, 0, 7, 77 }, // 11 Shift JIS 0x8181 + /* 39*/ { 2, 3, "\201", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, // 12 Shift JIS 0x8181 + /* 40*/ { 4, 3, "1", 21, 0, 7, 77 }, + /* 41*/ { 4, 3, "1", 22, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 42*/ { 4, 3, "A", 13, 0, 7, 77 }, + /* 43*/ { 4, 3, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 44*/ { 4, 3, "\200", 9, 0, 7, 77 }, + /* 45*/ { 4, 3, "\200", 10, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 46*/ { 4, 3, "\201", 10, 0, 7, 77 }, // 5 Shift JIS 0x8181 + /* 47*/ { 4, 3, "\201", 12, ZINT_ERROR_TOO_LONG, -1, -1 }, // 6 Shift JIS 0x8181 + /* 48*/ { 2, 4, "1", 64, 0, 7, 99 }, + /* 49*/ { 2, 4, "1", 65, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 50*/ { 2, 4, "A", 39, 0, 7, 99 }, + /* 51*/ { 2, 4, "A", 40, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 52*/ { 2, 4, "\200", 27, 0, 7, 99 }, + /* 53*/ { 2, 4, "\200", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 54*/ { 2, 4, "\201", 32, 0, 7, 99 }, // 16 Shift JIS 0x8181 + /* 55*/ { 2, 4, "\201", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, // 17 Shift JIS 0x8181 + /* 56*/ { 4, 4, "1", 30, 0, 7, 99 }, + /* 57*/ { 4, 4, "1", 31, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 58*/ { 4, 4, "A", 18, 0, 7, 99 }, + /* 59*/ { 4, 4, "A", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 60*/ { 4, 4, "\200", 13, 0, 7, 99 }, + /* 61*/ { 4, 4, "\200", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 62*/ { 4, 4, "\201", 16, 0, 7, 99 }, // 8 Shift JIS 0x8181 + /* 63*/ { 4, 4, "\201", 18, ZINT_ERROR_TOO_LONG, -1, -1 }, // 9 Shift JIS 0x8181 + /* 64*/ { 2, 5, "1", 102, 0, 7, 139 }, + /* 65*/ { 2, 5, "1", 103, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 66*/ { 2, 5, "A", 62, 0, 7, 139 }, + /* 67*/ { 2, 5, "A", 63, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 68*/ { 2, 5, "\200", 42, 0, 7, 139 }, + /* 69*/ { 2, 5, "\200", 43, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 70*/ { 2, 5, "\201", 52, 0, 7, 139 }, // 26 Shift JIS 0x8181 + /* 71*/ { 2, 5, "\201", 54, ZINT_ERROR_TOO_LONG, -1, -1 }, // 27 Shift JIS 0x8181 + /* 72*/ { 4, 5, "1", 54, 0, 7, 139 }, + /* 73*/ { 4, 5, "1", 55, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 74*/ { 4, 5, "A", 33, 0, 7, 139 }, + /* 75*/ { 4, 5, "A", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 76*/ { 4, 5, "\200", 22, 0, 7, 139 }, + /* 77*/ { 4, 5, "\200", 23, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 78*/ { 4, 5, "\201", 28, 0, 7, 139 }, // 14 Shift JIS 0x8181 + /* 79*/ { 4, 5, "\201", 30, ZINT_ERROR_TOO_LONG, -1, -1 }, // 15 Shift JIS 0x8181 + /* 80*/ { 2, 6, "1", 26, 0, 9, 43 }, + /* 81*/ { 2, 6, "1", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 82*/ { 2, 6, "A", 16, 0, 9, 43 }, + /* 83*/ { 2, 6, "A", 17, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 84*/ { 2, 6, "\200", 11, 0, 9, 43 }, + /* 85*/ { 2, 6, "\200", 12, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 86*/ { 2, 6, "\201", 12, 0, 9, 43 }, // 6 Shift JIS 0x8181 + /* 87*/ { 2, 6, "\201", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, // 7 Shift JIS 0x8181 + /* 88*/ { 4, 6, "1", 14, 0, 9, 43 }, + /* 89*/ { 4, 6, "1", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 90*/ { 4, 6, "A", 8, 0, 9, 43 }, + /* 91*/ { 4, 6, "A", 9, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 92*/ { 4, 6, "\200", 6, 0, 9, 43 }, + /* 93*/ { 4, 6, "\200", 7, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 94*/ { 4, 6, "\201", 6, 0, 9, 43 }, // 3 Shift JIS 0x8181 + /* 95*/ { 4, 6, "\201", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, // 4 Shift JIS 0x8181 + /* 96*/ { 2, 7, "1", 47, 0, 9, 59 }, + /* 97*/ { 2, 7, "1", 48, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 98*/ { 2, 7, "A", 29, 0, 9, 59 }, + /* 99*/ { 2, 7, "A", 30, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*100*/ { 2, 7, "\200", 20, 0, 9, 59 }, + /*101*/ { 2, 7, "\200", 21, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*102*/ { 2, 7, "\201", 24, 0, 9, 59 }, // 12 Shift JIS 0x8181 + /*103*/ { 2, 7, "\201", 26, ZINT_ERROR_TOO_LONG, -1, -1 }, // 13 Shift JIS 0x8181 + /*104*/ { 4, 7, "1", 23, 0, 9, 59 }, + /*105*/ { 4, 7, "1", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*106*/ { 4, 7, "A", 14, 0, 9, 59 }, + /*107*/ { 4, 7, "A", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*108*/ { 4, 7, "\200", 10, 0, 9, 59 }, + /*109*/ { 4, 7, "\200", 11, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*110*/ { 4, 7, "\201", 12, 0, 9, 59 }, // 6 Shift JIS 0x8181 + /*111*/ { 4, 7, "\201", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, // 7 Shift JIS 0x8181 + /*112*/ { 2, 8, "1", 71, 0, 9, 77 }, + /*113*/ { 2, 8, "1", 72, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*114*/ { 2, 8, "A", 43, 0, 9, 77 }, + /*115*/ { 2, 8, "A", 44, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*116*/ { 2, 8, "\200", 30, 0, 9, 77 }, + /*117*/ { 2, 8, "\200", 31, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*118*/ { 2, 8, "\201", 36, 0, 9, 77 }, // 18 Shift JIS 0x8181 + /*119*/ { 2, 8, "\201", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, // 19 Shift JIS 0x8181 + /*120*/ { 4, 8, "1", 37, 0, 9, 77 }, + /*121*/ { 4, 8, "1", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*122*/ { 4, 8, "A", 23, 0, 9, 77 }, + /*123*/ { 4, 8, "A", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*124*/ { 4, 8, "\200", 16, 0, 9, 77 }, + /*125*/ { 4, 8, "\200", 17, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*126*/ { 4, 8, "\201", 18, 0, 9, 77 }, // 9 Shift JIS 0x8181 + /*127*/ { 4, 8, "\201", 20, ZINT_ERROR_TOO_LONG, -1, -1 }, // 10 Shift JIS 0x8181 + /*128*/ { 2, 9, "1", 97, 0, 9, 99 }, + /*129*/ { 2, 9, "1", 98, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*130*/ { 2, 9, "A", 59, 0, 9, 99 }, + /*131*/ { 2, 9, "A", 60, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*132*/ { 2, 9, "\200", 40, 0, 9, 99 }, + /*133*/ { 2, 9, "\200", 41, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*134*/ { 2, 9, "\201", 50, 0, 9, 99 }, // 25 Shift JIS 0x8181 + /*135*/ { 2, 9, "\201", 52, ZINT_ERROR_TOO_LONG, -1, -1 }, // 26 Shift JIS 0x8181 + /*136*/ { 4, 9, "1", 49, 0, 9, 99 }, + /*137*/ { 4, 9, "1", 50, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*138*/ { 4, 9, "A", 30, 0, 9, 99 }, + /*139*/ { 4, 9, "A", 31, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*140*/ { 4, 9, "\200", 20, 0, 9, 99 }, + /*141*/ { 4, 9, "\200", 21, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*142*/ { 4, 9, "\201", 24, 0, 9, 99 }, // 12 Shift JIS 0x8181 + /*143*/ { 4, 9, "\201", 26, ZINT_ERROR_TOO_LONG, -1, -1 }, // 13 Shift JIS 0x8181 + /*144*/ { 2, 10, "1", 147, 0, 9, 139 }, + /*145*/ { 2, 10, "1", 148, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*146*/ { 2, 10, "A", 89, 0, 9, 139 }, + /*147*/ { 2, 10, "A", 90, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*148*/ { 2, 10, "\200", 61, 0, 9, 139 }, + /*149*/ { 2, 10, "\200", 62, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*150*/ { 2, 10, "\201", 76, 0, 9, 139 }, // 36 Shift JIS 0x8181 + /*151*/ { 2, 10, "\201", 78, ZINT_ERROR_TOO_LONG, -1, -1 }, // 37 Shift JIS 0x8181 + /*152*/ { 4, 10, "1", 75, 0, 9, 139 }, + /*153*/ { 4, 10, "1", 76, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*154*/ { 4, 10, "A", 46, 0, 9, 139 }, + /*155*/ { 4, 10, "A", 47, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*156*/ { 4, 10, "\200", 31, 0, 9, 139 }, + /*157*/ { 4, 10, "\200", 32, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*158*/ { 4, 10, "\201", 38, 0, 9, 139 }, // 19 Shift JIS 0x8181 + /*159*/ { 4, 10, "\201", 40, ZINT_ERROR_TOO_LONG, -1, -1 }, // 20 Shift JIS 0x8181 + /*160*/ { 2, 11, "1", 14, 0, 11, 27 }, + /*161*/ { 2, 11, "1", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*162*/ { 2, 11, "A", 8, 0, 11, 27 }, + /*163*/ { 2, 11, "A", 9, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*164*/ { 2, 11, "\200", 6, 0, 11, 27 }, + /*165*/ { 2, 11, "\200", 7, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*166*/ { 2, 11, "\201", 6, 0, 11, 27 }, // 3 Shift JIS 0x8181 + /*167*/ { 2, 11, "\201", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, // 4 Shift JIS 0x8181 + /*168*/ { 4, 11, "1", 9, 0, 11, 27 }, + /*169*/ { 4, 11, "1", 10, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*170*/ { 4, 11, "A", 6, 0, 11, 27 }, + /*171*/ { 4, 11, "A", 7, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*172*/ { 4, 11, "\200", 4, 0, 11, 27 }, + /*173*/ { 4, 11, "\200", 5, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*174*/ { 4, 11, "\201", 4, 0, 11, 27 }, // 2 Shift JIS 0x8181 + /*175*/ { 4, 11, "\201", 6, ZINT_ERROR_TOO_LONG, -1, -1 }, // 3 Shift JIS 0x8181 + /*176*/ { 2, 12, "1", 42, 0, 11, 43 }, + /*177*/ { 2, 12, "1", 43, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*178*/ { 2, 12, "A", 26, 0, 11, 43 }, + /*179*/ { 2, 12, "A", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*180*/ { 2, 12, "\200", 18, 0, 11, 43 }, + /*181*/ { 2, 12, "\200", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*182*/ { 2, 12, "\201", 22, 0, 11, 43 }, // 11 Shift JIS 0x8181 + /*183*/ { 2, 12, "\201", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, // 12 Shift JIS 0x8181 + /*184*/ { 4, 12, "1", 23, 0, 11, 43 }, + /*185*/ { 4, 12, "1", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*186*/ { 4, 12, "A", 14, 0, 11, 43 }, + /*187*/ { 4, 12, "A", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*188*/ { 4, 12, "\200", 10, 0, 11, 43 }, + /*189*/ { 4, 12, "\200", 11, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*190*/ { 4, 12, "\201", 12, 0, 11, 43 }, // 6 Shift JIS 0x8181 + /*191*/ { 4, 12, "\201", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, // 7 Shift JIS 0x8181 + /*192*/ { 2, 13, "1", 71, 0, 11, 59 }, + /*193*/ { 2, 13, "1", 72, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*194*/ { 2, 13, "A", 43, 0, 11, 59 }, + /*195*/ { 2, 13, "A", 44, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*196*/ { 2, 13, "\200", 30, 0, 11, 59 }, + /*197*/ { 2, 13, "\200", 31, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*198*/ { 2, 13, "\201", 36, 0, 11, 59 }, // 18 Shift JIS 0x8181 + /*199*/ { 2, 13, "\201", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, // 19 Shift JIS 0x8181 + /*200*/ { 4, 13, "1", 33, 0, 11, 59 }, + /*201*/ { 4, 13, "1", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*202*/ { 4, 13, "A", 20, 0, 11, 59 }, + /*203*/ { 4, 13, "A", 21, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*204*/ { 4, 13, "\200", 14, 0, 11, 59 }, + /*205*/ { 4, 13, "\200", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*206*/ { 4, 13, "\201", 16, 0, 11, 59 }, // 8 Shift JIS 0x8181 + /*207*/ { 4, 13, "\201", 18, ZINT_ERROR_TOO_LONG, -1, -1 }, // 9 Shift JIS 0x8181 + /*208*/ { 2, 14, "1", 100, 0, 11, 77 }, + /*209*/ { 2, 14, "1", 101, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*210*/ { 2, 14, "A", 60, 0, 11, 77 }, + /*211*/ { 2, 14, "A", 61, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*212*/ { 2, 14, "\200", 41, 0, 11, 77 }, + /*213*/ { 2, 14, "\200", 42, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*214*/ { 2, 14, "\201", 50, 0, 11, 77 }, // 25 Shift JIS 0x8181 + /*215*/ { 2, 14, "\201", 52, ZINT_ERROR_TOO_LONG, -1, -1 }, // 26 Shift JIS 0x8181 + /*216*/ { 4, 14, "1", 52, 0, 11, 77 }, + /*217*/ { 4, 14, "1", 53, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*218*/ { 4, 14, "A", 31, 0, 11, 77 }, + /*219*/ { 4, 14, "A", 32, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*220*/ { 4, 14, "\200", 21, 0, 11, 77 }, + /*221*/ { 4, 14, "\200", 22, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*222*/ { 4, 14, "\201", 26, 0, 11, 77 }, // 13 Shift JIS 0x8181 + /*223*/ { 4, 14, "\201", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, // 14 Shift JIS 0x8181 + /*224*/ { 2, 15, "1", 133, 0, 11, 99 }, + /*225*/ { 2, 15, "1", 134, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*226*/ { 2, 15, "A", 81, 0, 11, 99 }, + /*227*/ { 2, 15, "A", 82, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*228*/ { 2, 15, "\200", 55, 0, 11, 99 }, + /*229*/ { 2, 15, "\200", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*230*/ { 2, 15, "\201", 68, 0, 11, 99 }, // 34 Shift JIS 0x8181 + /*231*/ { 2, 15, "\201", 70, ZINT_ERROR_TOO_LONG, -1, -1 }, // 35 Shift JIS 0x8181 + /*232*/ { 4, 15, "1", 66, 0, 11, 99 }, + /*233*/ { 4, 15, "1", 67, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*234*/ { 4, 15, "A", 40, 0, 11, 99 }, + /*235*/ { 4, 15, "A", 41, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*236*/ { 4, 15, "\200", 27, 0, 11, 99 }, + /*237*/ { 4, 15, "\200", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*238*/ { 4, 15, "\201", 34, 0, 11, 99 }, // 17 Shift JIS 0x8181 + /*239*/ { 4, 15, "\201", 36, ZINT_ERROR_TOO_LONG, -1, -1 }, // 18 Shift JIS 0x8181 + /*240*/ { 2, 16, "1", 198, 0, 11, 139 }, + /*241*/ { 2, 16, "1", 199, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*242*/ { 2, 16, "A", 120, 0, 11, 139 }, + /*243*/ { 2, 16, "A", 121, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*244*/ { 2, 16, "\200", 82, 0, 11, 139 }, + /*245*/ { 2, 16, "\200", 83, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*246*/ { 2, 16, "\201", 102, 0, 11, 139 }, // 51 Shift JIS 0x8181 + /*247*/ { 2, 16, "\201", 104, ZINT_ERROR_TOO_LONG, -1, -1 }, // 52 Shift JIS 0x8181 + /*248*/ { 4, 16, "1", 97, 0, 11, 139 }, + /*249*/ { 4, 16, "1", 98, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*250*/ { 4, 16, "A", 59, 0, 11, 139 }, + /*251*/ { 4, 16, "A", 60, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*252*/ { 4, 16, "\200", 40, 0, 11, 139 }, + /*253*/ { 4, 16, "\200", 41, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*254*/ { 4, 16, "\201", 50, 0, 11, 139 }, // 25 Shift JIS 0x8181 + /*255*/ { 4, 16, "\201", 52, ZINT_ERROR_TOO_LONG, -1, -1 }, // 26 Shift JIS 0x8181 + /*256*/ { 2, 17, "1", 26, 0, 13, 27 }, + /*257*/ { 2, 17, "1", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*258*/ { 2, 17, "A", 16, 0, 13, 27 }, + /*259*/ { 2, 17, "A", 17, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*260*/ { 2, 17, "\200", 11, 0, 13, 27 }, + /*261*/ { 2, 17, "\200", 12, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*262*/ { 2, 17, "\201", 12, 0, 13, 27 }, // 6 Shift JIS 0x8181 + /*263*/ { 2, 17, "\201", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, // 7 Shift JIS 0x8181 + /*264*/ { 4, 17, "1", 14, 0, 13, 27 }, + /*265*/ { 4, 17, "1", 15, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*266*/ { 4, 17, "A", 8, 0, 13, 27 }, + /*267*/ { 4, 17, "A", 9, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*268*/ { 4, 17, "\200", 6, 0, 13, 27 }, + /*269*/ { 4, 17, "\200", 7, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*270*/ { 4, 17, "\201", 6, 0, 13, 27 }, // 3 Shift JIS 0x8181 + /*271*/ { 4, 17, "\201", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, // 4 Shift JIS 0x8181 + /*272*/ { 2, 18, "1", 62, 0, 13, 43 }, + /*273*/ { 2, 18, "1", 63, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*274*/ { 2, 18, "A", 37, 0, 13, 43 }, + /*275*/ { 2, 18, "A", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*276*/ { 2, 18, "\200", 26, 0, 13, 43 }, + /*277*/ { 2, 18, "\200", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*278*/ { 2, 18, "\201", 32, 0, 13, 43 }, // 16 Shift JIS 0x8181 + /*279*/ { 2, 18, "\201", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, // 17 Shift JIS 0x8181 + /*280*/ { 4, 18, "1", 28, 0, 13, 43 }, + /*281*/ { 4, 18, "1", 29, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*282*/ { 4, 18, "A", 17, 0, 13, 43 }, + /*283*/ { 4, 18, "A", 18, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*284*/ { 4, 18, "\200", 12, 0, 13, 43 }, + /*285*/ { 4, 18, "\200", 13, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*286*/ { 4, 18, "\201", 14, 0, 13, 43 }, // 7 Shift JIS 0x8181 + /*287*/ { 4, 18, "\201", 16, ZINT_ERROR_TOO_LONG, -1, -1 }, // 8 Shift JIS 0x8181 + /*288*/ { 2, 19, "1", 88, 0, 13, 59 }, + /*289*/ { 2, 19, "1", 89, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*290*/ { 2, 19, "A", 53, 0, 13, 59 }, + /*291*/ { 2, 19, "A", 54, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*292*/ { 2, 19, "\200", 36, 0, 13, 59 }, + /*293*/ { 2, 19, "\200", 37, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*294*/ { 2, 19, "\201", 44, 0, 13, 59 }, // 22 Shift JIS 0x8181 + /*295*/ { 2, 19, "\201", 46, ZINT_ERROR_TOO_LONG, -1, -1 }, // 23 Shift JIS 0x8181 + /*296*/ { 4, 19, "1", 45, 0, 13, 59 }, + /*297*/ { 4, 19, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*298*/ { 4, 19, "A", 27, 0, 13, 59 }, + /*299*/ { 4, 19, "A", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*300*/ { 4, 19, "\200", 18, 0, 13, 59 }, + /*301*/ { 4, 19, "\200", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*302*/ { 4, 19, "\201", 22, 0, 13, 59 }, // 11 Shift JIS 0x8181 + /*303*/ { 4, 19, "\201", 24, ZINT_ERROR_TOO_LONG, -1, -1 }, // 12 Shift JIS 0x8181 + /*304*/ { 2, 20, "1", 124, 0, 13, 77 }, + /*305*/ { 2, 20, "1", 125, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*306*/ { 2, 20, "A", 75, 0, 13, 77 }, + /*307*/ { 2, 20, "A", 76, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*308*/ { 2, 20, "\200", 51, 0, 13, 77 }, + /*309*/ { 2, 20, "\200", 52, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*310*/ { 2, 20, "\201", 62, 0, 13, 77 }, // 31 Shift JIS 0x8181 + /*311*/ { 2, 20, "\201", 64, ZINT_ERROR_TOO_LONG, -1, -1 }, // 32 Shift JIS 0x8181 + /*312*/ { 4, 20, "1", 66, 0, 13, 77 }, + /*313*/ { 4, 20, "1", 67, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*314*/ { 4, 20, "A", 40, 0, 13, 77 }, + /*315*/ { 4, 20, "A", 41, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*316*/ { 4, 20, "\200", 27, 0, 13, 77 }, + /*317*/ { 4, 20, "\200", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*318*/ { 4, 20, "\201", 34, 0, 13, 77 }, // 17 Shift JIS 0x8181 + /*319*/ { 4, 20, "\201", 36, ZINT_ERROR_TOO_LONG, -1, -1 }, // 18 Shift JIS 0x8181 + /*320*/ { 2, 21, "1", 171, 0, 13, 99 }, + /*321*/ { 2, 21, "1", 172, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*322*/ { 2, 21, "A", 104, 0, 13, 99 }, + /*323*/ { 2, 21, "A", 105, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*324*/ { 2, 21, "\200", 71, 0, 13, 99 }, + /*325*/ { 2, 21, "\200", 72, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*326*/ { 2, 21, "\201", 88, 0, 13, 99 }, // 44 Shift JIS 0x8181 + /*327*/ { 2, 21, "\201", 90, ZINT_ERROR_TOO_LONG, -1, -1 }, // 45 Shift JIS 0x8181 + /*328*/ { 4, 21, "1", 80, 0, 13, 99 }, + /*329*/ { 4, 21, "1", 81, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*330*/ { 4, 21, "A", 49, 0, 13, 99 }, + /*331*/ { 4, 21, "A", 50, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*332*/ { 4, 21, "\200", 33, 0, 13, 99 }, + /*333*/ { 4, 21, "\200", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*334*/ { 4, 21, "\201", 40, 0, 13, 99 }, // 20 Shift JIS 0x8181 + /*335*/ { 4, 21, "\201", 42, ZINT_ERROR_TOO_LONG, -1, -1 }, // 21 Shift JIS 0x8181 + /*336*/ { 2, 22, "1", 251, 0, 13, 139 }, + /*337*/ { 2, 22, "1", 252, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*338*/ { 2, 22, "A", 152, 0, 13, 139 }, + /*339*/ { 2, 22, "A", 153, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*340*/ { 2, 22, "\200", 104, 0, 13, 139 }, + /*341*/ { 2, 22, "\200", 105, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*342*/ { 2, 22, "\201", 128, 0, 13, 139 }, // 64 Shift JIS 0x8181 + /*343*/ { 2, 22, "\201", 130, ZINT_ERROR_TOO_LONG, -1, -1 }, // 65 Shift JIS 0x8181 + /*344*/ { 4, 22, "1", 126, 0, 13, 139 }, + /*345*/ { 4, 22, "1", 127, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*346*/ { 4, 22, "A", 76, 0, 13, 139 }, + /*347*/ { 4, 22, "A", 77, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*348*/ { 4, 22, "\200", 52, 0, 13, 139 }, + /*349*/ { 4, 22, "\200", 53, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*350*/ { 4, 22, "\201", 64, 0, 13, 139 }, // 32 Shift JIS 0x8181 + /*351*/ { 4, 22, "\201", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, // 33 Shift JIS 0x8181 + /*352*/ { 2, 23, "1", 76, 0, 15, 43 }, + /*353*/ { 2, 23, "1", 77, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*354*/ { 2, 23, "A", 46, 0, 15, 43 }, + /*355*/ { 2, 23, "A", 47, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*356*/ { 2, 23, "\200", 31, 0, 15, 43 }, + /*357*/ { 2, 23, "\200", 32, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*358*/ { 2, 23, "\201", 38, 0, 15, 43 }, // 19 Shift JIS 0x8181 + /*359*/ { 2, 23, "\201", 40, ZINT_ERROR_TOO_LONG, -1, -1 }, // 20 Shift JIS 0x8181 + /*360*/ { 4, 23, "1", 33, 0, 15, 43 }, + /*361*/ { 4, 23, "1", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*362*/ { 4, 23, "A", 20, 0, 15, 43 }, + /*363*/ { 4, 23, "A", 21, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*364*/ { 4, 23, "\200", 13, 0, 15, 43 }, + /*365*/ { 4, 23, "\200", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*366*/ { 4, 23, "\201", 16, 0, 15, 43 }, // 8 Shift JIS 0x8181 + /*367*/ { 4, 23, "\201", 18, ZINT_ERROR_TOO_LONG, -1, -1 }, // 9 Shift JIS 0x8181 + /*368*/ { 2, 24, "1", 112, 0, 15, 59 }, + /*369*/ { 2, 24, "1", 113, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*370*/ { 2, 24, "A", 68, 0, 15, 59 }, + /*371*/ { 2, 24, "A", 69, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*372*/ { 2, 24, "\200", 46, 0, 15, 59 }, + /*373*/ { 2, 24, "\200", 47, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*374*/ { 2, 24, "\201", 56, 0, 15, 59 }, // 28 Shift JIS 0x8181 + /*375*/ { 2, 24, "\201", 58, ZINT_ERROR_TOO_LONG, -1, -1 }, // 29 Shift JIS 0x8181 + /*376*/ { 4, 24, "1", 59, 0, 15, 59 }, + /*377*/ { 4, 24, "1", 60, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*378*/ { 4, 24, "A", 36, 0, 15, 59 }, + /*379*/ { 4, 24, "A", 37, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*380*/ { 4, 24, "\200", 24, 0, 15, 59 }, + /*381*/ { 4, 24, "\200", 25, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*382*/ { 4, 24, "\201", 30, 0, 15, 59 }, // 30 Shift JIS 0x8181 + /*383*/ { 4, 24, "\201", 32, ZINT_ERROR_TOO_LONG, -1, -1 }, // 31 Shift JIS 0x8181 + /*384*/ { 2, 25, "1", 157, 0, 15, 77 }, + /*385*/ { 2, 25, "1", 158, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*386*/ { 2, 25, "A", 95, 0, 15, 77 }, + /*387*/ { 2, 25, "A", 96, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*388*/ { 2, 25, "\200", 65, 0, 15, 77 }, + /*389*/ { 2, 25, "\200", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*390*/ { 2, 25, "\201", 80, 0, 15, 77 }, // 40 Shift JIS 0x8181 + /*391*/ { 2, 25, "\201", 82, ZINT_ERROR_TOO_LONG, -1, -1 }, // 41 Shift JIS 0x8181 + /*392*/ { 4, 25, "1", 71, 0, 15, 77 }, + /*393*/ { 4, 25, "1", 72, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*394*/ { 4, 25, "A", 43, 0, 15, 77 }, + /*395*/ { 4, 25, "A", 44, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*396*/ { 4, 25, "\200", 29, 0, 15, 77 }, + /*397*/ { 4, 25, "\200", 30, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*398*/ { 4, 25, "\201", 36, 0, 15, 77 }, // 18 Shift JIS 0x8181 + /*399*/ { 4, 25, "\201", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, // 19 Shift JIS 0x8181 + /*400*/ { 2, 26, "1", 207, 0, 15, 99 }, + /*401*/ { 2, 26, "1", 208, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*402*/ { 2, 26, "A", 126, 0, 15, 99 }, + /*403*/ { 2, 26, "A", 127, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*404*/ { 2, 26, "\200", 86, 0, 15, 99 }, + /*405*/ { 2, 26, "\200", 87, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*406*/ { 2, 26, "\201", 106, 0, 15, 99 }, // 53 Shift JIS 0x8181 + /*407*/ { 2, 26, "\201", 108, ZINT_ERROR_TOO_LONG, -1, -1 }, // 54 Shift JIS 0x8181 + /*408*/ { 4, 26, "1", 111, 0, 15, 99 }, + /*409*/ { 4, 26, "1", 112, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*410*/ { 4, 26, "A", 68, 0, 15, 99 }, + /*411*/ { 4, 26, "A", 69, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*412*/ { 4, 26, "\200", 46, 0, 15, 99 }, + /*413*/ { 4, 26, "\200", 47, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*414*/ { 4, 26, "\201", 56, 0, 15, 99 }, // 28 Shift JIS 0x8181 + /*415*/ { 4, 26, "\201", 58, ZINT_ERROR_TOO_LONG, -1, -1 }, // 29 Shift JIS 0x8181 + /*416*/ { 2, 27, "1", 301, 0, 15, 139 }, + /*417*/ { 2, 27, "1", 302, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*418*/ { 2, 27, "A", 182, 0, 15, 139 }, + /*419*/ { 2, 27, "A", 183, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*420*/ { 2, 27, "\200", 125, 0, 15, 139 }, + /*421*/ { 2, 27, "\200", 126, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*422*/ { 2, 27, "\201", 154, 0, 15, 139 }, // 77 Shift JIS 0x8181 + /*423*/ { 2, 27, "\201", 156, ZINT_ERROR_TOO_LONG, -1, -1 }, // 78 Shift JIS 0x8181 + /*424*/ { 4, 27, "1", 162, 0, 15, 139 }, + /*425*/ { 4, 27, "1", 163, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*426*/ { 4, 27, "A", 98, 0, 15, 139 }, + /*427*/ { 4, 27, "A", 99, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*428*/ { 4, 27, "\200", 67, 0, 15, 139 }, + /*429*/ { 4, 27, "\200", 68, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*430*/ { 4, 27, "\201", 82, 0, 15, 139 }, // 41 Shift JIS 0x8181 + /*431*/ { 4, 27, "\201", 84, ZINT_ERROR_TOO_LONG, -1, -1 }, // 42 Shift JIS 0x8181 + /*432*/ { 2, 28, "1", 90, 0, 17, 43 }, + /*433*/ { 2, 28, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*434*/ { 2, 28, "A", 55, 0, 17, 43 }, + /*435*/ { 2, 28, "A", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*436*/ { 2, 28, "\200", 37, 0, 17, 43 }, + /*437*/ { 2, 28, "\200", 38, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*438*/ { 2, 28, "\201", 46, 0, 17, 43 }, // 23 Shift JIS 0x8181 + /*439*/ { 2, 28, "\201", 48, ZINT_ERROR_TOO_LONG, -1, -1 }, // 24 Shift JIS 0x8181 + /*440*/ { 4, 28, "1", 47, 0, 17, 43 }, + /*441*/ { 4, 28, "1", 48, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*442*/ { 4, 28, "A", 28, 0, 17, 43 }, + /*443*/ { 4, 28, "A", 29, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*444*/ { 4, 28, "\200", 19, 0, 17, 43 }, + /*445*/ { 4, 28, "\200", 20, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*446*/ { 4, 28, "\201", 24, 0, 17, 43 }, // 12 Shift JIS 0x8181 + /*447*/ { 4, 28, "\201", 26, ZINT_ERROR_TOO_LONG, -1, -1 }, // 13 Shift JIS 0x8181 + /*448*/ { 2, 29, "1", 131, 0, 17, 59 }, + /*449*/ { 2, 29, "1", 132, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*450*/ { 2, 29, "A", 79, 0, 17, 59 }, + /*451*/ { 2, 29, "A", 80, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*452*/ { 2, 29, "\200", 54, 0, 17, 59 }, + /*453*/ { 2, 29, "\200", 55, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*454*/ { 2, 29, "\201", 66, 0, 17, 59 }, // 33 Shift JIS 0x8181 + /*455*/ { 2, 29, "\201", 68, ZINT_ERROR_TOO_LONG, -1, -1 }, // 34 Shift JIS 0x8181 + /*456*/ { 4, 29, "1", 63, 0, 17, 59 }, + /*457*/ { 4, 29, "1", 64, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*458*/ { 4, 29, "A", 38, 0, 17, 59 }, + /*459*/ { 4, 29, "A", 39, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*460*/ { 4, 29, "\200", 26, 0, 17, 59 }, + /*461*/ { 4, 29, "\200", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*462*/ { 4, 29, "\201", 32, 0, 17, 59 }, // 16 Shift JIS 0x8181 + /*463*/ { 4, 29, "\201", 34, ZINT_ERROR_TOO_LONG, -1, -1 }, // 17 Shift JIS 0x8181 + /*464*/ { 2, 30, "1", 183, 0, 17, 77 }, + /*465*/ { 2, 30, "1", 184, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*466*/ { 2, 30, "A", 111, 0, 17, 77 }, + /*467*/ { 2, 30, "A", 112, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*468*/ { 2, 30, "\200", 76, 0, 17, 77 }, + /*469*/ { 2, 30, "\200", 77, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*470*/ { 2, 30, "\201", 94, 0, 17, 77 }, // 47 Shift JIS 0x8181 + /*471*/ { 2, 30, "\201", 96, ZINT_ERROR_TOO_LONG, -1, -1 }, // 48 Shift JIS 0x8181 + /*472*/ { 4, 30, "1", 87, 0, 17, 77 }, + /*473*/ { 4, 30, "1", 88, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*474*/ { 4, 30, "A", 53, 0, 17, 77 }, + /*475*/ { 4, 30, "A", 54, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*476*/ { 4, 30, "\200", 36, 0, 17, 77 }, + /*477*/ { 4, 30, "\200", 37, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*478*/ { 4, 30, "\201", 44, 0, 17, 77 }, // 22 Shift JIS 0x8181 + /*479*/ { 4, 30, "\201", 46, ZINT_ERROR_TOO_LONG, -1, -1 }, // 23 Shift JIS 0x8181 + /*480*/ { 2, 31, "1", 236, 0, 17, 99 }, + /*481*/ { 2, 31, "1", 237, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*482*/ { 2, 31, "A", 143, 0, 17, 99 }, + /*483*/ { 2, 31, "A", 144, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*484*/ { 2, 31, "\200", 98, 0, 17, 99 }, + /*485*/ { 2, 31, "\200", 99, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*486*/ { 2, 31, "\201", 120, 0, 17, 99 }, // 60 Shift JIS 0x8181 + /*487*/ { 2, 31, "\201", 122, ZINT_ERROR_TOO_LONG, -1, -1 }, // 61 Shift JIS 0x8181 + /*488*/ { 4, 31, "1", 131, 0, 17, 99 }, + /*489*/ { 4, 31, "1", 132, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*490*/ { 4, 31, "A", 79, 0, 17, 99 }, + /*491*/ { 4, 31, "A", 80, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*492*/ { 4, 31, "\200", 54, 0, 17, 99 }, + /*493*/ { 4, 31, "\200", 55, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*494*/ { 4, 31, "\201", 66, 0, 17, 99 }, // 33 Shift JIS 0x8181 + /*495*/ { 4, 31, "\201", 68, ZINT_ERROR_TOO_LONG, -1, -1 }, // 34 Shift JIS 0x8181 + /*496*/ { 2, 32, "1", 361, 0, 17, 139 }, + /*497*/ { 2, 32, "1", 362, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*498*/ { 2, 32, "A", 219, 0, 17, 139 }, + /*499*/ { 2, 32, "A", 220, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*500*/ { 2, 32, "\200", 150, 0, 17, 139 }, + /*501*/ { 2, 32, "\200", 151, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*502*/ { 2, 32, "\201", 184, 0, 17, 139 }, // 92 Shift JIS 0x8181 + /*503*/ { 2, 32, "\201", 186, ZINT_ERROR_TOO_LONG, -1, -1 }, // 93 Shift JIS 0x8181 + /*504*/ { 4, 32, "1", 178, 0, 17, 139 }, + /*505*/ { 4, 32, "1", 179, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*506*/ { 4, 32, "A", 108, 0, 17, 139 }, + /*507*/ { 4, 32, "A", 109, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*508*/ { 4, 32, "\200", 74, 0, 17, 139 }, + /*509*/ { 4, 32, "\200", 75, ZINT_ERROR_TOO_LONG, -1, -1 }, + /*510*/ { 4, 32, "\201", 92, 0, 17, 139 }, // 46 Shift JIS 0x8181 + /*511*/ { 4, 32, "\201", 94, ZINT_ERROR_TOO_LONG, -1, -1 }, // 47 Shift JIS 0x8181 + }; + int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol; + + char data_buf[ZINT_MAX_DATA_LEN]; + + testStart("test_rmqr_large"); + + for (i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + + length = testUtilSetSymbol(symbol, BARCODE_RMQR, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, -1 /*output_options*/, data_buf, data[i].length, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + if (ret < ZINT_ERROR) { + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + } + + symbol->input_mode |= FAST_MODE; + ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + if (ret < ZINT_ERROR) { + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + static void test_rmqr_options(int index, int debug) { struct item { @@ -6333,9 +6921,9 @@ static void test_rmqr_encode(int index, int generate, int debug) { char *comment; char *expected; }; - // ISO/IEC JTC1/SC31N000 (Draft 2019-6-24) + // ISO/IEC 23941:2022 struct item data[] = { - /* 0*/ { UNICODE_MODE, 4, 11, "0123456", 0, 11, 27, 1, "Draft ISO 2019-6-24 Annex I Figure I.2, R11x27-H, same", + /* 0*/ { UNICODE_MODE, 4, 11, "0123456", 0, 11, 27, 1, "ISO 23941 Annex I Figure I.2, R11x27-H, same", "111111101010101010101010111" "100000100110100001110100101" "101110100001001111010011111" @@ -6348,7 +6936,7 @@ static void test_rmqr_encode(int index, int generate, int debug) { "101010100110010100111010001" "111010101010101010101011111" }, - /* 1*/ { UNICODE_MODE, 2, 17, "12345678901234567890123456", 0, 13, 27, 1, "Draft ISO 2019-6-24 6.2 Figure 1, R13x27-M, same", + /* 1*/ { UNICODE_MODE, 2, 17, "12345678901234567890123456", 0, 13, 27, 1, "ISO 23941 6.2 Figure 1, R13x27-M, same", "111111101010101010101010111" "100000100001001100010011001" "101110101100000011001110001" @@ -6363,7 +6951,7 @@ static void test_rmqr_encode(int index, int generate, int debug) { "100011010010010100000010001" "111010101010101010101011111" }, - /* 2*/ { UNICODE_MODE, 2, 2, "0123456789012345", 0, 7, 59, 1, "Draft ISO 2019-6-24 7.4.2 Numeric mode Example, R7x59-M, same codewords", + /* 2*/ { UNICODE_MODE, 2, 2, "0123456789012345", 0, 7, 59, 1, "ISO 23941 7.4.2 Numeric mode Example, R7x59-M, same codewords", "11111110101010101011101010101010101010111010101010101010111" "10000010101111011110100001100001100001101100100101100100101" "10111010100100001011110010110000011110111110111100011011111" @@ -6372,7 +6960,7 @@ static void test_rmqr_encode(int index, int generate, int debug) { "10000010101010110110100010111110010010101111101111110010001" "11111110101010101011101010101010101010111010101010101011111" }, - /* 3*/ { UNICODE_MODE, 2, 2, "AC-42", 0, 7, 59, 1, "Draft ISO 2019-6-24 7.4.3 Alphanumeric mode Example, R7x59-M, same codewords", + /* 3*/ { UNICODE_MODE, 2, 2, "AC-42", 0, 7, 59, 1, "ISO 23941 7.4.3 Alphanumeric mode Example, R7x59-M, same codewords", "11111110101010101011101010101010101010111010101010101010111" "10000010101111010010110011010101100000101011001111100100101" "10111010100100100011100100111100011101111100011011111011111" @@ -6595,19 +7183,19 @@ static void test_rmqr_encode(int index, int generate, int debug) { "10001001000010011011101110100010010001101111111101101000000110010000011010001" "11101010101010101010101011101010101010101010101010111010101010101010101011111" }, - /* 22*/ { UNICODE_MODE, 2, 20, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123", 0, 13, 77, 1, "R13x77-M with max 123 numerics (note 8 bit cci in draft 2019-6-24 when 7 suffices)", + /* 22*/ { UNICODE_MODE, 2, 20, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123", 0, 13, 77, 1, "R13x77-M with max 123 numerics (note was 8 bit cci in draft 2019-6-24 when 7 suffices - corrected in ISO/IEC 23941:2022)", "11111110101010101010101011101010101010101010101010111010101010101010101010111" - "10000010001111011110000010110000001101001111110110101010010010110011111011101" - "10111010001010000001000011100001010010100110011011111001000001111110100011001" - "10111010010011101110100110011001011011110110011101100011001010000010000010000" - "10111010010010111110100011010101011101110000000101110101111110010001000110011" - "10000010011110000011110100011001011101111111110110000100110010110011101011000" - "11111110111010011010000011010010110010010111011011111111010101111110110011111" - "00000000111011110111001110010000001000110001011101100110000110000010110101110" - "11111111010011101000010001110101101101110010000101011101110010000001101111111" - "01101010101001000000100000100000111110111111111011100100110100001011100110001" - "10110000001110100010011011100001011011010111011110111011010101110111111110101" - "10101101110110111100111010111111000100010001001101101110100100010100001010001" + "10000010001100001001010010111101110110110101101001101011011001000011001101101" + "10111010001011111111101011111110010001001001010111111010111100100101101011011" + "10111010010011001001111000101011110101101001011100100011110111011001010011110" + "10111010010010000101101011100011011110101010010010011000001101000010111011011" + "10000010011110010100000110001011110110000101101001100010101000000011101101010" + "11111110011111101010010101000001100001110001110111111111111000100101101011111" + "00000000010000010110000110000010010100101010010100100011101011011001010101110" + "11100011101100001111000101000000101100100001010010011110000001010010101111111" + "01010100110000011101011010011100101101000101101111001010100000110111000110001" + "10111001001100001100110011110011010111110001111111111011110000001001011110101" + "10100110000111111100100010100011100000011010110100101111001000011010001010001" "11101010101010101010101011101010101010101010101010111010101010101010101011111" }, /* 23*/ { UNICODE_MODE, 2, 23, "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 0, 15, 43, 1, "R15x43-M with max 31 binary", @@ -6984,6 +7572,7 @@ int main(int argc, char *argv[]) { { "test_upnqr_input", test_upnqr_input, 1, 1, 1 }, { "test_upnqr_encode", test_upnqr_encode, 1, 1, 1 }, + { "test_rmqr_large", test_rmqr_large, 1, 0, 1 }, { "test_rmqr_options", test_rmqr_options, 1, 0, 1 }, { "test_rmqr_input", test_rmqr_input, 1, 1, 1 }, { "test_rmqr_gs1", test_rmqr_gs1, 1, 1, 1 }, diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 437f0866..c207b539 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* * Adapted from qrencode/tests/common.c * Copyright (C) 2006-2017 Kentaro Fukuchi @@ -3513,8 +3514,7 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source, return 0; } -STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, - int *length); +INTERNAL int escape_char_process_test(struct zint_symbol *symbol, unsigned char *input_string, int *length); #include "../gs1.h" @@ -3559,7 +3559,7 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in if (is_escaped) { memcpy(escaped, expected, expected_len); - ret = escape_char_process(symbol, (unsigned char *) escaped, &expected_len); + ret = escape_char_process_test(symbol, (unsigned char *) escaped, &expected_len); if (ret != 0) { sprintf(msg, "escape_char_process %d != 0", ret); return 3; diff --git a/backend/tools/gen_eci_mb_h.php b/backend/tools/gen_eci_mb_h.php index 91068b1c..6f7ce247 100644 --- a/backend/tools/gen_eci_mb_h.php +++ b/backend/tools/gen_eci_mb_h.php @@ -4,6 +4,7 @@ libzint - the open source barcode library Copyright (C) 2022 Robin Stuart */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* * To create "backend/eci_mb.h" (from project root directory): * @@ -42,6 +43,7 @@ $copyright_text = <<<'EOD' OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ EOD; @@ -202,11 +204,13 @@ for ($u_i = 0, $cnt = count($sort); $u_i < $cnt && $sort[$u_i] < 0x4E00; $u_i++) $start_u_i = $u_i; $big5_uro_u = $big5_uro_mb_ind = array(); +$sort_search = array_flip($sort); for ($u = 0x4E00; $u <= 0x9FAF; $u += 16) { $used = 0; $next_u_i = $u_i; for ($j = 0; $j < 16; $j++) { - if (($i = array_search($u + $j, $sort)) !== false) { + if (isset($sort_search[$u + $j])) { + $i = $sort_search[$u + $j]; $used |= 1 << $j; $next_u_i = $i + 1; $end_u_i = $i; @@ -286,11 +290,13 @@ for ($u_i = 0, $cnt = count($sort); $u_i < $cnt && $sort[$u_i] < 0x4E00; $u_i++) $start_u_i = $u_i; $ksx1001_uro_u = $ksx1001_uro_mb_ind = array(); +$sort_search = array_flip($sort); for ($u = 0x4E00; $u <= 0x9F9F; $u += 16) { $used = 0; $next_u_i = $u_i; for ($j = 0; $j < 16; $j++) { - if (($i = array_search($u + $j, $sort)) !== false) { + if (isset($sort_search[$u + $j])) { + $i = $sort_search[$u + $j]; $used |= 1 << $j; $next_u_i = $i + 1; $end_u_i = $i; @@ -366,11 +372,13 @@ for ($u_i = 0, $cnt = count($sort); $u_i < $cnt && $sort[$u_i] < 0x4E00; $u_i++) $start_u_i = $u_i; $sjis_uro_u = $sjis_uro_mb_ind = array(); +$sort_search = array_flip($sort); for ($u = 0x4E00; $u <= 0x9FAF; $u += 16) { $used = 0; $next_u_i = $u_i; for ($j = 0; $j < 16; $j++) { - if (($i = array_search($u + $j, $sort)) !== false) { + if (isset($sort_search[$u + $j])) { + $i = $sort_search[$u + $j]; $used |= 1 << $j; $next_u_i = $i + 1; $end_u_i = $i; @@ -444,11 +452,13 @@ for ($u_i = 0, $cnt = count($sort); $u_i < $cnt && $sort[$u_i] < 0x4E00; $u_i++) $start_u_i = $u_i; $gb2312_uro_u = $gb2312_uro_mb_ind = array(); +$sort_search = array_flip($sort); for ($u = 0x4E00; $u <= 0x9CEF; $u += 16) { $used = 0; $next_u_i = $u_i; for ($j = 0; $j < 16; $j++) { - if (($i = array_search($u + $j, $sort)) !== false) { + if (isset($sort_search[$u + $j])) { + $i = $sort_search[$u + $j]; $used |= 1 << $j; $next_u_i = $i + 1; $end_u_i = $i; @@ -524,11 +534,13 @@ for ($u_i = 0, $cnt = count($sort); $u_i < $cnt && $sort[$u_i] < 0x4E00; $u_i++) $start_u_i = $u_i; $gbk_uro_u = $gbk_uro_mb_ind = array(); +$sort_search = array_flip($sort); for ($u = 0x4E00; $u <= 0x9FAF; $u += 16) { $used = 0; $next_u_i = $u_i; for ($j = 0; $j < 16; $j++) { - if (($i = array_search($u + $j, $sort)) !== false) { + if (isset($sort_search[$u + $j])) { + $i = $sort_search[$u + $j]; $used |= 1 << $j; $next_u_i = $i + 1; $end_u_i = $i; diff --git a/backend/tools/gen_eci_sb_h.php b/backend/tools/gen_eci_sb_h.php index b5d14e7a..27039504 100644 --- a/backend/tools/gen_eci_sb_h.php +++ b/backend/tools/gen_eci_sb_h.php @@ -56,6 +56,7 @@ $head = <<<'EOD' OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef Z_ECI_SB_H #define Z_ECI_SB_H diff --git a/backend/zint.h b/backend/zint.h index c70ec296..eb39d747 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -28,6 +28,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* * For version, see "zintconfig.h" * For documentation, see "../docs/manual.txt" @@ -91,7 +92,7 @@ extern "C" { struct zint_symbol { int symbology; /* Symbol to use (see BARCODE_XXX below) */ float height; /* Barcode height in X-dimensions (ignored for fixed-width barcodes) */ - float scale; /* Scale factor when printing barcode. Default 1 */ + float scale; /* Scale factor when printing barcode, i.e. adjusts X-dimension. Default 1 */ int whitespace_width; /* Width in X-dimensions of whitespace to left & right of barcode */ int whitespace_height; /* Height in X-dimensions of whitespace above & below the barcode */ int border_width; /* Size of border in X-dimensions */ @@ -110,7 +111,7 @@ extern "C" { int input_mode; /* Encoding of input data (see DATA_MODE etc below). Default DATA_MODE */ int eci; /* Extended Channel Interpretation. Default 0 (none) */ float dot_size; /* Size of dots used in BARCODE_DOTTY_MODE. Default 0.8 */ - float guard_descent; /* Height in X-dimensions that UPC/EAN guard bars descend. Default 5 */ + float guard_descent; /* Height in X-dimensions that EAN/UPC guard bars descend. Default 5 */ struct zint_structapp structapp; /* Structured Append info. Default structapp.count 0 (none) */ int warn_level; /* Affects error/warning value returned by Zint API (see WARN_XXX below) */ int debug; /* Debugging flags */ @@ -274,7 +275,7 @@ extern "C" { #define GS1_GS_SEPARATOR 0x0200 /* Use GS instead of FNC1 as GS1 separator (Data Matrix) */ #define OUT_BUFFER_INTERMEDIATE 0x0400 /* Return ASCII values in bitmap buffer (OUT_BUFFER only) */ #define BARCODE_QUIET_ZONES 0x0800 /* Add compliant quiet zones (additional to any specified whitespace) */ - /* Note: CODE16K, CODE49, CODABLOCKF, ITF14, UPC/EAN have default quiet zones + /* Note: CODE16K, CODE49, CODABLOCKF, ITF14, EAN/UPC have default quiet zones */ #define BARCODE_NO_QUIET_ZONES 0x1000 /* Disable quiet zones, notably those with defaults as listed above */ #define COMPLIANT_HEIGHT 0x2000 /* Warn if height not compliant and use standard height (if any) as default */ @@ -324,7 +325,7 @@ extern "C" { /* Capability flags (ZBarcode_Cap() `cap_flag`) */ #define ZINT_CAP_HRT 0x0001 /* Prints Human Readable Text? */ #define ZINT_CAP_STACKABLE 0x0002 /* Is stackable? */ -#define ZINT_CAP_EXTENDABLE 0x0004 /* Is extendable with add-on data? (Is UPC/EAN?) */ +#define ZINT_CAP_EXTENDABLE 0x0004 /* Is extendable with add-on data? (Is EAN/UPC?) */ #define ZINT_CAP_COMPOSITE 0x0008 /* Can have composite data? */ #define ZINT_CAP_ECI 0x0010 /* Supports Extended Channel Interpretations? */ #define ZINT_CAP_GS1 0x0020 /* Supports GS1 data? */ diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp index 8a363d9f..e235880c 100644 --- a/backend_qt/qzint.cpp +++ b/backend_qt/qzint.cpp @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #ifdef _MSC_VER #if _MSC_VER >= 1900 /* MSVC 2015 */ @@ -60,6 +61,43 @@ namespace Zint { return ret; } + /* Helper to calculate max right and bottom of elements for fudging render() */ + static void getMaxRectsRightBottom(struct zint_vector *vector, int &maxRight, int &maxBottom) { + struct zint_vector_rect *rect; + struct zint_vector_hexagon *hex; + struct zint_vector_circle *circle; + + maxRight = maxBottom = -1; + + for (rect = vector->rectangles; rect; rect = rect->next) { + if (rect->x + rect->width > maxRight) { + maxRight = rect->x + rect->width; + } + if (rect->y + rect->height > maxBottom) { + maxBottom = rect->y + rect->height; + } + } + + for (hex = vector->hexagons; hex; hex = hex->next) { + if (hex->x + hex->diameter > maxRight) { + maxRight = hex->x + hex->diameter; + } + if (hex->y + hex->diameter > maxBottom) { + maxBottom = hex->y + hex->diameter; + } + } + + for (circle = vector->circles; circle; circle = circle->next) { + if (circle->x + circle->diameter + circle->width > maxRight) { + maxRight = circle->x + circle->diameter + circle->width; + } + if (circle->y + circle->diameter + circle->width > maxBottom) { + maxBottom = circle->y + circle->diameter + circle->width; + } + } + // TODO: Strings? + } + /* Segment constructors */ QZintSeg::QZintSeg() : m_eci(0) {} QZintSeg::QZintSeg(const QString& text, const int ECIIndex) : m_text(text), m_eci(ECIIndexToECI(ECIIndex)) {} @@ -773,6 +811,10 @@ namespace Zint { // Plot rectangles rect = m_zintSymbol->vector->rectangles; if (rect) { + int maxRight = -1, maxBottom = -1; // Used for fudging below + if (borderWidth() && (borderType() & (BARCODE_BIND | BARCODE_BOX))) { + getMaxRectsRightBottom(m_zintSymbol->vector, maxRight, maxBottom); + } QBrush brush(Qt::SolidPattern); while (rect) { if (rect->colour == -1) { @@ -780,7 +822,10 @@ namespace Zint { } else { brush.setColor(colourToQtColor(rect->colour)); } - painter.fillRect(QRectF(rect->x, rect->y, rect->width, rect->height), brush); + // Allow for rounding errors on translation/scaling TODO: proper calc + float fudgeW = rect->x + rect->width == maxRight ? 0.1f : 0.0f; + float fudgeH = rect->y + rect->height == maxBottom ? 0.1f : 0.0f; + painter.fillRect(QRectF(rect->x, rect->y, rect->width + fudgeW, rect->height + fudgeH), brush); rect = rect->next; } } diff --git a/backend_qt/qzint.h b/backend_qt/qzint.h index 335a3369..d57ab6a7 100644 --- a/backend_qt/qzint.h +++ b/backend_qt/qzint.h @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef QZINT_H #define QZINT_H diff --git a/backend_qt/tests/test_qzint.cpp b/backend_qt/tests/test_qzint.cpp index 09d37c26..9fca17da 100644 --- a/backend_qt/tests/test_qzint.cpp +++ b/backend_qt/tests/test_qzint.cpp @@ -12,6 +12,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #include #include "../qzint.h" /* Don't use in case it's been changed */ @@ -372,7 +373,7 @@ private slots: QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 0 << "" << 21 << 21; if (!m_skipIfFontUsed) { - QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << ZINT_ERROR_INVALID_DATA << "Error 773: Input segment 0 length zero" << 0 << 0; + QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << ZINT_ERROR_INVALID_DATA << "Error 778: No input data (segment 0 empty)" << 0 << 0; } } diff --git a/backend_tcl/zint.c b/backend_tcl/zint.c index ab9d3432..6e2e5cf4 100644 --- a/backend_tcl/zint.c +++ b/backend_tcl/zint.c @@ -468,7 +468,7 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n" " photo: a tcl photo image handle ('p' after 'image create photo p')\n" " Available options:\n" " -barcode choice: symbology, use 'zint symbology' to get a list\n" - " -addongap integer: (7..12, default: 9) set add-on gap in multiple of module size (UPC/EAN-CC)\n" + " -addongap integer: (7..12, default: 9) set add-on gap in multiple of module size (EAN/UPC-CC)\n" " -bg color: set background color as 6 or 8 hex rrggbbaa\n" /* cli option --binary internally handled */ " -bind bool: bars above/below the code, size set by -border\n" @@ -495,7 +495,7 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n" " -gs1nocheck bool: for gs1, do not check validity of data (allows non-standard symbols)\n" " -gs1parens bool: for gs1, AIs enclosed in parentheses instead of square brackets\n" " -gssep bool: for gs1, use gs as separator instead fnc1 (Datamatrix only)\n" - " -guarddescent double: Height of guard bar descent in modules (UPC/EAN only)\n" + " -guarddescent double: Height of guard bar descent in modules (EAN/UPC only)\n" " -height double: Symbol height in modules\n" " -heightperrow bool: treat height as per-row\n" /* cli option --input not supported */ diff --git a/docs/Makefile b/docs/Makefile index cf9d39b4..d5492c79 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -16,7 +16,6 @@ INCLUDES_TXT = inc_header_txt.tex INC_TXT = --include-in-header $(INCLUDES_TXT) SOURCE_MAN_PAGE = zint.1.pmd OUT_MAN_PAGE = zint.1 -INC_HEADER_TEX_MAN = inc_header_man.tex IMAGES = \ images/zint.png \ images/zint-qt.png \ @@ -31,6 +30,9 @@ IMAGES = \ images/gui_sequence.png \ images/gui_export.png \ images/gui_cli_equivalent.png \ + images/gui_black_eye.png \ + images/gui_white_eye.png \ + images/gui_swap.png \ images/pdf417_heightperrow.svg \ images/code128_box.svg \ images/qrcode_box.svg \ diff --git a/docs/images/gui_appearance.png b/docs/images/gui_appearance.png index 04b522dc..28d23095 100644 Binary files a/docs/images/gui_appearance.png and b/docs/images/gui_appearance.png differ diff --git a/docs/images/gui_aztec.png b/docs/images/gui_aztec.png index 6efab76a..3220a558 100644 Binary files a/docs/images/gui_aztec.png and b/docs/images/gui_aztec.png differ diff --git a/docs/images/gui_black_eye.png b/docs/images/gui_black_eye.png new file mode 100644 index 00000000..246ac5da Binary files /dev/null and b/docs/images/gui_black_eye.png differ diff --git a/docs/images/gui_composite.png b/docs/images/gui_composite.png index 7b246856..f76088b0 100644 Binary files a/docs/images/gui_composite.png and b/docs/images/gui_composite.png differ diff --git a/docs/images/gui_data_dialog.png b/docs/images/gui_data_dialog.png index 975982fb..0cff7f1d 100644 Binary files a/docs/images/gui_data_dialog.png and b/docs/images/gui_data_dialog.png differ diff --git a/docs/images/gui_export.png b/docs/images/gui_export.png index c4f981e2..32c6d2c6 100644 Binary files a/docs/images/gui_export.png and b/docs/images/gui_export.png differ diff --git a/docs/images/gui_main.png b/docs/images/gui_main.png index e2fd51b0..5fb88fd2 100644 Binary files a/docs/images/gui_main.png and b/docs/images/gui_main.png differ diff --git a/docs/images/gui_menus.png b/docs/images/gui_menus.png index 27c1aab0..b0c2d81d 100644 Binary files a/docs/images/gui_menus.png and b/docs/images/gui_menus.png differ diff --git a/docs/images/gui_segs.png b/docs/images/gui_segs.png index 23d3e4e4..178e7a7f 100644 Binary files a/docs/images/gui_segs.png and b/docs/images/gui_segs.png differ diff --git a/docs/images/gui_sequence.png b/docs/images/gui_sequence.png index 1c474be9..7e997814 100644 Binary files a/docs/images/gui_sequence.png and b/docs/images/gui_sequence.png differ diff --git a/docs/images/gui_swap.png b/docs/images/gui_swap.png new file mode 100644 index 00000000..31464b42 Binary files /dev/null and b/docs/images/gui_swap.png differ diff --git a/docs/images/gui_white_eye.png b/docs/images/gui_white_eye.png new file mode 100644 index 00000000..8c8ea30c Binary files /dev/null and b/docs/images/gui_white_eye.png differ diff --git a/docs/manual.pmd b/docs/manual.pmd index a07cd975..0cd4dd29 100644 --- a/docs/manual.pmd +++ b/docs/manual.pmd @@ -1,6 +1,6 @@ % Zint Barcode Generator and Zint Barcode Studio User Manual % Version 2.11.0.9 -% May 2022 +% June 2022 # 1. Introduction @@ -28,35 +28,35 @@ used in the symbol and the orientation of the image. Some of the words and phrases used in this document are specific to barcoding, and so a brief explanation is given to help understanding: -symbol: +symbol : A symbol is an image which encodes data according to one of the standards. This encompasses barcodes (linear symbols) as well as any of the other methods of representing data used in this program. -symbology: +symbology : A method of encoding data to create a certain type of symbol. -linear: +linear : A linear or one-dimensional symbol is one which consists of bars and spaces, and is what most people associate with the term 'barcode'. Examples include Code 128. -stacked: +stacked : A stacked symbol consists of multiple linear symbols placed one above another and which together hold the message, usually alongside some error correction data. Examples include PDF417. -matrix: +matrix : A matrix symbol is one based on a (usually square) grid of elements called modules. Examples include Data Matrix, but MaxiCode and DotCode are also considered matrix symbologies. -composite: +composite : A composite symbology is one which is made up of elements which are both linear and stacked. Those currently supported are made up of a linear @@ -64,7 +64,7 @@ composite: PDF417 symbology. These symbols also have a separator which separates the linear and the stacked components. -X-dimension: +X-dimension : The X-dimension of a symbol is the size (usually the width) of the smallest element. For a linear symbology this is the width of the smallest bar. For @@ -74,13 +74,13 @@ X-dimension: most matrix symbologies have a fixed width-to-height ratio where the height is determined by the width. -GS1 data: +GS1 data : This is a structured way of representing information which consists of 'chunks' of data, each of which starts with an Application Identifier (AI). The AI identifies what type of information is being encoded. -Reader Initialisation (Programming): +Reader Initialisation (Programming) : Some symbologies allow a special character to be included which can be detected by the scanning equipment as signifying that the data is used to @@ -89,7 +89,7 @@ Reader Initialisation (Programming): should only be used if you are familiar with the programming codes relevant to your scanner. -ECI: +ECI : The Extended Channel Interpretations (ECI) mechanism allows for multi-language data to be encoded in symbols which would usually support @@ -99,14 +99,14 @@ ECI: Two other concepts that are important are raster and vector. -raster: +raster : A low level bitmap representation of an image. BMP, GIF, PCX, PNG and TIF are raster file formats. -vector: +vector -: A high level command- or data-based representation of an image. EMF, EPS +: A high level command- or data-based representation of an image. EMF, EPS and SVG are vector file formats. They require renderers to turn them into bitmaps. @@ -248,9 +248,9 @@ contain `"mail"` or `"post"` (or both). The `"BMP"` and `"SVG"` buttons at the bottom will copy the image to the clipboard in BMP format and SVG format respectively. Further copy-to-clipboard formats are available by clicking the `"Menu"` button, along with -`"CLI Equivalent"`, `"Save As"`, `"Help"`, `"About"` and `"Quit"` options. Most -of the options are also available in a context menu by right-clicking the -preview. +`"CLI Equivalent"`, `"Save As"`, `"Factory Reset"`, `"Help"`, `"About"` and +`"Quit"` options. Most of the options are also available in a context menu by +right-clicking the preview. ![Zint Barcode Studio main menu (left) and context menu (right)](images/gui_menus.png) @@ -293,16 +293,18 @@ The Appearance tab can be used to adjust the dimensions and other properties of the symbol. The `"Height"` value affects the height of symbologies which do not have a fixed width-to-height ratio, i.e. those other than matrix symbologies. Boundary bars (`"Border Type"`) can be added and adjusted (`"Border Width"`) and -the size of the saved image (`"Printing Scale"`) can be determined. +the size of the saved image (`"Printing Scale"`) can be specified. ## 3.6 Colour Dialog ![The colour picker tool](images/gui_colour.png) A colour dialog is used to adjust the colour of the foreground and background of -the generated image. In the Appearance tab click on the `"Foreground"` or -`"Background"` button respectively. The colours can be reset to black-on-white -using the `"Reset"` button. +the generated image. In the Appearance tab click on the foreground eye +![eye](images/gui_black_eye.png) or background eye +![eye](images/gui_white_eye.png) button respectively. The colours can be reset +to black-on-white using the `"Reset"` button, and exchanged one for the other +using the swap ![swap](images/gui_swap.png) button next to it. ## 3.7 Data Dialog @@ -427,41 +429,46 @@ Non-printing characters can be entered on the command line using backslash (`\`) as an escape character in combination with the `--esc` switch. Permissible sequences are shown in the table below. -------------------------------------------------------------------------- -Escape ASCII Name Interpretation -Sequence Equivalent --------- ---------- ----- ------------------------------------------- -`\0` 0x00 `NUL` Null character +--------------------------------------------------------------------------- +Escape ASCII Name Interpretation +Sequence Equivalent +---------- ---------- ----- ------------------------------------------- +`\0` 0x00 `NUL` Null character -`\E` 0x04 `EOT` End of Transmission +`\E` 0x04 `EOT` End of Transmission -`\a` 0x07 `BEL` Bell +`\a` 0x07 `BEL` Bell -`\b` 0x08 `BS` Backspace +`\b` 0x08 `BS` Backspace -`\t` 0x09 `HT` Horizontal Tab +`\t` 0x09 `HT` Horizontal Tab -`\n` 0x0A `LF` Line Feed +`\n` 0x0A `LF` Line Feed -`\v` 0x0B `VT` Vertical Tab +`\v` 0x0B `VT` Vertical Tab -`\f` 0x0C `FF` Form Feed +`\f` 0x0C `FF` Form Feed -`\r` 0x0D `CR` Carriage Return +`\r` 0x0D `CR` Carriage Return -`\e` 0x1B `ESC` Escape +`\e` 0x1B `ESC` Escape -`\G` 0x1D `GS` Group Separator +`\G` 0x1D `GS` Group Separator -`\R` 0x1E `RS` Record Separator +`\R` 0x1E `RS` Record Separator -`\\` 0x5C `\` Backslash +`\\` 0x5C `\` Backslash -`\xNN` 0xNN Any 8-bit character where NN is hexadecimal +`\dNNN` NNN Any 8-bit character where NNN is decimal (0-255) -`\uNNNN` Any 16-bit Unicode BMP[^1] character where - NNNN is hexadecimal -------------------------------------------------------------------------- +`\xNN` 0xNN Any 8-bit character where NN is hexadecimal + +`\uNNNN` Any 16-bit Unicode BMP[^1] character where + NNNN is hexadecimal + +`\UNNNNNN` Any 20-bit Unicode character where NNNNNN + is hexadecimal (maximum 0x10FFFF) +--------------------------------------------------------------------------- Table: {#tbl:escape_sequences tag=": Escape Sequences"} @@ -846,7 +853,8 @@ particular horizontal whitespace values. Special considerations apply to ITF-14 The default colours of a symbol are a black symbol on a white background. Zint allows you to change this. The `-r` or `--reverse` switch allows the default colours to be inverted so that a white symbol is shown on a black background -(known as reflectance reversal). For example the command +(known as "reflectance reversal" or "reversed reflectance"). For example the +command ```bash zint -r -d "This Text" @@ -1082,8 +1090,8 @@ by the default character set then you should check that the resulting barcode can be understood by your target barcode reader. The ECI value may be specified with the `--eci` switch, followed by the value in -the column `"ECI Code"`. The input data should be UTF-8 formatted. Zint -automatically translates the data into the target encoding. +the column `"ECI Code"` in the table below. The input data should be UTF-8 +formatted. Zint automatically translates the data into the target encoding. ECI Code Character Encoding Scheme (ISO/IEC 8859 schemes include ASCII) -------- -------------------------------------------------------------- @@ -1702,7 +1710,7 @@ Variable Name Type Meaning Default Value `option_3` integer Symbol specific options. 0 -`show_hrt` integer Set to 0 to hide text 1 +`show_hrt` integer Set to 0 to hide text. 1 `input_mode` integer Set encoding of input `DATA_MODE` data (see [5.10 Setting the @@ -1715,7 +1723,7 @@ Variable Name Type Meaning Default Value dotty mode. `guard_descent` float Height of guard bar 5.0 - descent (UPC/EAN only) + descent (EAN/UPC only). `structapp` Structured Mark a symbol as part of a count 0 Append sequence of symbols. (disabled) @@ -1764,7 +1772,7 @@ Variable Name Type Meaning Default Value `alphamap` pointer to Pointer to array (output only) unsigned representing alpha channel character (or `NULL` if no alpha - array channel needed) + array channel needed). `bitmap_byte_length` integer Size of BMP bitmap data. (output only) @@ -2174,7 +2182,7 @@ Value Meaning `ZINT_CAP_STACKABLE` Is the symbology stackable? `ZINT_CAP_EXTENDABLE` Is the symbology extendable with add-on data? (i.e. - is it UPC/EAN?) + is it EAN/UPC?) `ZINT_CAP_COMPOSITE` Does the symbology support composite data? (see [6.3 GS1 Composite Symbols (ISO 24723)] below) @@ -2262,10 +2270,10 @@ before using these standards. ![`zint -b C25STANDARD -d "9212320967"`](images/c25standard.svg) -Also known as Code 2 of 5 Matrix this is a self-checking code used in industrial -applications and photo development. Standard Code 2 of 5 will encode numeric -input (digits 0-9) up to a maximum of 80 digits. No check digit is added by -default. To add a check digit, set `--vers=1` (API `option_2 = 1`). To add a +Also known as Code 2 of 5 Matrix, this is a self-checking code used in +industrial applications and photo development. Standard Code 2 of 5 will encode +numeric input (digits 0-9) up to a maximum of 80 digits. No check digit is added +by default. To add a check digit, set `--vers=1` (API `option_2 = 1`). To add a check digit but not show it in the Human Readable Text, set `--vers=2` (API `option_2 = 2`). @@ -2354,11 +2362,10 @@ the data 12345 use the command: zint -b UPCA -d 72527270270+12345 ``` -or encode a data string with the + character included: +or using the API encode a data string with the + character included: ```c my_symbol->symbology = BARCODE_UPCA; - error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0); ``` @@ -2393,7 +2400,6 @@ or ```c my_symbol->symbology = BARCODE_UPCE; - error = ZBarcode_Encode_and_Print(my_symbol, "1123456", 0, 0); ``` @@ -2581,7 +2587,7 @@ Zint. ![`zint -b HIBC_39 --compliantheight -d "14352312"`](images/hibc_39.svg) -This option adds a leading `'+'` character and a trailing modulo-49 check digit +This variant adds a leading `'+'` character and a trailing modulo-49 check digit to a standard Code 39 symbol as required by the Health Industry Barcode standards. @@ -2702,12 +2708,12 @@ standards. "%000393206219912345678101040"`](images/dpd.svg) Another variation of Code 128 as used by DPD (Deutsher Paket Dienst). Requires -a 28 character alphanumeric input. Zint formats Human Readable Text as +a 28 character alphanumeric input. Zint formats the Human Readable Text as specified by DPD and adds a modulo-36 check character. ### 6.1.11 GS1 DataBar (ISO 24724) -Previously known as RSS (Reduced Spaced Symbology) these symbols are due to +Previously known as RSS (Reduced Spaced Symbology), these symbols are due to replace GS1-128 symbols in accordance with the GS1 General Specifications. If a GS1 DataBar symbol is to be printed with a 2D component as specified in ISO/IEC 24723 set `--mode=2` (API `option_1 = 2`). See [6.3 GS1 Composite Symbols (ISO @@ -2720,10 +2726,11 @@ GS1 DataBar symbol is to be printed with a 2D component as specified in ISO/IEC Previously known as RSS-14 this standard encodes a 13-digit item code. A check digit and Application Identifier of (01) are added by Zint. (A 14-digit code that appends the check digit may be given, in which case the check digit will be -verified.) To produce a truncated symbol set the symbol height to a value -between 13 and 32. Truncated symbols may not be scannable by omnidirectional -scanners. Normal DataBar Omnidirectional symbols should have a height of 33 or -greater. +verified.) + +GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To +produce a GS1 DataBar Truncated symbol set the symbol height to a value between +13 and 32. Truncated symbols may not be scannable by omnidirectional scanners. ![`zint -b DBAR_OMN -d "0950110153001" --height=13`](images/dbar_truncated.svg) @@ -2732,11 +2739,11 @@ greater. ![`zint -b DBAR_LTD --compliantheight -d "0950110153001"`](images/dbar_ltd.svg) Previously known as RSS Limited this standard encodes a 13-digit item code and -can be used in the same way as DataBar Omnidirectional above. DataBar Limited, -however, is limited to data starting with digits 0 and 1 (i.e. numbers in the -range 0 to 1999999999999). As with DataBar Omnidirectional a check digit and -Application Identifier of (01) are added by Zint, and a 14-digit code may be -given in which case the check digit will be verified. +can be used in the same way as GS1 DataBar Omnidirectional above. GS1 DataBar +Limited, however, is limited to data starting with digits 0 and 1 (i.e. numbers +in the range 0 to 1999999999999). As with GS1 DataBar Omnidirectional a check +digit and Application Identifier of (01) are added by Zint, and a 14-digit code +may be given in which case the check digit will be verified. #### 6.1.11.3 GS1 DataBar Expanded @@ -2745,17 +2752,16 @@ given in which case the check digit will be verified. Previously known as RSS Expanded this is a variable length symbology capable of encoding data from a number of AIs in a single symbol. AIs should be encased in -[square brackets] in the input data. This will be converted to parentheses -(round brackets) before it is included in the Human Readable Text attached to +[square brackets] in the input data, which will be converted to parentheses +(round brackets) before being included in the Human Readable Text attached to the symbol. This method allows the inclusion of parentheses in the data to be -encoded. If the data does not include parentheses, the AIs may alternatively -be encased in parentheses using the `--gs1parens` switch. See [6.1.10.3 -GS1-128]. +encoded. If the data does not include parentheses, the AIs may alternatively be +encased in parentheses using the `--gs1parens` switch. See [6.1.10.3 GS1-128]. GTIN data AI (01) should also include the check digit data as this is not calculated by Zint when this symbology is encoded. Fixed length data should be entered at the appropriate length for correct encoding. The following is an -example of a valid DataBar Expanded input: +example of a valid GS1 DataBar Expanded input: ```bash zint -b 31 -d "[01]98898765432106[3202]012345[15]991231" @@ -2839,7 +2845,7 @@ zint --bind --notext --separator=2 -d "This" -d "That" "That"`](images/code128_stacked_sep2.svg) A more sophisticated method is to use some type of line indexing which indicates -to the barcode reader which order the symbols should be read in. This is +to the barcode reader which order the stacked symbols should be read in. This is demonstrated by the symbologies below. ### 6.2.2 Codablock-F @@ -2912,7 +2918,7 @@ for PDF417 above. A variation of the PDF417 standard, MicroPDF417 is intended for applications where symbol size needs to be kept to a minimum. 34 predefined symbol sizes are -available with 1 - 4 columns and 4 - 44 rows. The maximum size a MicroPDF417 +available with 1 - 4 columns and 4 - 44 rows. The maximum amount a MicroPDF417 symbol can hold is 250 alphanumeric characters or 366 digits. The amount of error correction used is dependent on symbol size. The number of columns used can be determined using the `--cols` switch (API `option_2`) as with PDF417. @@ -2930,7 +2936,7 @@ Structured Append the same as PDF417, for which see details. A stacked variation of the GS1 DataBar Truncated symbol requiring the same input (see [6.1.11.1 GS1 DataBar Omnidirectional and GS1 DataBar Truncated]), this -symbol is the same as the following DataBar Stacked Omnidirectional symbol +symbol is the same as the following GS1 DataBar Stacked Omnidirectional symbol except that its height is reduced, making it suitable for small items when omnidirectional scanning is not required. It can be generated with a two-dimensional component to make a composite symbol. @@ -2958,7 +2964,7 @@ Expanded]). In addition the width of the symbol can be altered using the to 11) relates to the number of character pairs on each row of the symbol. Alternatively the `--rows` switch (API `option_3`) can be used to specify the maximum number of rows (values 2 to 11), and the number of columns will be -adjusted accordingly. This symbol can be generated with a two-dimensional +adjusted accordingly. This symbol can be generated with a two-dimensional component to make a composite symbol. For symbols with a 2D component the number of columns must be at least 2. @@ -2982,10 +2988,10 @@ Composite symbols employ a mixture of components to give more comprehensive information about a product. The permissible contents of a composite symbol is determined by the terms of the GS1 General Specifications. Composite symbols consist of a linear component which can be an EAN, UPC, GS1-128 or GS1 DataBar -symbol, a 2D component which is based on PDF417 or MicroPDF417, and a separator -pattern. The type of linear component to be used is determined using the `-b` or -`--barcode` switch (API `symbology`) as with other encoding methods. Valid -values are shown below. +symbol, a two-dimensional (2D) component which is based on PDF417 or +MicroPDF417, and a separator pattern. The type of linear component to be used is +determined using the `-b` or `--barcode` switch (API `symbology`) as with other +encoding methods. Valid values are shown below. -------------------------------------------------------------------------------- Numeric Name Barcode Name @@ -3107,7 +3113,8 @@ used for encoding zip-codes on mail items. POSTNET uses numerical input data and includes a modulo-10 check digit. While Zint will encode POSTNET symbols of up to 38 digits in length, standard lengths as used by USPS were `PostNet6` (5-digit ZIP input), `PostNet10` (5-digit ZIP + 4-digit user data) and -`PostNet12` (5-digit ZIP + 6-digit user data). +`PostNet12` (5-digit ZIP + 6-digit user data), and a warning will be issued if +the input length is not one of these. ### 6.4.3 PLANET @@ -3118,7 +3125,8 @@ Numeric Encoding Technique) barcode was used for encoding routing data on mail items. PLANET uses numerical input data and includes a modulo-10 check digit. While Zint will encode PLANET symbols of up to 38 digits in length, standard lengths used by USPS were `Planet12` (11-digit input) and `Planet14` (13-digit -input). +input), and as with POSTNET a warning will be issued if the length is not one of +these. \clearpage @@ -3203,9 +3211,24 @@ generated by Zint. Developed in 2014 as a replacement for RM4SCC this 4-state symbol includes Reed Solomon error correction. Input is a pre-formatted alphanumeric string of 22 (for Barcode C) or 26 (for Barcode L) characters, producing a symbol with -66 or 78 bars respectively. Some of the permitted inputs include a number of -trailing space characters - these will be appended by Zint if not included in -the input data. +66 or 78 bars respectively. The rules for the input data are complex, as +summarized in the following table. + +Format Version ID Class Supply Chain ID Item ID Destination+DPS +------- ---------- ------- --------------- -------- ----------------- +1 digit 1 digit 1 alphanum. 2 digits (C) or 8 digits 9 alphanumerics +(0-4) (0-3) (0-9A-E) 6 digits (L) (1 of 6 patterns) + +Table: {#tbl:mailmark_input_fields tag=": Royal Mail Mailmark Input Fields"} + +The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) +patterns are `'FNFNLLNLS'`, `'FFNNLLNLS'`, `'FFNNNLLNL'`, `'FFNFNLLNL'`, +`'FNNLLNLSS'` and `'FNNNLLNLS'`, where `'F'` stands for full alphabetic (A-Z), +`'L'` for limited alphabetic (A-Z less `'CIKMOV'`), `'N'` for numeric (0-9), and +`'S'` for space. + +Four of the permitted patterns include a number of trailing space characters - +these will be appended by Zint if not included in the input data. ### 6.5.5 USPS Intelligent Mail @@ -3220,15 +3243,10 @@ consists of a 20-digit tracking code, followed by a dash (`-`), followed by a delivery point zip-code which can be 0, 5, 9 or 11 digits in length. For example all of the following inputs are valid data entries: -``` -"01234567094987654321" - -"01234567094987654321-01234" - -"01234567094987654321-012345678" - -"01234567094987654321-01234567891" -``` +- `"01234567094987654321"` +- `"01234567094987654321-01234"` +- `"01234567094987654321-012345678"` +- `"01234567094987654321-01234567891"` ### 6.5.6 Japanese Postal Code @@ -3238,6 +3256,32 @@ all of the following inputs are valid data entries: Used for address data on mail items for Japan Post. Accepted values are 0-9, A-Z and dash (`-`). A modulo 19 check digit is added by Zint. +### 6.5.7 DAFT Code + +![`zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 +--vers=256`](images/daft_rm4scc.svg) + +This is a method for creating 4-state codes where the data encoding is provided +by an external program. Input data should consist of the letters `'D'`, `'A'`, +`'F'` and `'T'` where these refer to descender, ascender, full (ascender and +descender) and tracker (neither ascender nor descender) respectively. All other +characters are invalid. The ratio of the tracker size to full height can be +given in thousandths (permille) using the `--vers` option (API `option_2`). The +default value is 250 (25%). + +For example the following + +```bash +zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256 +``` + +produces the same barcode (see [6.5.3 Royal Mail 4-State Customer Code +(RM4SCC)]) as + +```bash +zint -b RM4SCC --compliantheight -d "W1J0TR01" +``` + \clearpage ## 6.6 Matrix Symbols @@ -3252,10 +3296,10 @@ in partnership with the US DoD and NASA. The symbol can encode a large amount of data in a small area. Data Matrix encodes characters in the Latin-1 set by default but also supports encoding in other character sets using the ECI mechanism. It can also encode GS1 data. The size of the generated symbol can -also be adjusted using the `--vers` option (API `option_2`) as shown in the -table below. A separate symbology ID (`BARCODE_HIBC_DM`) can be used to encode -Health Industry Barcode (HIBC) data. Note that only ECC200 encoding is -supported, the older standards have now been removed from Zint. +be adjusted using the `--vers` option (API `option_2`) as shown in the table +below. A separate symbology ID (`BARCODE_HIBC_DM`) can be used to encode Health +Industry Barcode (HIBC) data. Note that only ECC200 encoding is supported, the +older standards have now been removed from Zint. Input Symbol Size Input Symbol Size Input Symbol Size ----- ----------- -- ----- ----------- -- ----- ----------- @@ -3440,14 +3484,12 @@ option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8 ![`zint -b RMQR -d "0123456"`](images/rmqr.svg) -A rectangular version of QR Code, it is still under development, so it is -recommended it should not yet be used for a production environment. Like QR -Code, rMQR supports encoding of GS1 data, and either Latin-1 characters or Shift -JIS characters, and other encodings using the ECI mechanism. As with other -symbologies data should be entered as UTF-8 with conversion being handled by -Zint. The amount of ECC codewords can be adjusted using the `--secure` option -(API `option_1`), however only ECC levels M and H are valid for this type of -symbol. +A rectangular version of QR Code, rMQR supports encoding of GS1 data, and either +Latin-1 characters or Shift JIS characters, and other encodings using the ECI +mechanism. As with other symbologies data should be entered as UTF-8 with +conversion being handled by Zint. The amount of ECC codewords can be adjusted +using the `--secure` option (API `option_1`), however only ECC levels M and H +are valid for this type of symbol. Input ECC Level Error Correction Capacity Recovery Capacity ----- --------- ------------------------- ----------------- @@ -3934,33 +3976,6 @@ not a true barcode symbol and requires precise knowledge of the position of the mark on the page. The Flattermarken system can encode numeric data up to a maximum of 90 digits and does not include a check digit. -### 6.7.3 DAFT Code - -![`zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 ---vers=256`](images/daft_rm4scc.svg) - - -This is a method for creating 4-state codes where the data encoding is provided -by an external program. Input data should consist of the letters `'D'`, `'A'`, -`'F'` and `'T'` where these refer to descender, ascender, full (ascender and -descender) and tracker (neither ascender nor descender) respectively. All other -characters are invalid. The ratio of the tracker size to full height can be -given in thousandths (permille) using the `--vers` option (API `option_2`). The -default value is 250 (25%). - -For example the following - -```bash -zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256 -``` - -produces the same barcode (see [6.5.3 Royal Mail 4-State Customer Code -(RM4SCC)]) as - -```bash -zint -b RM4SCC --compliantheight -d "W1J0TR01" -``` - # 7. Legal and Version Information @@ -3968,15 +3983,17 @@ zint -b RM4SCC --compliantheight -d "W1J0TR01" Zint, libzint and Zint Barcode Studio are Copyright © 2022 Robin Stuart. All historical versions are distributed under the GNU General Public License -version 3 or later. Version 2.5 (and later) is released under a dual license: -the encoding library is released under the BSD license whereas the GUI, Zint -Barcode Studio, is released under the GNU General Public License version 3 or -later. +version 3 or later. Versions 2.5 and later are released under a dual license: +the encoding library is released under the BSD (3 clause) license whereas the +GUI, Zint Barcode Studio, and the CLI are released under the GNU General Public +License version 3 or later. Telepen is a trademark of SB Electronic Systems Ltd. QR Code is a registered trademark of Denso Wave Incorporated. +Mailmark is a registered trademark of Royal Mail Group Ltd. + Microsoft, Windows and the Windows logo are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. @@ -4036,61 +4053,71 @@ Below is a list of some of the sources used in rough chronological order: Zint was developed to provide compliance with the following British and international standards: +### 7.5.1 Symbology Standards + +- ISO/IEC 24778:2008 Information technology - Automatic identification and data + capture techniques - Aztec Code bar code symbology specification +- ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code - BS EN 798:1996 Bar coding - Symbology specifications - 'Codabar' -- BS EN 12323:2005 AIDC technologies - Symbology specifications - Code 16K -- ISO/IEC 15420:2009 Information technology - Automatic identification and data - capture techniques - EAN/UPC bar code symbology specification +- AIM Europe ISS-X-24 - Uniform Symbology Specification Codablock-F (1995) - ISO/IEC 15417:2007 Information technology - Automatic identification and data capture techniques - Code 128 bar code symbology specification -- ISO/IEC 15438:2015 Information technology - Automatic identification and data - capture techniques - PDF417 bar code symbology specification -- ISO/IEC 16022:2006 Information technology - Automatic identification and data - capture techniques - Data Matrix ECC200 bar code symbology specification -- ISO/IEC 16023:2000 Information technology - International symbology - specification - MaxiCode +- BS EN 12323:2005 AIDC technologies - Symbology specifications - Code 16K - ISO/IEC 16388:2007 Information technology - Automatic identification and data capture techniques - Code 39 bar code symbology specification -- ISO/IEC 18004:2015 Information technology - Automatic identification and data - capture techniques - QR Code bar code symbology specification -- ISO/IEC 20830:2021 Information technology - Automatic identification and data - capture techniques - Han Xin Code bar code symbology specification +- ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 +- ANSI/AIM BC5-1995 - Uniform Symbology Specification Code 93 +- AIM Uniform Symbology Specification Code One (1994) +- ISO/IEC 16022:2006 Information technology - Automatic identification and data + capture techniques - Data Matrix ECC200 bar code symbology specification +- ISO/IEC 21471:2020 Information technology - Automatic identification and data + capture techniques - Extended rectangular data matrix (DMRE) bar code + symbology specification +- AIM TSC1705001 (v 4.0 Draft 0.15) - Information technology - Automatic + identification and data capture techniques - Bar code symbology + specification - DotCode (Revised 28th May 2019) +- ISO/IEC 15420:2009 Information technology - Automatic identification and data + capture techniques - EAN/UPC bar code symbology specification +- AIMD014 (v 1.63) - Information technology, Automatic identification and data + capture techniques - Bar code symbology specification - Grid Matrix + (Released 9th Dec 2008) - ISO/IEC 24723:2010 Information technology - Automatic identification and data capture techniques - GS1 Composite bar code symbology specification - ISO/IEC 24724:2011 Information technology - Automatic identification and data capture techniques - GS1 DataBar bar code symbology specification -- ISO/IEC 24728:2006 Information technology - Automatic identification and data - capture techniques - MicroPDF417 bar code symbology specification -- ISO/IEC 24778:2008 Information technology - Automatic identification and data - capture techniques - Aztec Code bar code symbology specification -- ISO/IEC JTC1/SC31N000 (Draft 2019-6-24) Information technology - Automatic - identification and data capture techniques - Rectangular Micro QR Code - (rMQR) bar code symbology specification +- ISO/IEC 20830:2021 Information technology - Automatic identification and data + capture techniques - Han Xin Code bar code symbology specification - ISO/IEC 16390:2007 Information technology - Automatic identification and data capture techniques - Interleaved 2 of 5 bar code symbology specification -- ISO/IEC 21471:2020 Information technology - Automatic identification and data - capture techniques - Extended rectangular data matrix (DMRE) bar code - symbology specification -- AIM Uniform Symbology Specification Code One (1994) -- ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code -- ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 -- ANSI/AIM BC5-1995 - Uniform Symbology Specification Code 93 -- AIM Europe ISS-X-24 - Uniform Symbology Specification Codablock-F (1995) -- AIM TSC1705001 (v 4.0 Draft 0.15) - Information technology - Automatic - identification and data capture techniques - Bar code symbology - specification - DotCode (Revised 28th May 2019) -- AIMD014 (v 1.63) - Information technology, Automatic identification and data - capture techniques - Bar code symbology specification - Grid Matrix - (Released 9th Dec 2008) +- ISO/IEC 16023:2000 Information technology - International symbology + specification - MaxiCode +- ISO/IEC 24728:2006 Information technology - Automatic identification and data + capture techniques - MicroPDF417 bar code symbology specification +- ISO/IEC 15438:2015 Information technology - Automatic identification and data + capture techniques - PDF417 bar code symbology specification +- ISO/IEC 18004:2015 Information technology - Automatic identification and data + capture techniques - QR Code bar code symbology specification +- ISO/IEC 23941:2022 Information technology - Automatic identification and data + capture techniques - Rectangular Micro QR Code (rMQR) bar code symbology + specification - AIMD/TSC15032-43 (v 0.99c) - International Technical Specification - Ultracode Symbology (Draft) (Released 4th Nov 2015) -- ANSI/HIBC 2.6-2016 - The Health Industry Bar Code (HIBC) Supplier Labeling - Standard -- GS1 General Specifications Release 22.0 (Jan 2022) + +A number of other specification documents have also been referenced, such as +MIL-STD-1189 Rev. B (1989) (LOGMARS), USPS DMM 300 2006 (2011) (POSTNET, PLANET, +FIM) and USPS-B-3200 (2015) (IMAIL). Those not named include postal and delivery +company references in particular. + +### 7.5.2 General Standards + - AIM ITS/04-001 International Technical Standard - Extended Channel Interpretations Part 1: Identification Schemes and Protocol (Released 24th May 2004) - AIM ITS/04-023 International Technical Standard - Extended Channel Interpretations Part 3: Register (Version 2, February 2022) +- GS1 General Specifications Release 22.0 (Jan 2022) +- ANSI/HIBC 2.6-2016 - The Health Industry Bar Code (HIBC) Supplier Labeling + Standard # Annex A. Character Encoding @@ -4155,4 +4182,4 @@ F `¯` `¿` `Ï` `ß` `ï` `ÿ` Table: {#tbl:iso_iec_8869_1 tag=": ISO/IEC 8859-1"} -# Annex B. zint(1) Man Page +# Annex B. Man Page ZINT(1) diff --git a/docs/manual.txt b/docs/manual.txt index 347112d5..676c496a 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -1,6 +1,6 @@ Zint Barcode Generator and Zint Barcode Studio User Manual Version 2.11.0.9 -May 2022 +June 2022 ******************************************************************************* * For reference the following is a text-only version of the Zint manual, * @@ -148,6 +148,7 @@ May 2022 - 6.5.4 Royal Mail 4-State Mailmark - 6.5.5 USPS Intelligent Mail - 6.5.6 Japanese Postal Code + - 6.5.7 DAFT Code - 6.6 Matrix Symbols - 6.6.1 Data Matrix (ISO 16022) - 6.6.2 QR Code (ISO 18004) @@ -165,17 +166,18 @@ May 2022 - 6.7 Other Barcode-Like Markings - 6.7.1 Facing Identification Mark (FIM) - 6.7.2 Flattermarken - - 6.7.3 DAFT Code - 7. Legal and Version Information - 7.1 License - 7.2 Patent Issues - 7.3 Version Information - 7.4 Sources of Information - 7.5 Standards Compliance + - 7.5.1 Symbology Standards + - 7.5.2 General Standards - Annex A. Character Encoding - A.1 ASCII Standard - A.2 Latin Alphabet No. 1 (ISO/IEC 8859-1) -- Annex B. zint(1) Man Page +- Annex B. Man Page ZINT(1) - NAME - SYNOPSIS - DESCRIPTION @@ -185,7 +187,8 @@ May 2022 - BUGS - SEE ALSO - CONFORMING TO - - AUTHORS + - COPYRIGHT + - AUTHOR 1. Introduction @@ -213,35 +216,35 @@ used in the symbol and the orientation of the image. Some of the words and phrases used in this document are specific to barcoding, and so a brief explanation is given to help understanding: -symbol: +symbol A symbol is an image which encodes data according to one of the standards. This encompasses barcodes (linear symbols) as well as any of the other methods of representing data used in this program. -symbology: +symbology A method of encoding data to create a certain type of symbol. -linear: +linear A linear or one-dimensional symbol is one which consists of bars and spaces, and is what most people associate with the term ‘barcode’. Examples include Code 128. -stacked: +stacked A stacked symbol consists of multiple linear symbols placed one above another and which together hold the message, usually alongside some error correction data. Examples include PDF417. -matrix: +matrix A matrix symbol is one based on a (usually square) grid of elements called modules. Examples include Data Matrix, but MaxiCode and DotCode are also considered matrix symbologies. -composite: +composite A composite symbology is one which is made up of elements which are both linear and stacked. Those currently supported are made up of a linear @@ -249,7 +252,7 @@ composite: PDF417 symbology. These symbols also have a separator which separates the linear and the stacked components. -X-dimension: +X-dimension The X-dimension of a symbol is the size (usually the width) of the smallest element. For a linear symbology this is the width of the smallest bar. For @@ -259,13 +262,13 @@ X-dimension: most matrix symbologies have a fixed width-to-height ratio where the height is determined by the width. -GS1 data: +GS1 data This is a structured way of representing information which consists of ‘chunks’ of data, each of which starts with an Application Identifier (AI). The AI identifies what type of information is being encoded. -Reader Initialisation (Programming): +Reader Initialisation (Programming) Some symbologies allow a special character to be included which can be detected by the scanning equipment as signifying that the data is used to @@ -274,7 +277,7 @@ Reader Initialisation (Programming): should only be used if you are familiar with the programming codes relevant to your scanner. -ECI: +ECI The Extended Channel Interpretations (ECI) mechanism allows for multi-language data to be encoded in symbols which would usually support @@ -284,12 +287,12 @@ ECI: Two other concepts that are important are raster and vector. -raster: +raster A low level bitmap representation of an image. BMP, GIF, PCX, PNG and TIF are raster file formats. -vector: +vector A high level command- or data-based representation of an image. EMF, EPS and SVG are vector file formats. They require renderers to turn them into @@ -410,8 +413,8 @@ contain "mail" or "post" (or both). The "BMP" and "SVG" buttons at the bottom will copy the image to the clipboard in BMP format and SVG format respectively. Further copy-to-clipboard formats are available by clicking the "Menu" button, along with "CLI Equivalent", "Save As", -"Help", "About" and "Quit" options. Most of the options are also available in a -context menu by right-clicking the preview. +"Factory Reset", "Help", "About" and "Quit" options. Most of the options are +also available in a context menu by right-clicking the preview. [Zint Barcode Studio main menu (left) and context menu (right)] @@ -453,16 +456,17 @@ The Appearance tab can be used to adjust the dimensions and other properties of the symbol. The "Height" value affects the height of symbologies which do not have a fixed width-to-height ratio, i.e. those other than matrix symbologies. Boundary bars ("Border Type") can be added and adjusted ("Border Width") and the -size of the saved image ("Printing Scale") can be determined. +size of the saved image ("Printing Scale") can be specified. 3.6 Colour Dialog [The colour picker tool] A colour dialog is used to adjust the colour of the foreground and background of -the generated image. In the Appearance tab click on the "Foreground" or -"Background" button respectively. The colours can be reset to black-on-white -using the "Reset" button. +the generated image. In the Appearance tab click on the foreground eye [eye] or +background eye [eye] button respectively. The colours can be reset to +black-on-white using the "Reset" button, and exchanged one for the other using +the swap [swap] button next to it. 3.7 Data Dialog @@ -576,41 +580,47 @@ Non-printing characters can be entered on the command line using backslash (\) as an escape character in combination with the --esc switch. Permissible sequences are shown in the table below. - --------------------------------------------------------------------------- - Escape ASCII Name Interpretation - Sequence Equivalent - ---------- ------------ ------- ------------------------------------------- - \0 0x00 NUL Null character + ---------------------------------------------------------------------------- + Escape ASCII Name Interpretation + Sequence Equivalent + ----------- ------------ ------- ------------------------------------------- + \0 0x00 NUL Null character - \E 0x04 EOT End of Transmission + \E 0x04 EOT End of Transmission - \a 0x07 BEL Bell + \a 0x07 BEL Bell - \b 0x08 BS Backspace + \b 0x08 BS Backspace - \t 0x09 HT Horizontal Tab + \t 0x09 HT Horizontal Tab - \n 0x0A LF Line Feed + \n 0x0A LF Line Feed - \v 0x0B VT Vertical Tab + \v 0x0B VT Vertical Tab - \f 0x0C FF Form Feed + \f 0x0C FF Form Feed - \r 0x0D CR Carriage Return + \r 0x0D CR Carriage Return - \e 0x1B ESC Escape + \e 0x1B ESC Escape - \G 0x1D GS Group Separator + \G 0x1D GS Group Separator - \R 0x1E RS Record Separator + \R 0x1E RS Record Separator - \\ 0x5C \ Backslash + \\ 0x5C \ Backslash - \xNN 0xNN Any 8-bit character where NN is hexadecimal + \dNNN NNN Any 8-bit character where NNN is decimal + (0-255) - \uNNNN Any 16-bit Unicode BMP[1] character where - NNNN is hexadecimal - --------------------------------------------------------------------------- + \xNN 0xNN Any 8-bit character where NN is hexadecimal + + \uNNNN Any 16-bit Unicode BMP[1] character where + NNNN is hexadecimal + + \UNNNNNN Any 20-bit Unicode character where NNNNNN + is hexadecimal (maximum 0x10FFFF) + ---------------------------------------------------------------------------- : Table : Escape Sequences: @@ -957,7 +967,7 @@ ITF-14 - see 6.1.2.6 ITF-14 for that symbology. The default colours of a symbol are a black symbol on a white background. Zint allows you to change this. The -r or --reverse switch allows the default colours to be inverted so that a white symbol is shown on a black background (known as -reflectance reversal). For example the command +“reflectance reversal” or “reversed reflectance”). For example the command zint -r -d "This Text" @@ -1177,8 +1187,8 @@ by the default character set then you should check that the resulting barcode can be understood by your target barcode reader. The ECI value may be specified with the --eci switch, followed by the value in -the column "ECI Code". The input data should be UTF-8 formatted. Zint -automatically translates the data into the target encoding. +the column "ECI Code" in the table below. The input data should be UTF-8 +formatted. Zint automatically translates the data into the target encoding. ECI Code Character Encoding Scheme (ISO/IEC 8859 schemes include ASCII) ---------- ---------------------------------------------------------------- @@ -1745,7 +1755,7 @@ encoding stages. The zint_symbol structure consists of the following variables: option_3 integer Symbol specific options. 0 - show_hrt integer Set to 0 to hide text 1 + show_hrt integer Set to 0 to hide text. 1 input_mode integer Set encoding of input data DATA_MODE (see 5.10 Setting the Input @@ -1758,7 +1768,7 @@ encoding stages. The zint_symbol structure consists of the following variables: dotty mode. guard_descent float Height of guard bar descent 5.0 - (UPC/EAN only) + (EAN/UPC only). structapp Structured Mark a symbol as part of a count 0 Append sequence of symbols. (disabled) @@ -1807,7 +1817,7 @@ encoding stages. The zint_symbol structure consists of the following variables: alphamap pointer to Pointer to array (output only) unsigned representing alpha channel character (or NULL if no alpha channel - array needed) + array needed). bitmap_byte_length integer Size of BMP bitmap data. (output only) @@ -2170,7 +2180,7 @@ see which are set. ZINT_CAP_STACKABLE Is the symbology stackable? ZINT_CAP_EXTENDABLE Is the symbology extendable with add-on data? (i.e. - is it UPC/EAN?) + is it EAN/UPC?) ZINT_CAP_COMPOSITE Does the symbology support composite data? (see 6.3 GS1 Composite Symbols (ISO 24723) below) @@ -2253,11 +2263,11 @@ before using these standards. [zint -b C25STANDARD -d "9212320967"] -Also known as Code 2 of 5 Matrix this is a self-checking code used in industrial -applications and photo development. Standard Code 2 of 5 will encode numeric -input (digits 0-9) up to a maximum of 80 digits. No check digit is added by -default. To add a check digit, set --vers=1 (API option_2 = 1). To add a check -digit but not show it in the Human Readable Text, set --vers=2 (API +Also known as Code 2 of 5 Matrix, this is a self-checking code used in +industrial applications and photo development. Standard Code 2 of 5 will encode +numeric input (digits 0-9) up to a maximum of 80 digits. No check digit is added +by default. To add a check digit, set --vers=1 (API option_2 = 1). To add a +check digit but not show it in the Human Readable Text, set --vers=2 (API option_2 = 2). 6.1.2.2 IATA Code 2 of 5 @@ -2342,10 +2352,9 @@ the data 12345 use the command: zint -b UPCA -d 72527270270+12345 -or encode a data string with the + character included: +or using the API encode a data string with the + character included: my_symbol->symbology = BARCODE_UPCA; - error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0); [zint -b UPCA --compliantheight -d "72527270270+12345"] @@ -2375,7 +2384,6 @@ by entering a 7-digit article number stating with the digit 1. For example: or my_symbol->symbology = BARCODE_UPCE; - error = ZBarcode_Encode_and_Print(my_symbol, "1123456", 0, 0); If your input data already includes the check digit symbology BARCODE_UPCE_CHK @@ -2555,8 +2563,9 @@ Zint. [zint -b HIBC_39 --compliantheight -d "14352312"] -This option adds a leading '+' character and a trailing modulo-49 check digit to -a standard Code 39 symbol as required by the Health Industry Barcode standards. +This variant adds a leading '+' character and a trailing modulo-49 check digit +to a standard Code 39 symbol as required by the Health Industry Barcode +standards. 6.1.7.8 Vehicle Identification Number (VIN) @@ -2666,12 +2675,12 @@ a standard Code 128 symbol as required by the Health Industry Barcode standards. [zint -b DPD --compliantheight -d "%000393206219912345678101040"] Another variation of Code 128 as used by DPD (Deutsher Paket Dienst). Requires a -28 character alphanumeric input. Zint formats Human Readable Text as specified -by DPD and adds a modulo-36 check character. +28 character alphanumeric input. Zint formats the Human Readable Text as +specified by DPD and adds a modulo-36 check character. 6.1.11 GS1 DataBar (ISO 24724) -Previously known as RSS (Reduced Spaced Symbology) these symbols are due to +Previously known as RSS (Reduced Spaced Symbology), these symbols are due to replace GS1-128 symbols in accordance with the GS1 General Specifications. If a GS1 DataBar symbol is to be printed with a 2D component as specified in ISO/IEC 24723 set --mode=2 (API option_1 = 2). See 6.3 GS1 Composite Symbols (ISO 24723) @@ -2684,10 +2693,11 @@ to find out how to generate DataBar symbols with 2D components. Previously known as RSS-14 this standard encodes a 13-digit item code. A check digit and Application Identifier of (01) are added by Zint. (A 14-digit code that appends the check digit may be given, in which case the check digit will be -verified.) To produce a truncated symbol set the symbol height to a value -between 13 and 32. Truncated symbols may not be scannable by omnidirectional -scanners. Normal DataBar Omnidirectional symbols should have a height of 33 or -greater. +verified.) + +GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To +produce a GS1 DataBar Truncated symbol set the symbol height to a value between +13 and 32. Truncated symbols may not be scannable by omnidirectional scanners. [zint -b DBAR_OMN -d "0950110153001" --height=13] @@ -2696,11 +2706,11 @@ greater. [zint -b DBAR_LTD --compliantheight -d "0950110153001"] Previously known as RSS Limited this standard encodes a 13-digit item code and -can be used in the same way as DataBar Omnidirectional above. DataBar Limited, -however, is limited to data starting with digits 0 and 1 (i.e. numbers in the -range 0 to 1999999999999). As with DataBar Omnidirectional a check digit and -Application Identifier of (01) are added by Zint, and a 14-digit code may be -given in which case the check digit will be verified. +can be used in the same way as GS1 DataBar Omnidirectional above. GS1 DataBar +Limited, however, is limited to data starting with digits 0 and 1 (i.e. numbers +in the range 0 to 1999999999999). As with GS1 DataBar Omnidirectional a check +digit and Application Identifier of (01) are added by Zint, and a 14-digit code +may be given in which case the check digit will be verified. 6.1.11.3 GS1 DataBar Expanded @@ -2708,8 +2718,8 @@ given in which case the check digit will be verified. Previously known as RSS Expanded this is a variable length symbology capable of encoding data from a number of AIs in a single symbol. AIs should be encased in -[square brackets] in the input data. This will be converted to parentheses -(round brackets) before it is included in the Human Readable Text attached to +[square brackets] in the input data, which will be converted to parentheses +(round brackets) before being included in the Human Readable Text attached to the symbol. This method allows the inclusion of parentheses in the data to be encoded. If the data does not include parentheses, the AIs may alternatively be encased in parentheses using the --gs1parens switch. See 6.1.10.3 GS1-128. @@ -2717,7 +2727,7 @@ encased in parentheses using the --gs1parens switch. See 6.1.10.3 GS1-128. GTIN data AI (01) should also include the check digit data as this is not calculated by Zint when this symbology is encoded. Fixed length data should be entered at the appropriate length for correct encoding. The following is an -example of a valid DataBar Expanded input: +example of a valid GS1 DataBar Expanded input: zint -b 31 -d "[01]98898765432106[3202]012345[15]991231" @@ -2790,7 +2800,7 @@ set by --separator (API option_3): [zint --notext --bind --separator=2 -d "This" -d "That"] A more sophisticated method is to use some type of line indexing which indicates -to the barcode reader which order the symbols should be read in. This is +to the barcode reader which order the stacked symbols should be read in. This is demonstrated by the symbologies below. 6.2.2 Codablock-F @@ -2862,7 +2872,7 @@ above. A variation of the PDF417 standard, MicroPDF417 is intended for applications where symbol size needs to be kept to a minimum. 34 predefined symbol sizes are -available with 1 - 4 columns and 4 - 44 rows. The maximum size a MicroPDF417 +available with 1 - 4 columns and 4 - 44 rows. The maximum amount a MicroPDF417 symbol can hold is 250 alphanumeric characters or 366 digits. The amount of error correction used is dependent on symbol size. The number of columns used can be determined using the --cols switch (API option_2) as with PDF417. @@ -2880,7 +2890,7 @@ Structured Append the same as PDF417, for which see details. A stacked variation of the GS1 DataBar Truncated symbol requiring the same input (see 6.1.11.1 GS1 DataBar Omnidirectional and GS1 DataBar Truncated), this -symbol is the same as the following DataBar Stacked Omnidirectional symbol +symbol is the same as the following GS1 DataBar Stacked Omnidirectional symbol except that its height is reduced, making it suitable for small items when omnidirectional scanning is not required. It can be generated with a two-dimensional component to make a composite symbol. @@ -2926,10 +2936,10 @@ Composite symbols employ a mixture of components to give more comprehensive information about a product. The permissible contents of a composite symbol is determined by the terms of the GS1 General Specifications. Composite symbols consist of a linear component which can be an EAN, UPC, GS1-128 or GS1 DataBar -symbol, a 2D component which is based on PDF417 or MicroPDF417, and a separator -pattern. The type of linear component to be used is determined using the -b or ---barcode switch (API symbology) as with other encoding methods. Valid values -are shown below. +symbol, a two-dimensional (2D) component which is based on PDF417 or +MicroPDF417, and a separator pattern. The type of linear component to be used is +determined using the -b or --barcode switch (API symbology) as with other +encoding methods. Valid values are shown below. -------------------------------------------------------------------------------- Numeric Name Barcode Name @@ -3041,7 +3051,8 @@ used for encoding zip-codes on mail items. POSTNET uses numerical input data and includes a modulo-10 check digit. While Zint will encode POSTNET symbols of up to 38 digits in length, standard lengths as used by USPS were PostNet6 (5-digit ZIP input), PostNet10 (5-digit ZIP + 4-digit user data) and PostNet12 (5-digit -ZIP + 6-digit user data). +ZIP + 6-digit user data), and a warning will be issued if the input length is +not one of these. 6.4.3 PLANET @@ -3052,7 +3063,8 @@ Numeric Encoding Technique) barcode was used for encoding routing data on mail items. PLANET uses numerical input data and includes a modulo-10 check digit. While Zint will encode PLANET symbols of up to 38 digits in length, standard lengths used by USPS were Planet12 (11-digit input) and Planet14 (13-digit -input). +input), and as with POSTNET a warning will be issued if the length is not one of +these. 6.5 4-State Postal Codes @@ -3134,9 +3146,23 @@ Zint. Developed in 2014 as a replacement for RM4SCC this 4-state symbol includes Reed Solomon error correction. Input is a pre-formatted alphanumeric string of 22 (for Barcode C) or 26 (for Barcode L) characters, producing a symbol with 66 or -78 bars respectively. Some of the permitted inputs include a number of trailing -space characters - these will be appended by Zint if not included in the input -data. +78 bars respectively. The rules for the input data are complex, as summarized in +the following table. + + Format Version ID Class Supply Chain ID Item ID Destination+DPS + --------- ------------ ------------- ----------------- ---------- ------------------- + 1 digit 1 digit 1 alphanum. 2 digits (C) or 8 digits 9 alphanumerics + (0-4) (0-3) (0-9A-E) 6 digits (L) (1 of 6 patterns) + + : Table : Royal Mail Mailmark Input Fields: + +The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) +patterns are 'FNFNLLNLS', 'FFNNLLNLS', 'FFNNNLLNL', 'FFNFNLLNL', 'FNNLLNLSS' and +'FNNNLLNLS', where 'F' stands for full alphabetic (A-Z), 'L' for limited +alphabetic (A-Z less 'CIKMOV'), 'N' for numeric (0-9), and 'S' for space. + +Four of the permitted patterns include a number of trailing space characters - +these will be appended by Zint if not included in the input data. 6.5.5 USPS Intelligent Mail @@ -3150,13 +3176,10 @@ consists of a 20-digit tracking code, followed by a dash (-), followed by a delivery point zip-code which can be 0, 5, 9 or 11 digits in length. For example all of the following inputs are valid data entries: - "01234567094987654321" - - "01234567094987654321-01234" - - "01234567094987654321-012345678" - - "01234567094987654321-01234567891" +- "01234567094987654321" +- "01234567094987654321-01234" +- "01234567094987654321-012345678" +- "01234567094987654321-01234567891" 6.5.6 Japanese Postal Code @@ -3165,6 +3188,27 @@ all of the following inputs are valid data entries: Used for address data on mail items for Japan Post. Accepted values are 0-9, A-Z and dash (-). A modulo 19 check digit is added by Zint. +6.5.7 DAFT Code + +[zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 --vers=256] + +This is a method for creating 4-state codes where the data encoding is provided +by an external program. Input data should consist of the letters 'D', 'A', 'F' +and 'T' where these refer to descender, ascender, full (ascender and descender) +and tracker (neither ascender nor descender) respectively. All other characters +are invalid. The ratio of the tracker size to full height can be given in +thousandths (permille) using the --vers option (API option_2). The default value +is 250 (25%). + +For example the following + + zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256 + +produces the same barcode (see 6.5.3 Royal Mail 4-State Customer Code (RM4SCC)) +as + + zint -b RM4SCC --compliantheight -d "W1J0TR01" + 6.6 Matrix Symbols 6.6.1 Data Matrix (ISO 16022) @@ -3175,11 +3219,11 @@ Also known as Semacode this symbology was developed in 1989 by Acuity CiMatrix in partnership with the US DoD and NASA. The symbol can encode a large amount of data in a small area. Data Matrix encodes characters in the Latin-1 set by default but also supports encoding in other character sets using the ECI -mechanism. It can also encode GS1 data. The size of the generated symbol can -also be adjusted using the --vers option (API option_2) as shown in the table -below. A separate symbology ID (BARCODE_HIBC_DM) can be used to encode Health -Industry Barcode (HIBC) data. Note that only ECC200 encoding is supported, the -older standards have now been removed from Zint. +mechanism. It can also encode GS1 data. The size of the generated symbol can be +adjusted using the --vers option (API option_2) as shown in the table below. A +separate symbology ID (BARCODE_HIBC_DM) can be used to encode Health Industry +Barcode (HIBC) data. Note that only ECC200 encoding is supported, the older +standards have now been removed from Zint. Input Symbol Size Input Symbol Size Input Symbol Size ------- ------------- -- ------- ------------- -- ------- ------------- @@ -3360,13 +3404,12 @@ option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set [zint -b RMQR -d "0123456"] -A rectangular version of QR Code, it is still under development, so it is -recommended it should not yet be used for a production environment. Like QR -Code, rMQR supports encoding of GS1 data, and either Latin-1 characters or Shift -JIS characters, and other encodings using the ECI mechanism. As with other -symbologies data should be entered as UTF-8 with conversion being handled by -Zint. The amount of ECC codewords can be adjusted using the --secure option (API -option_1), however only ECC levels M and H are valid for this type of symbol. +A rectangular version of QR Code, rMQR supports encoding of GS1 data, and either +Latin-1 characters or Shift JIS characters, and other encodings using the ECI +mechanism. As with other symbologies data should be entered as UTF-8 with +conversion being handled by Zint. The amount of ECC codewords can be adjusted +using the --secure option (API option_1), however only ECC levels M and H are +valid for this type of symbol. Input ECC Level Error Correction Capacity Recovery Capacity ------- ----------- --------------------------- ------------------- @@ -3835,41 +3878,23 @@ not a true barcode symbol and requires precise knowledge of the position of the mark on the page. The Flattermarken system can encode numeric data up to a maximum of 90 digits and does not include a check digit. -6.7.3 DAFT Code - -[zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 --vers=256] - -This is a method for creating 4-state codes where the data encoding is provided -by an external program. Input data should consist of the letters 'D', 'A', 'F' -and 'T' where these refer to descender, ascender, full (ascender and descender) -and tracker (neither ascender nor descender) respectively. All other characters -are invalid. The ratio of the tracker size to full height can be given in -thousandths (permille) using the --vers option (API option_2). The default value -is 250 (25%). - -For example the following - - zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256 - -produces the same barcode (see 6.5.3 Royal Mail 4-State Customer Code (RM4SCC)) -as - - zint -b RM4SCC --compliantheight -d "W1J0TR01" - 7. Legal and Version Information 7.1 License Zint, libzint and Zint Barcode Studio are Copyright © 2022 Robin Stuart. All historical versions are distributed under the GNU General Public License version -3 or later. Version 2.5 (and later) is released under a dual license: the -encoding library is released under the BSD license whereas the GUI, Zint Barcode -Studio, is released under the GNU General Public License version 3 or later. +3 or later. Versions 2.5 and later are released under a dual license: the +encoding library is released under the BSD (3 clause) license whereas the GUI, +Zint Barcode Studio, and the CLI are released under the GNU General Public +License version 3 or later. Telepen is a trademark of SB Electronic Systems Ltd. QR Code is a registered trademark of Denso Wave Incorporated. +Mailmark is a registered trademark of Royal Mail Group Ltd. + Microsoft, Windows and the Windows logo are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. @@ -3929,63 +3954,73 @@ Below is a list of some of the sources used in rough chronological order: Zint was developed to provide compliance with the following British and international standards: -- BS EN 798:1996 Bar coding - Symbology specifications - ‘Codabar’ -- BS EN 12323:2005 AIDC technologies - Symbology specifications - Code 16K -- ISO/IEC 15420:2009 Information technology - Automatic identification and - data capture techniques - EAN/UPC bar code symbology specification -- ISO/IEC 15417:2007 Information technology - Automatic identification and - data capture techniques - Code 128 bar code symbology specification -- ISO/IEC 15438:2015 Information technology - Automatic identification and - data capture techniques - PDF417 bar code symbology specification -- ISO/IEC 16022:2006 Information technology - Automatic identification and - data capture techniques - Data Matrix ECC200 bar code symbology - specification -- ISO/IEC 16023:2000 Information technology - International symbology - specification - MaxiCode -- ISO/IEC 16388:2007 Information technology - Automatic identification and - data capture techniques - Code 39 bar code symbology specification -- ISO/IEC 18004:2015 Information technology - Automatic identification and - data capture techniques - QR Code bar code symbology specification -- ISO/IEC 20830:2021 Information technology - Automatic identification and - data capture techniques - Han Xin Code bar code symbology specification -- ISO/IEC 24723:2010 Information technology - Automatic identification and - data capture techniques - GS1 Composite bar code symbology specification -- ISO/IEC 24724:2011 Information technology - Automatic identification and - data capture techniques - GS1 DataBar bar code symbology specification -- ISO/IEC 24728:2006 Information technology - Automatic identification and - data capture techniques - MicroPDF417 bar code symbology specification +7.5.1 Symbology Standards + - ISO/IEC 24778:2008 Information technology - Automatic identification and data capture techniques - Aztec Code bar code symbology specification -- ISO/IEC JTC1/SC31N000 (Draft 2019-6-24) Information technology - Automatic - identification and data capture techniques - Rectangular Micro QR Code - (rMQR) bar code symbology specification -- ISO/IEC 16390:2007 Information technology - Automatic identification and - data capture techniques - Interleaved 2 of 5 bar code symbology +- ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code +- BS EN 798:1996 Bar coding - Symbology specifications - ‘Codabar’ +- AIM Europe ISS-X-24 - Uniform Symbology Specification Codablock-F (1995) +- ISO/IEC 15417:2007 Information technology - Automatic identification and + data capture techniques - Code 128 bar code symbology specification +- BS EN 12323:2005 AIDC technologies - Symbology specifications - Code 16K +- ISO/IEC 16388:2007 Information technology - Automatic identification and + data capture techniques - Code 39 bar code symbology specification +- ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 +- ANSI/AIM BC5-1995 - Uniform Symbology Specification Code 93 +- AIM Uniform Symbology Specification Code One (1994) +- ISO/IEC 16022:2006 Information technology - Automatic identification and + data capture techniques - Data Matrix ECC200 bar code symbology specification - ISO/IEC 21471:2020 Information technology - Automatic identification and data capture techniques - Extended rectangular data matrix (DMRE) bar code symbology specification -- AIM Uniform Symbology Specification Code One (1994) -- ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code -- ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 -- ANSI/AIM BC5-1995 - Uniform Symbology Specification Code 93 -- AIM Europe ISS-X-24 - Uniform Symbology Specification Codablock-F (1995) - AIM TSC1705001 (v 4.0 Draft 0.15) - Information technology - Automatic identification and data capture techniques - Bar code symbology specification - DotCode (Revised 28th May 2019) +- ISO/IEC 15420:2009 Information technology - Automatic identification and + data capture techniques - EAN/UPC bar code symbology specification - AIMD014 (v 1.63) - Information technology, Automatic identification and data capture techniques - Bar code symbology specification - Grid Matrix (Released 9th Dec 2008) +- ISO/IEC 24723:2010 Information technology - Automatic identification and + data capture techniques - GS1 Composite bar code symbology specification +- ISO/IEC 24724:2011 Information technology - Automatic identification and + data capture techniques - GS1 DataBar bar code symbology specification +- ISO/IEC 20830:2021 Information technology - Automatic identification and + data capture techniques - Han Xin Code bar code symbology specification +- ISO/IEC 16390:2007 Information technology - Automatic identification and + data capture techniques - Interleaved 2 of 5 bar code symbology + specification +- ISO/IEC 16023:2000 Information technology - International symbology + specification - MaxiCode +- ISO/IEC 24728:2006 Information technology - Automatic identification and + data capture techniques - MicroPDF417 bar code symbology specification +- ISO/IEC 15438:2015 Information technology - Automatic identification and + data capture techniques - PDF417 bar code symbology specification +- ISO/IEC 18004:2015 Information technology - Automatic identification and + data capture techniques - QR Code bar code symbology specification +- ISO/IEC 23941:2022 Information technology - Automatic identification and + data capture techniques - Rectangular Micro QR Code (rMQR) bar code + symbology specification - AIMD/TSC15032-43 (v 0.99c) - International Technical Specification - Ultracode Symbology (Draft) (Released 4th Nov 2015) -- ANSI/HIBC 2.6-2016 - The Health Industry Bar Code (HIBC) Supplier Labeling - Standard -- GS1 General Specifications Release 22.0 (Jan 2022) + +A number of other specification documents have also been referenced, such as +MIL-STD-1189 Rev. B (1989) (LOGMARS), USPS DMM 300 2006 (2011) (POSTNET, PLANET, +FIM) and USPS-B-3200 (2015) (IMAIL). Those not named include postal and delivery +company references in particular. + +7.5.2 General Standards + - AIM ITS/04-001 International Technical Standard - Extended Channel Interpretations Part 1: Identification Schemes and Protocol (Released 24th May 2004) - AIM ITS/04-023 International Technical Standard - Extended Channel Interpretations Part 3: Register (Version 2, February 2022) +- GS1 General Specifications Release 22.0 (Jan 2022) +- ANSI/HIBC 2.6-2016 - The Health Industry Bar Code (HIBC) Supplier Labeling + Standard Annex A. Character Encoding @@ -4049,13 +4084,13 @@ defined. : Table : ISO/IEC 8859-1: -Annex B. zint(1) Man Page +Annex B. Man Page ZINT(1) -% zint(1) Version 2.11.0.9 % % May 2022 +% ZINT(1) Version 2.11.0.9 % % June 2022 NAME -zint - Encode data as a barcode image +zint - encode data as a barcode image SYNOPSIS @@ -4072,7 +4107,7 @@ Input data is UTF-8, unless --binary is specified. Human Readable Text (HRT) is displayed by default for those barcodes that support HRT, unless --notext is specified. -The output image file (specified with -o or --output) may be in one of these +The output image file (specified with -o | --output) may be in one of these formats: Windows Bitmap (BMP), Enhanced Metafile Format (EMF), Encapsulated PostScript (EPS), Graphics Interchange Format (GIF), ZSoft Paintbrush (PCX), Portable Network Format (PNG), Scalable Vector Graphic (SVG), or Tagged Image @@ -4086,20 +4121,20 @@ OPTIONS -b TYPE, --barcode=TYPE Set the barcode symbology that will be used to encode the data. TYPE is the number or name of the barcode symbology. If not given, the symbology - defaults to 20 (Code 128). To see what types are available, use the -t or + defaults to 20 (Code 128). To see what types are available, use the -t | --types option. Type names are case-insensitive, and non-alphanumerics are ignored. --addongap=INTEGER - For UPC/EAN symbologies, set the gap between the main data and the add-on. + For EAN/UPC symbologies, set the gap between the main data and the add-on. INTEGER is in integral multiples of the X-dimension. The maximum gap that can be set is 12. The minimum is 7, except for UPC-A, when the minimum is 9. --batch - Treat each line of an input file specified with -i or --input as a separate + Treat each line of an input file specified with -i | --input as a separate data set and produce a barcode image for each one. The barcode images are outputted by default to numbered filenames starting with “00001.png”, - “00002.png” etc., which can be changed by using the -o or --output option. + “00002.png” etc., which can be changed by using the -o | --output option. --bg=COLOUR Specify a background (paper) colour where COLOUR is in hex RRGGBB or @@ -4112,21 +4147,21 @@ OPTIONS --bind Add horizontal boundary bars (also known as bearer bars) to the symbol. The - width of the boundary bars must be specified by the --border option. --bind - can also be used to add row separator bars to symbols stacked with multiple - -d or --data inputs, in which case the width of the separator bars must be - specified with the --separator option. + width of the boundary bars is specified by the --border option. --bind can + also be used to add row separator bars to symbols stacked with multiple -d | + --data inputs, in which case the width of the separator bars is specified + with the --separator option. --bold Use bold text for the Human Readable Text (HRT). --border=INTEGER Set the width of boundary bars (--bind) or box borders (--box), where - INTEGER is in integral multiples of the X-dimension. + INTEGER is in integral multiples of the X-dimension. The default is zero. --box - Add a box around the symbol. The width of the borders must be specified by - the --border option. + Add a box around the symbol. The width of the borders is specified by the + --border option. --cmyk Use the CMYK colour space when outputting to Encapsulated PostScript (EPS) @@ -4173,7 +4208,7 @@ OPTIONS Dump a hexadecimal representation of the symbol’s encodation to stdout. The same representation may be outputted to a file by using a .txt extension - with -o or --output or by specifying --filetype=txt. + with -o | --output or by specifying --filetype=txt. -e, --ecinos @@ -4181,8 +4216,8 @@ OPTIONS --eci=INTEGER - Set the ECI code for the input data to INTEGER. See -e or --ecinos for a - list of the ECIs available. ECIs are supported by Aztec Code, Code One, Data + Set the ECI code for the input data to INTEGER. See -e | --ecinos for a list + of the ECIs available. ECIs are supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, Han Xin Code, MaxiCode, MicroPDF417, PDF417, QR Code, rMQR and Ultracode @@ -4190,23 +4225,27 @@ OPTIONS Process escape characters in the input data. The escape sequences are: - \0 (0x00) NUL Null character - \E (0x04) EOT End of Transmission - \a (0x07) BEL Bell - \b (0x08) BS Backspace - \t (0x09) HT Horizontal Tab - \n (0x0A) LF Line Feed - \v (0x0B) VT Vertical Tab - \f (0x0C) FF Form Feed - \r (0x0D) CR Carriage Return - \e (0x1B) ESC Escape - \G (0x1D) GS Group Separator - \R (0x1E) RS Record Separator - \\ (0x5C) \ Backslash - \xNN (0xNN) Any 8-bit character where NN is - hexadecimal - \uNNNN (U+NNNN) Any 16-bit Unicode BMP character - where NNNN is hexadecimal + \0 (0x00) NUL Null character + \E (0x04) EOT End of Transmission + \a (0x07) BEL Bell + \b (0x08) BS Backspace + \t (0x09) HT Horizontal Tab + \n (0x0A) LF Line Feed + \v (0x0B) VT Vertical Tab + \f (0x0C) FF Form Feed + \r (0x0D) CR Carriage Return + \e (0x1B) ESC Escape + \G (0x1D) GS Group Separator + \R (0x1E) RS Record Separator + \\ (0x5C) \ Backslash + \dNNN (NNN) Any 8-bit character where NNN is + decimal (000-255) + \xNN (0xNN) Any 8-bit character where NN is + hexadecimal + \uNNNN (U+NNNN) Any 16-bit Unicode BMP character + where NNNN is hexadecimal + \UNNNNNN (U+NNNNNN) Any 20-bit Unicode character + where NNNNNN is hexadecimal --fast @@ -4248,14 +4287,14 @@ OPTIONS --guarddescent=NUMBER - For UPC/EAN symbols, set the height of the guard bars’ descent, where NUMBER - is in multiples of the X-dimension. NUMBER may be floating-point. + For EAN/UPC symbols, set the height the guard bars descend below the main + bars, where NUMBER is in multiples of the X-dimension. NUMBER may be + floating-point. --height=NUMBER Set the height of the symbol in multiples of the X-dimension. NUMBER may be - floating-point. Increments of 0.5 are recommended for raster output (BMP, - GIF, PCX, PNG and TIF). + floating-point. --heightperrow @@ -4281,7 +4320,7 @@ OPTIONS --mode=INTEGER - For MaxiCode and Composite symbols, set the encoding mode to INTEGER. + For MaxiCode and GS1 Composite symbols, set the encoding mode to INTEGER. For MaxiCode (SCM is Structured Carrier Message, with 3 fields: postcode, 3-digit ISO 3166-1 country code, 3-digit service code): @@ -4292,7 +4331,7 @@ OPTIONS 5 Enhanced ECC for all of the message 6 Reader Initialisation (Programming) - For Composite symbols (names end in _CC, i.e. EANX_CC, GS1_128_CC, + For GS1 Composite symbols (names end in _CC, i.e. EANX_CC, GS1_128_CC, DBAR_OMN_CC etc.): 1 CC-A @@ -4324,17 +4363,18 @@ OPTIONS --primary=STRING - For MaxiCode, set the content of the primary message. For Composite symbols, - set the content of the linear symbol. + For MaxiCode, set the content of the primary message. For GS1 Composite + symbols, set the content of the linear symbol. --quietzones Add compliant quiet zones for symbols that specify one. This is in addition - to any whitespace specified by -w or --whitesp or --vwhitesp. + to any whitespace specified by -w | --whitesp or --vwhitesp. -r, --reverse - Reverse the foreground and background colours (white on black). + Reverse the foreground and background colours (white on black). Known as + “reflectance reversal” or “reversed reflectance”. --rotate=INTEGER @@ -4349,10 +4389,15 @@ OPTIONS --scale=NUMBER - Set the X-dimension. NUMBER may be floating-point, and is multiplied by 2 - (except for MaxiCode) before being applied. For MaxiCode, the scale is - multiplied by 10 for raster output, by 20 for EMF vector output, and by 2 - otherwise. The default scale is 1. + Adjust the size of the X-dimension. NUMBER may be floating-point, and is + multiplied by 2 (except for MaxiCode) before being applied. The default + scale is 1. + + For MaxiCode, the scale is multiplied by 10 for raster output, by 20 for EMF + output, and by 2 otherwise. + + Increments of 0.5 (half-integers) are recommended for non-MaxiCode raster + output (BMP, GIF, PCX, PNG and TIF). --scmvv=INTEGER @@ -4362,27 +4407,27 @@ OPTIONS --secure=INTEGER Set the error correction level (ECC) to INTEGER. The meaning is specific to - the following matrix symbols: + the following matrix symbols (all except PDF417 are approximate): - Aztec Code 1 to 4 (10%, 23%, 36%, 50%) (approx.) - Grid Matrix 1 to 5 (10% to 50%) (approx.) - Han Xin 1 to 4 (8%, 15%, 23%, 30%) (approx.) - Micro QR 1 to 3 (L, M, Q) + Aztec Code 1 to 4 (10%, 23%, 36%, 50%) + Grid Matrix 1 to 5 (10% to 50%) + Han Xin 1 to 4 (8%, 15%, 23%, 30%) + Micro QR 1 to 3 (7%, 15%, 25%) (L, M, Q) PDF417 0 to 8 (2^(INTEGER + 1) codewords) - QR Code 1 to 4 (L, M, Q, H) - rMQR 2 or 4 (M, H) - Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) (approx.) + QR Code 1 to 4 (7%, 15%, 25%, 30%) (L, M, Q, H) + rMQR 2 or 4 (15% or 30%) (M or H) + Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) --segN=ECI,DATA - Set the ECI & DATA content for segment N, where N is 1 to 9. -d or --data + Set the ECI & DATA content for segment N, where N is 1 to 9. -d | --data must still be given, and counts as segment 0, its ECI given by --eci. Segments must be consecutive. --separator=INTEGER Set the height of row separator bars for stacked symbologies, where INTEGER - is in integral multiples of the X-dimension. + is in integral multiples of the X-dimension. The default is zero. --small @@ -4395,16 +4440,16 @@ OPTIONS --structapp=I,C[,ID] - Set Structured Append info, where I is the 1-based index, C is the count of - total symbols in the sequence, and ID, which is optional, is the identifier - that all symbols in the sequence share. Structured Append is supported by - Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, MaxiCode, - MicroPDF417, PDF417, QR Code and Ultracode. + Set Structured Append info, where I is the 1-based index, C is the total + number of symbols in the sequence, and ID, which is optional, is the + identifier that all symbols in the sequence share. Structured Append is + supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, + MaxiCode, MicroPDF417, PDF417, QR Code and Ultracode. -t, --types Display the table of barcode types (symbologies). The numbers or names can - be used with -b or --barcode. + be used with -b | --barcode. --vers=INTEGER @@ -4432,13 +4477,16 @@ OPTIONS C25LOGIC ditto C25STANDARD ditto Codabar 1 or 2 (add hidden or visible check digit) - Code 11 0 or 1 (no or 1 check digit only) - (has 2 check digits by default) + Code 11 0 or 1 (no or 1 visible check digit only) + (default is 2 visible check digits) Code 39 1 (add visible check digit) Code 93 1 (hide the default check characters) EXCODE39 1 (add visible check digit) LOGMARS 1 (add visible check digit) - MSI Plessey 0 to 6 (various check digit options) + MSI Plessey 0 to 6 (none to various visible options) + 1, 2 (mod-10, mod-10 + mod-10) + 3, 4 (mod-11 IBM, mod-11 IBM + mod-10) + 5, 6 (mod-11 NCR, mod-11 NCR + mod-10) +10 (hide) For a few other symbologies, it specifies other characteristics: @@ -4469,8 +4517,8 @@ OPTIONS EXIT STATUS 0 - Success (including when given informational options -h, --help, -e, - --ecinos, -t, --types, -v, --version). + Success (including when given informational options -h | --help, -e | + --ecinos, -t | --types, -v | --version). 2 Invalid option given but overridden by Zint (ZINT_WARN_INVALID_OPTION) @@ -4543,15 +4591,19 @@ CONFORMING TO Zint is designed to be compliant with a number of international standards, including: -EN 798:1996, EN 12323:2005, ISO/IEC 15420:2009, ISO/IEC 15417:2007, ISO/IEC -15438:2015, ISO/IEC 16022:2006, ISO/IEC 16023:2000, ISO/IEC 16388:2007, ISO/IEC -18004:2015, ISO/IEC 20830:2021, ISO/IEC 24723:2010, ISO/IEC 24724:2011, ISO/IEC -24728:2006, ISO/IEC 24778:2008, ISO/IEC 16390:2007, ISO/IEC 21471:2019, AIM USS -Code One (1994), ANSI/AIM BC12-1998, ANSI/AIM BC6-2000, ANSI/AIM BC5-1995, AIM -ISS-X-24 (1995), AIMD014 (v 1.63) (2008), ANSI-HIBC 2.6-2016, AIM ITS/04-023 -(2022) +ISO/IEC 24778:2008, ANSI/AIM BC12-1998, EN 798:1996, AIM ISS-X-24 (1995), +ISO/IEC 15417:2007, EN 12323:2005, ISO/IEC 16388:2007, ANSI/AIM BC6-2000, +ANSI/AIM BC5-1995, AIM USS Code One (1994), ISO/IEC 16022:2006, ISO/IEC +21471:2019, ISO/IEC 15420:2009, AIMD014 (v 1.63) (2008), ISO/IEC 24723:2010, +ISO/IEC 24724:2011, ISO/IEC 20830:2021, ISO/IEC 16390:2007, ISO/IEC 16023:2000, +ISO/IEC 24728:2006, ISO/IEC 15438:2015, ISO/IEC 18004:2015, ISO/IEC 23941:2022, +AIM ITS/04-023 (2022) -AUTHORS +COPYRIGHT + +Copyright © 2022 Robin Stuart. Released under GNU GPL 3.0 or later. + +AUTHOR Robin Stuart robin@zint.org.uk diff --git a/docs/zint.1 b/docs/zint.1 index a6eec709..f77407c4 100644 --- a/docs/zint.1 +++ b/docs/zint.1 @@ -14,11 +14,11 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "zint" "1" "May 2022" "Version 2.11.0.9" "" +.TH "ZINT" "1" "June 2022" "Version 2.11.0.9" "" .hy .SH NAME .PP -\f[V]zint\f[R] - Encode data as a barcode image +\f[V]zint\f[R] - encode data as a barcode image .SH SYNOPSIS .PP \f[V]zint\f[R] [\f[V]-h\f[R] | \f[V]--help\f[R]] @@ -36,13 +36,13 @@ Input data is UTF-8, unless \f[V]--binary\f[R] is specified. Human Readable Text (HRT) is displayed by default for those barcodes that support HRT, unless \f[V]--notext\f[R] is specified. .PP -The output image file (specified with \f[V]-o\f[R] or -\f[V]--output\f[R]) may be in one of these formats: Windows Bitmap -(\f[V]BMP\f[R]), Enhanced Metafile Format (\f[V]EMF\f[R]), Encapsulated -PostScript (\f[V]EPS\f[R]), Graphics Interchange Format (\f[V]GIF\f[R]), -ZSoft Paintbrush (\f[V]PCX\f[R]), Portable Network Format -(\f[V]PNG\f[R]), Scalable Vector Graphic (\f[V]SVG\f[R]), or Tagged -Image File Format (\f[V]TIF\f[R]). +The output image file (specified with \f[V]-o\f[R] | \f[V]--output\f[R]) +may be in one of these formats: Windows Bitmap (\f[V]BMP\f[R]), Enhanced +Metafile Format (\f[V]EMF\f[R]), Encapsulated PostScript +(\f[V]EPS\f[R]), Graphics Interchange Format (\f[V]GIF\f[R]), ZSoft +Paintbrush (\f[V]PCX\f[R]), Portable Network Format (\f[V]PNG\f[R]), +Scalable Vector Graphic (\f[V]SVG\f[R]), or Tagged Image File Format +(\f[V]TIF\f[R]). .SH OPTIONS .TP \f[V]-h\f[R], \f[V]--help\f[R] @@ -52,28 +52,28 @@ Print usage information summarizing command line options. Set the barcode symbology that will be used to encode the data. \f[I]TYPE\f[R] is the number or name of the barcode symbology. If not given, the symbology defaults to 20 (Code 128). -To see what types are available, use the \f[V]-t\f[R] or +To see what types are available, use the \f[V]-t\f[R] | \f[V]--types\f[R] option. Type names are case-insensitive, and non-alphanumerics are ignored. .TP \f[V]--addongap=INTEGER\f[R] -For UPC/EAN symbologies, set the gap between the main data and the +For EAN/UPC symbologies, set the gap between the main data and the add-on. \f[I]INTEGER\f[R] is in integral multiples of the X-dimension. The maximum gap that can be set is 12. The minimum is 7, except for UPC-A, when the minimum is 9. .TP \f[V]--batch\f[R] -Treat each line of an input file specified with \f[V]-i\f[R] or +Treat each line of an input file specified with \f[V]-i\f[R] | \f[V]--input\f[R] as a separate data set and produce a barcode image for each one. The barcode images are outputted by default to numbered filenames starting with \[lq]00001.png\[rq], \[lq]00002.png\[rq] etc., which can -be changed by using the \f[V]-o\f[R] or \f[V]--output\f[R] option. +be changed by using the \f[V]-o\f[R] | \f[V]--output\f[R] option. .TP \f[V]--bg=COLOUR\f[R] Specify a background (paper) colour where \f[I]COLOUR\f[R] is in hex -RRGGBB or RRGGBBAA format. +\f[V]RRGGBB\f[R] or \f[V]RRGGBBAA\f[R] format. .TP \f[V]--binary\f[R] Treat input data as raw 8-bit binary data instead of the default UTF-8. @@ -82,11 +82,11 @@ validation of the data\[cq]s character encoding takes place. .TP \f[V]--bind\f[R] Add horizontal boundary bars (also known as bearer bars) to the symbol. -The width of the boundary bars must be specified by the -\f[V]--border\f[R] option. +The width of the boundary bars is specified by the \f[V]--border\f[R] +option. \f[V]--bind\f[R] can also be used to add row separator bars to symbols -stacked with multiple \f[V]-d\f[R] or \f[V]--data\f[R] inputs, in which -case the width of the separator bars must be specified with the +stacked with multiple \f[V]-d\f[R] | \f[V]--data\f[R] inputs, in which +case the width of the separator bars is specified with the \f[V]--separator\f[R] option. .TP \f[V]--bold\f[R] @@ -96,11 +96,11 @@ Use bold text for the Human Readable Text (HRT). Set the width of boundary bars (\f[V]--bind\f[R]) or box borders (\f[V]--box\f[R]), where \f[I]INTEGER\f[R] is in integral multiples of the X-dimension. +The default is zero. .TP \f[V]--box\f[R] Add a box around the symbol. -The width of the borders must be specified by the \f[V]--border\f[R] -option. +The width of the borders is specified by the \f[V]--border\f[R] option. .TP \f[V]--cmyk\f[R] Use the CMYK colour space when outputting to Encapsulated PostScript @@ -147,7 +147,7 @@ DotCode is always in dotty mode. Dump a hexadecimal representation of the symbol\[cq]s encodation to stdout. The same representation may be outputted to a file by using a -\f[V].txt\f[R] extension with \f[V]-o\f[R] or \f[V]--output\f[R] or by +\f[V].txt\f[R] extension with \f[V]-o\f[R] | \f[V]--output\f[R] or by specifying \f[V]--filetype=txt\f[R]. .TP \f[V]-e\f[R], \f[V]--ecinos\f[R] @@ -155,7 +155,7 @@ Display the table of ECIs (Extended Channel Interpretations). .TP \f[V]--eci=INTEGER\f[R] Set the ECI code for the input data to \f[I]INTEGER\f[R]. -See \f[V]-e\f[R] or \f[V]--ecinos\f[R] for a list of the ECIs available. +See \f[V]-e\f[R] | \f[V]--ecinos\f[R] for a list of the ECIs available. ECIs are supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, Han Xin Code, MaxiCode, MicroPDF417, PDF417, QR Code, rMQR and Ultracode @@ -167,23 +167,27 @@ The escape sequences are: .IP .nf \f[C] -\[rs]0 (0x00) NUL Null character -\[rs]E (0x04) EOT End of Transmission -\[rs]a (0x07) BEL Bell -\[rs]b (0x08) BS Backspace -\[rs]t (0x09) HT Horizontal Tab -\[rs]n (0x0A) LF Line Feed -\[rs]v (0x0B) VT Vertical Tab -\[rs]f (0x0C) FF Form Feed -\[rs]r (0x0D) CR Carriage Return -\[rs]e (0x1B) ESC Escape -\[rs]G (0x1D) GS Group Separator -\[rs]R (0x1E) RS Record Separator -\[rs]\[rs] (0x5C) \[rs] Backslash -\[rs]xNN (0xNN) Any 8-bit character where NN is - hexadecimal -\[rs]uNNNN (U+NNNN) Any 16-bit Unicode BMP character - where NNNN is hexadecimal +\[rs]0 (0x00) NUL Null character +\[rs]E (0x04) EOT End of Transmission +\[rs]a (0x07) BEL Bell +\[rs]b (0x08) BS Backspace +\[rs]t (0x09) HT Horizontal Tab +\[rs]n (0x0A) LF Line Feed +\[rs]v (0x0B) VT Vertical Tab +\[rs]f (0x0C) FF Form Feed +\[rs]r (0x0D) CR Carriage Return +\[rs]e (0x1B) ESC Escape +\[rs]G (0x1D) GS Group Separator +\[rs]R (0x1E) RS Record Separator +\[rs]\[rs] (0x5C) \[rs] Backslash +\[rs]dNNN (NNN) Any 8-bit character where NNN is + decimal (000-255) +\[rs]xNN (0xNN) Any 8-bit character where NN is + hexadecimal +\[rs]uNNNN (U+NNNN) Any 16-bit Unicode BMP character + where NNNN is hexadecimal +\[rs]UNNNNNN (U+NNNNNN) Any 20-bit Unicode character + where NNNNNN is hexadecimal \f[R] .fi .RE @@ -194,7 +198,7 @@ only). .TP \f[V]--fg=COLOUR\f[R] Specify a foreground (ink) colour where \f[I]COLOUR\f[R] is in hex -RRGGBB or RRGGBBAA format. +\f[V]RRGGBB\f[R] or \f[V]RRGGBBAA\f[R] format. .TP \f[V]--filetype=TYPE\f[R] Set the output file type to \f[I]TYPE\f[R], which is one of @@ -224,15 +228,13 @@ For Data Matrix in GS1 mode, use \f[V]GS\f[R] (0x1D) as the GS1 data separator instead of \f[V]FNC1\f[R]. .TP \f[V]--guarddescent=NUMBER\f[R] -For UPC/EAN symbols, set the height of the guard bars\[cq] descent, -where \f[I]NUMBER\f[R] is in multiples of the X-dimension. +For EAN/UPC symbols, set the height the guard bars descend below the +main bars, where \f[I]NUMBER\f[R] is in multiples of the X-dimension. \f[I]NUMBER\f[R] may be floating-point. .TP \f[V]--height=NUMBER\f[R] Set the height of the symbol in multiples of the X-dimension. \f[I]NUMBER\f[R] may be floating-point. -Increments of 0.5 are recommended for raster output (BMP, GIF, PCX, PNG -and TIF). .TP \f[V]--heightperrow\f[R] Treat height as per-row. @@ -254,7 +256,7 @@ Use the batch data to determine the filename in batch mode (\f[V]--batch\f[R]). .TP \f[V]--mode=INTEGER\f[R] -For MaxiCode and Composite symbols, set the encoding mode to +For MaxiCode and GS1 Composite symbols, set the encoding mode to \f[I]INTEGER\f[R]. .RS .PP @@ -271,7 +273,7 @@ postcode, 3-digit ISO 3166-1 country code, 3-digit service code): \f[R] .fi .PP -For Composite symbols (names end in \f[V]_CC\f[R], i.e.\ EANX_CC, +For GS1 Composite symbols (names end in \f[V]_CC\f[R], i.e.\ EANX_CC, GS1_128_CC, DBAR_OMN_CC etc.): .IP .nf @@ -312,15 +314,17 @@ Any other Insert literally .TP \f[V]--primary=STRING\f[R] For MaxiCode, set the content of the primary message. -For Composite symbols, set the content of the linear symbol. +For GS1 Composite symbols, set the content of the linear symbol. .TP \f[V]--quietzones\f[R] Add compliant quiet zones for symbols that specify one. -This is in addition to any whitespace specified by \f[V]-w\f[R] or +This is in addition to any whitespace specified by \f[V]-w\f[R] | \f[V]--whitesp\f[R] or \f[V]--vwhitesp\f[R]. .TP \f[V]-r\f[R], \f[V]--reverse\f[R] Reverse the foreground and background colours (white on black). +Known as \[lq]reflectance reversal\[rq] or \[lq]reversed +reflectance\[rq]. .TP \f[V]--rotate=INTEGER\f[R] Rotate the symbol by \f[I]INTEGER\f[R] degrees, where \f[I]INTEGER\f[R] @@ -333,33 +337,40 @@ the maximum number of rows for GS1 DataBar Expanded Stacked (DBAR_EXPSTK). .TP \f[V]--scale=NUMBER\f[R] -Set the X-dimension. +Adjust the size of the X-dimension. \f[I]NUMBER\f[R] may be floating-point, and is multiplied by 2 (except for MaxiCode) before being applied. -For MaxiCode, the scale is multiplied by 10 for raster output, by 20 for -EMF vector output, and by 2 otherwise. The default scale is 1. +.RS +.PP +For MaxiCode, the scale is multiplied by 10 for raster output, by 20 for +EMF output, and by 2 otherwise. +.PP +Increments of 0.5 (half-integers) are recommended for non-MaxiCode +raster output (BMP, GIF, PCX, PNG and TIF). +.RE .TP \f[V]--scmvv=INTEGER\f[R] For MaxiCode, prefix the Structured Carrier Message (SCM) with -\f[V]\[dq][)>\[rs]R01\[rs]Gvv\[dq]\f[R], where vv is a 2-digit +\f[V]\[dq][)>\[rs]R01\[rs]Gvv\[dq]\f[R], where \f[V]vv\f[R] is a 2-digit \f[I]INTEGER\f[R]. .TP \f[V]--secure=INTEGER\f[R] Set the error correction level (ECC) to \f[I]INTEGER\f[R]. -The meaning is specific to the following matrix symbols: +The meaning is specific to the following matrix symbols (all except +PDF417 are approximate): .RS .IP .nf \f[C] -Aztec Code 1 to 4 (10%, 23%, 36%, 50%) (approx.) -Grid Matrix 1 to 5 (10% to 50%) (approx.) -Han Xin 1 to 4 (8%, 15%, 23%, 30%) (approx.) -Micro QR 1 to 3 (L, M, Q) +Aztec Code 1 to 4 (10%, 23%, 36%, 50%) +Grid Matrix 1 to 5 (10% to 50%) +Han Xin 1 to 4 (8%, 15%, 23%, 30%) +Micro QR 1 to 3 (7%, 15%, 25%) (L, M, Q) PDF417 0 to 8 (2\[ha](INTEGER + 1) codewords) -QR Code 1 to 4 (L, M, Q, H) -rMQR 2 or 4 (M, H) -Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) (approx.) +QR Code 1 to 4 (7%, 15%, 25%, 30%) (L, M, Q, H) +rMQR 2 or 4 (15% or 30%) (M or H) +Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) \f[R] .fi .RE @@ -367,13 +378,14 @@ Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) (approx.) \f[V]--segN=ECI,DATA\f[R] Set the \f[I]ECI\f[R] & \f[I]DATA\f[R] content for segment N, where N is 1 to 9. -\f[V]-d\f[R] or \f[V]--data\f[R] must still be given, and counts as +\f[V]-d\f[R] | \f[V]--data\f[R] must still be given, and counts as segment 0, its ECI given by \f[V]--eci\f[R]. Segments must be consecutive. .TP \f[V]--separator=INTEGER\f[R] Set the height of row separator bars for stacked symbologies, where \f[I]INTEGER\f[R] is in integral multiples of the X-dimension. +The default is zero. .TP \f[V]--small\f[R] Use small text for Human Readable Text (HRT). @@ -384,7 +396,7 @@ automatic sizes. .TP \f[V]--structapp=I,C[,ID]\f[R] Set Structured Append info, where \f[V]I\f[R] is the 1-based index, -\f[V]C\f[R] is the count of total symbols in the sequence, and +\f[V]C\f[R] is the total number of symbols in the sequence, and \f[V]ID\f[R], which is optional, is the identifier that all symbols in the sequence share. Structured Append is supported by Aztec Code, Code One, Data Matrix, @@ -393,7 +405,7 @@ Ultracode. .TP \f[V]-t\f[R], \f[V]--types\f[R] Display the table of barcode types (symbologies). -The numbers or names can be used with \f[V]-b\f[R] or +The numbers or names can be used with \f[V]-b\f[R] | \f[V]--barcode\f[R]. .TP \f[V]--vers=INTEGER\f[R] @@ -429,13 +441,16 @@ C25INTER ditto C25LOGIC ditto C25STANDARD ditto Codabar 1 or 2 (add hidden or visible check digit) -Code 11 0 or 1 (no or 1 check digit only) - (has 2 check digits by default) +Code 11 0 or 1 (no or 1 visible check digit only) + (default is 2 visible check digits) Code 39 1 (add visible check digit) Code 93 1 (hide the default check characters) EXCODE39 1 (add visible check digit) LOGMARS 1 (add visible check digit) -MSI Plessey 0 to 6 (various check digit options) +MSI Plessey 0 to 6 (none to various visible options) + 1, 2 (mod-10, mod-10 + mod-10) + 3, 4 (mod-11 IBM, mod-11 IBM + mod-10) + 5, 6 (mod-11 NCR, mod-11 NCR + mod-10) +10 (hide) \f[R] .fi @@ -468,9 +483,9 @@ Convert all warnings into errors. .SH EXIT STATUS .TP \f[V]0\f[R] -Success (including when given informational options \f[V]-h\f[R], -\f[V]--help\f[R], \f[V]-e\f[R], \f[V]--ecinos\f[R], \f[V]-t\f[R], -\f[V]--types\f[R], \f[V]-v\f[R], \f[V]--version\f[R]). +Success (including when given informational options \f[V]-h\f[R] | +\f[V]--help\f[R], \f[V]-e\f[R] | \f[V]--ecinos\f[R], \f[V]-t\f[R] | +\f[V]--types\f[R], \f[V]-v\f[R] | \f[V]--version\f[R]). .TP \f[V]2\f[R] Invalid option given but overridden by Zint @@ -559,13 +574,18 @@ https://sourceforge.net/p/zint/docs/manual.txt. Zint is designed to be compliant with a number of international standards, including: .PP -EN 798:1996, EN 12323:2005, ISO/IEC 15420:2009, ISO/IEC 15417:2007, -ISO/IEC 15438:2015, ISO/IEC 16022:2006, ISO/IEC 16023:2000, ISO/IEC -16388:2007, ISO/IEC 18004:2015, ISO/IEC 20830:2021, ISO/IEC 24723:2010, -ISO/IEC 24724:2011, ISO/IEC 24728:2006, ISO/IEC 24778:2008, ISO/IEC -16390:2007, ISO/IEC 21471:2019, AIM USS Code One (1994), ANSI/AIM -BC12-1998, ANSI/AIM BC6-2000, ANSI/AIM BC5-1995, AIM ISS-X-24 (1995), -AIMD014 (v 1.63) (2008), ANSI-HIBC 2.6-2016, AIM ITS/04-023 (2022) -.SH AUTHORS +ISO/IEC 24778:2008, ANSI/AIM BC12-1998, EN 798:1996, AIM ISS-X-24 +(1995), ISO/IEC 15417:2007, EN 12323:2005, ISO/IEC 16388:2007, ANSI/AIM +BC6-2000, ANSI/AIM BC5-1995, AIM USS Code One (1994), ISO/IEC +16022:2006, ISO/IEC 21471:2019, ISO/IEC 15420:2009, AIMD014 (v 1.63) +(2008), ISO/IEC 24723:2010, ISO/IEC 24724:2011, ISO/IEC 20830:2021, +ISO/IEC 16390:2007, ISO/IEC 16023:2000, ISO/IEC 24728:2006, ISO/IEC +15438:2015, ISO/IEC 18004:2015, ISO/IEC 23941:2022, AIM ITS/04-023 +(2022) +.SH COPYRIGHT +.PP +Copyright \[co] 2022 Robin Stuart. +Released under GNU GPL 3.0 or later. +.SH AUTHOR .PP Robin Stuart diff --git a/docs/zint.1.pmd b/docs/zint.1.pmd index 5b80575f..89a278a6 100644 --- a/docs/zint.1.pmd +++ b/docs/zint.1.pmd @@ -1,10 +1,10 @@ -% zint(1) Version 2.11.0.9 +% ZINT(1) Version 2.11.0.9 % -% May 2022 +% June 2022 # NAME -`zint` - Encode data as a barcode image +`zint` - encode data as a barcode image # SYNOPSIS @@ -19,7 +19,7 @@ Input data is UTF-8, unless `--binary` is specified. Human Readable Text (HRT) is displayed by default for those barcodes that support HRT, unless `--notext` is specified. -The output image file (specified with `-o` or `--output`) may be in one of these formats: Windows Bitmap (`BMP`), +The output image file (specified with `-o` | `--output`) may be in one of these formats: Windows Bitmap (`BMP`), Enhanced Metafile Format (`EMF`), Encapsulated PostScript (`EPS`), Graphics Interchange Format (`GIF`), ZSoft Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`SVG`), or Tagged Image File Format (`TIF`). @@ -31,40 +31,40 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `-b TYPE`, `--barcode=TYPE` : Set the barcode symbology that will be used to encode the data. *TYPE* is the number or name of the barcode - symbology. If not given, the symbology defaults to 20 (Code 128). To see what types are available, use the `-t` or + symbology. If not given, the symbology defaults to 20 (Code 128). To see what types are available, use the `-t` | `--types` option. Type names are case-insensitive, and non-alphanumerics are ignored. `--addongap=INTEGER` -: For UPC/EAN symbologies, set the gap between the main data and the add-on. *INTEGER* is in integral multiples of +: For EAN/UPC symbologies, set the gap between the main data and the add-on. *INTEGER* is in integral multiples of the X-dimension. The maximum gap that can be set is 12. The minimum is 7, except for UPC-A, when the minimum is 9. `--batch` -: Treat each line of an input file specified with `-i` or `--input` as a separate data set and produce a barcode +: Treat each line of an input file specified with `-i` | `--input` as a separate data set and produce a barcode image for each one. The barcode images are outputted by default to numbered filenames starting with "00001.png", - "00002.png" etc., which can be changed by using the `-o` or `--output` option. + "00002.png" etc., which can be changed by using the `-o` | `--output` option. `--bg=COLOUR` -: Specify a background (paper) colour where *COLOUR* is in hex RRGGBB or RRGGBBAA format. +: Specify a background (paper) colour where *COLOUR* is in hex `RRGGBB` or `RRGGBBAA` format. `--binary` : Treat input data as raw 8-bit binary data instead of the default UTF-8. Automatic code page translation to an ECI page is disabled, and no validation of the data's character encoding takes place. `--bind` -: Add horizontal boundary bars (also known as bearer bars) to the symbol. The width of the boundary bars must be +: Add horizontal boundary bars (also known as bearer bars) to the symbol. The width of the boundary bars is specified by the `--border` option. `--bind` can also be used to add row separator bars to symbols stacked with - multiple `-d` or `--data` inputs, in which case the width of the separator bars must be specified with the - `--separator` option. + multiple `-d` | `--data` inputs, in which case the width of the separator bars is specified with the `--separator` + option. `--bold` : Use bold text for the Human Readable Text (HRT). `--border=INTEGER` : Set the width of boundary bars (`--bind`) or box borders (`--box`), where *INTEGER* is in integral multiples of - the X-dimension. + the X-dimension. The default is zero. `--box` -: Add a box around the symbol. The width of the borders must be specified by the `--border` option. +: Add a box around the symbol. The width of the borders is specified by the `--border` option. `--cmyk` : Use the CMYK colour space when outputting to Encapsulated PostScript (EPS) or TIF files. @@ -104,7 +104,7 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--dump` : Dump a hexadecimal representation of the symbol's encodation to stdout. The same representation may be outputted - to a file by using a `.txt` extension with `-o` or `--output` or by specifying `--filetype=txt`. + to a file by using a `.txt` extension with `-o` | `--output` or by specifying `--filetype=txt`. `-e`, `--ecinos` @@ -112,31 +112,35 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--eci=INTEGER` -: Set the ECI code for the input data to *INTEGER*. See `-e` or `--ecinos` for a list of the ECIs available. ECIs - are supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, Han Xin Code, MaxiCode, MicroPDF417, - PDF417, QR Code, rMQR and Ultracode +: Set the ECI code for the input data to *INTEGER*. See `-e` | `--ecinos` for a list of the ECIs available. ECIs are + supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, Han Xin Code, MaxiCode, MicroPDF417, PDF417, + QR Code, rMQR and Ultracode `--esc` : Process escape characters in the input data. The escape sequences are: - \0 (0x00) NUL Null character - \E (0x04) EOT End of Transmission - \a (0x07) BEL Bell - \b (0x08) BS Backspace - \t (0x09) HT Horizontal Tab - \n (0x0A) LF Line Feed - \v (0x0B) VT Vertical Tab - \f (0x0C) FF Form Feed - \r (0x0D) CR Carriage Return - \e (0x1B) ESC Escape - \G (0x1D) GS Group Separator - \R (0x1E) RS Record Separator - \\ (0x5C) \ Backslash - \xNN (0xNN) Any 8-bit character where NN is - hexadecimal - \uNNNN (U+NNNN) Any 16-bit Unicode BMP character - where NNNN is hexadecimal + \0 (0x00) NUL Null character + \E (0x04) EOT End of Transmission + \a (0x07) BEL Bell + \b (0x08) BS Backspace + \t (0x09) HT Horizontal Tab + \n (0x0A) LF Line Feed + \v (0x0B) VT Vertical Tab + \f (0x0C) FF Form Feed + \r (0x0D) CR Carriage Return + \e (0x1B) ESC Escape + \G (0x1D) GS Group Separator + \R (0x1E) RS Record Separator + \\ (0x5C) \ Backslash + \dNNN (NNN) Any 8-bit character where NNN is + decimal (000-255) + \xNN (0xNN) Any 8-bit character where NN is + hexadecimal + \uNNNN (U+NNNN) Any 16-bit Unicode BMP character + where NNNN is hexadecimal + \UNNNNNN (U+NNNNNN) Any 20-bit Unicode character + where NNNNNN is hexadecimal `--fast` @@ -144,7 +148,7 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--fg=COLOUR` -: Specify a foreground (ink) colour where *COLOUR* is in hex RRGGBB or RRGGBBAA format. +: Specify a foreground (ink) colour where *COLOUR* is in hex `RRGGBB` or `RRGGBBAA` format. `--filetype=TYPE` @@ -174,13 +178,12 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--guarddescent=NUMBER` -: For UPC/EAN symbols, set the height of the guard bars' descent, where *NUMBER* is in multiples of the X-dimension. - *NUMBER* may be floating-point. +: For EAN/UPC symbols, set the height the guard bars descend below the main bars, where *NUMBER* is in multiples of + the X-dimension. *NUMBER* may be floating-point. `--height=NUMBER` -: Set the height of the symbol in multiples of the X-dimension. *NUMBER* may be floating-point. Increments of 0.5 - are recommended for raster output (BMP, GIF, PCX, PNG and TIF). +: Set the height of the symbol in multiples of the X-dimension. *NUMBER* may be floating-point. `--heightperrow` @@ -205,7 +208,7 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--mode=INTEGER` -: For MaxiCode and Composite symbols, set the encoding mode to *INTEGER*. +: For MaxiCode and GS1 Composite symbols, set the encoding mode to *INTEGER*. For MaxiCode (SCM is Structured Carrier Message, with 3 fields: postcode, 3-digit ISO 3166-1 country code, 3-digit service code): @@ -216,7 +219,7 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S 5 Enhanced ECC for all of the message 6 Reader Initialisation (Programming) - For Composite symbols (names end in `_CC`, i.e. EANX_CC, GS1_128_CC, DBAR_OMN_CC etc.): + For GS1 Composite symbols (names end in `_CC`, i.e. EANX_CC, GS1_128_CC, DBAR_OMN_CC etc.): 1 CC-A 2 CC-B @@ -246,16 +249,18 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--primary=STRING` -: For MaxiCode, set the content of the primary message. For Composite symbols, set the content of the linear symbol. +: For MaxiCode, set the content of the primary message. For GS1 Composite symbols, set the content of the linear + symbol. `--quietzones` -: Add compliant quiet zones for symbols that specify one. This is in addition to any whitespace specified by `-w` or +: Add compliant quiet zones for symbols that specify one. This is in addition to any whitespace specified by `-w` | `--whitesp` or `--vwhitesp`. `-r`, `--reverse` -: Reverse the foreground and background colours (white on black). +: Reverse the foreground and background colours (white on black). Known as "reflectance reversal" or "reversed + reflectance". `--rotate=INTEGER` @@ -268,36 +273,40 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--scale=NUMBER` -: Set the X-dimension. *NUMBER* may be floating-point, and is multiplied by 2 (except for MaxiCode) before being - applied. For MaxiCode, the scale is multiplied by 10 for raster output, by 20 for EMF vector output, and by 2 - otherwise. The default scale is 1. +: Adjust the size of the X-dimension. *NUMBER* may be floating-point, and is multiplied by 2 (except for MaxiCode) + before being applied. The default scale is 1. + + For MaxiCode, the scale is multiplied by 10 for raster output, by 20 for EMF output, and by 2 otherwise. + + Increments of 0.5 (half-integers) are recommended for non-MaxiCode raster output (BMP, GIF, PCX, PNG and TIF). `--scmvv=INTEGER` -: For MaxiCode, prefix the Structured Carrier Message (SCM) with `"[)>\R01\Gvv"`, where vv is a 2-digit *INTEGER*. +: For MaxiCode, prefix the Structured Carrier Message (SCM) with `"[)>\R01\Gvv"`, where `vv` is a 2-digit *INTEGER*. `--secure=INTEGER` -: Set the error correction level (ECC) to *INTEGER*. The meaning is specific to the following matrix symbols: +: Set the error correction level (ECC) to *INTEGER*. The meaning is specific to the following matrix symbols (all + except PDF417 are approximate): - Aztec Code 1 to 4 (10%, 23%, 36%, 50%) (approx.) - Grid Matrix 1 to 5 (10% to 50%) (approx.) - Han Xin 1 to 4 (8%, 15%, 23%, 30%) (approx.) - Micro QR 1 to 3 (L, M, Q) + Aztec Code 1 to 4 (10%, 23%, 36%, 50%) + Grid Matrix 1 to 5 (10% to 50%) + Han Xin 1 to 4 (8%, 15%, 23%, 30%) + Micro QR 1 to 3 (7%, 15%, 25%) (L, M, Q) PDF417 0 to 8 (2^(INTEGER + 1) codewords) - QR Code 1 to 4 (L, M, Q, H) - rMQR 2 or 4 (M, H) - Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) (approx.) + QR Code 1 to 4 (7%, 15%, 25%, 30%) (L, M, Q, H) + rMQR 2 or 4 (15% or 30%) (M or H) + Ultracode 1 to 6 (0%, 5%, 9%, 17%, 25%, 33%) `--segN=ECI,DATA` -: Set the *ECI* & *DATA* content for segment N, where N is 1 to 9. `-d` or `--data` must still be given, and counts +: Set the *ECI* & *DATA* content for segment N, where N is 1 to 9. `-d` | `--data` must still be given, and counts as segment 0, its ECI given by `--eci`. Segments must be consecutive. `--separator=INTEGER` : Set the height of row separator bars for stacked symbologies, where *INTEGER* is in integral multiples of the - X-dimension. + X-dimension. The default is zero. `--small` @@ -309,13 +318,14 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S `--structapp=I,C[,ID]` -: Set Structured Append info, where `I` is the 1-based index, `C` is the count of total symbols in the sequence, and - `ID`, which is optional, is the identifier that all symbols in the sequence share. Structured Append is supported - by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, MaxiCode, MicroPDF417, PDF417, QR Code and Ultracode. +: Set Structured Append info, where `I` is the 1-based index, `C` is the total number of symbols in the sequence, + and `ID`, which is optional, is the identifier that all symbols in the sequence share. Structured Append is + supported by Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, MaxiCode, MicroPDF417, PDF417, QR Code and + Ultracode. `-t`, `--types` -: Display the table of barcode types (symbologies). The numbers or names can be used with `-b` or `--barcode`. +: Display the table of barcode types (symbologies). The numbers or names can be used with `-b` | `--barcode`. `--vers=INTEGER` @@ -341,13 +351,16 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S C25LOGIC ditto C25STANDARD ditto Codabar 1 or 2 (add hidden or visible check digit) - Code 11 0 or 1 (no or 1 check digit only) - (has 2 check digits by default) + Code 11 0 or 1 (no or 1 visible check digit only) + (default is 2 visible check digits) Code 39 1 (add visible check digit) Code 93 1 (hide the default check characters) EXCODE39 1 (add visible check digit) LOGMARS 1 (add visible check digit) - MSI Plessey 0 to 6 (various check digit options) + MSI Plessey 0 to 6 (none to various visible options) + 1, 2 (mod-10, mod-10 + mod-10) + 3, 4 (mod-11 IBM, mod-11 IBM + mod-10) + 5, 6 (mod-11 NCR, mod-11 NCR + mod-10) +10 (hide) For a few other symbologies, it specifies other characteristics: @@ -378,7 +391,7 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S # EXIT STATUS `0` -: Success (including when given informational options `-h`, `--help`, `-e`, `--ecinos`, `-t`, `--types`, `-v`, +: Success (including when given informational options `-h` | `--help`, `-e` | `--ecinos`, `-t` | `--types`, `-v` | `--version`). `2` @@ -454,15 +467,19 @@ http://zint.org.uk/Manual.aspx, and at https://sourceforge.net/p/zint/docs/manua Zint is designed to be compliant with a number of international standards, including: -EN 798:1996, EN 12323:2005, ISO/IEC 15420:2009, -ISO/IEC 15417:2007, ISO/IEC 15438:2015, ISO/IEC 16022:2006, -ISO/IEC 16023:2000, ISO/IEC 16388:2007, ISO/IEC 18004:2015, -ISO/IEC 20830:2021, ISO/IEC 24723:2010, ISO/IEC 24724:2011, -ISO/IEC 24728:2006, ISO/IEC 24778:2008, ISO/IEC 16390:2007, -ISO/IEC 21471:2019, AIM USS Code One (1994), ANSI/AIM BC12-1998, -ANSI/AIM BC6-2000, ANSI/AIM BC5-1995, AIM ISS-X-24 (1995), -AIMD014 (v 1.63) (2008), ANSI-HIBC 2.6-2016, AIM ITS/04-023 (2022) +ISO/IEC 24778:2008, ANSI/AIM BC12-1998, EN 798:1996, +AIM ISS-X-24 (1995), ISO/IEC 15417:2007, EN 12323:2005, +ISO/IEC 16388:2007, ANSI/AIM BC6-2000, ANSI/AIM BC5-1995, +AIM USS Code One (1994), ISO/IEC 16022:2006, ISO/IEC 21471:2019, +ISO/IEC 15420:2009, AIMD014 (v 1.63) (2008), ISO/IEC 24723:2010, +ISO/IEC 24724:2011, ISO/IEC 20830:2021, ISO/IEC 16390:2007, +ISO/IEC 16023:2000, ISO/IEC 24728:2006, ISO/IEC 15438:2015, +ISO/IEC 18004:2015, ISO/IEC 23941:2022, AIM ITS/04-023 (2022) -# AUTHORS +# COPYRIGHT + +Copyright © 2022 Robin Stuart. Released under GNU GPL 3.0 or later. + +# AUTHOR Robin Stuart diff --git a/frontend/main.c b/frontend/main.c index e1b1731c..fd5a4d8d 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #include #include @@ -126,7 +127,7 @@ static void usage(int no_png) { printf( "Encode input data in a barcode and save as BMP/EMF/EPS/GIF/PCX%s/SVG/TIF/TXT\n\n" " -b, --barcode=TYPE Number or name of barcode type. Default is 20 (CODE128)\n" - " --addongap=NUMBER Set add-on gap in multiples of X-dimension for UPC/EAN\n" + " --addongap=NUMBER Set add-on gap in multiples of X-dimension for EAN/UPC\n" " --batch Treat each line of input file as a separate data set\n" " --bg=COLOUR Specify a background colour (in hex RGB/RGBA)\n" " --binary Treat input as raw binary data\n" @@ -154,7 +155,7 @@ static void usage(int no_png) { " --gs1nocheck Do not check validity of GS1 data\n" " --gs1parens Process parentheses \"()\" as GS1 AI delimiters, not \"[]\"\n" " --gssep Use separator GS for GS1 (Data Matrix)\n" - " --guarddescent=NUMBER Set height of guard bar descent in X-dims (UPC/EAN)\n" + " --guarddescent=NUMBER Set height of guard bar descent in X-dims (EAN/UPC)\n" " -h, --help Display help message\n" " --height=NUMBER Set height of symbol in multiples of X-dimension\n" " --heightperrow Treat height as per-row\n" diff --git a/frontend_qt/CMakeLists.txt b/frontend_qt/CMakeLists.txt index 197b98a5..c906b415 100644 --- a/frontend_qt/CMakeLists.txt +++ b/frontend_qt/CMakeLists.txt @@ -32,7 +32,7 @@ endif() target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/backend" "${CMAKE_SOURCE_DIR}/backend_qt") target_link_libraries(${PROJECT_NAME} zint QZint - Qt${QT_VERSION_MAJOR}::UiTools Qt${QT_VERSION_MAJOR}::Xml Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::UiTools Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Core) diff --git a/frontend_qt/datawindow.cpp b/frontend_qt/datawindow.cpp index 91bfb3fd..499f3c74 100644 --- a/frontend_qt/datawindow.cpp +++ b/frontend_qt/datawindow.cpp @@ -1,6 +1,6 @@ /* Zint Barcode Generator - the open source barcode generator - Copyright (C) 2009 - 2021 Robin Stuart + Copyright (C) 2009-2022 Robin Stuart This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: GPL-3.0-or-later */ //#include #include @@ -33,7 +33,8 @@ static const int tempMessageTimeout = 2000; -DataWindow::DataWindow(const QString &input, bool isEscaped) : Valid(false), Escaped(false) +DataWindow::DataWindow(const QString &input, bool isEscaped, int seg_no) : Valid(false), Escaped(false), + m_isEscaped(isEscaped), m_seg_no(seg_no) { setupUi(this); QSettings settings; @@ -45,7 +46,7 @@ DataWindow::DataWindow(const QString &input, bool isEscaped) : Valid(false), Esc restoreGeometry(geometry); QIcon closeIcon(QIcon::fromTheme(QSL("window-close"), QIcon(QSL(":res/x.svg")))); - QIcon clearIcon(QIcon::fromTheme(QSL("edit-clear"), QIcon(QSL(":res/delete.svg")))); + QIcon clearIcon(QSL(":res/delete.svg")); QIcon okIcon(QIcon(QSL(":res/check.svg"))); btnCancel->setIcon(closeIcon); btnDataClear->setIcon(clearIcon); @@ -56,7 +57,8 @@ DataWindow::DataWindow(const QString &input, bool isEscaped) : Valid(false), Esc QString out; out.reserve(input.length()); int lastPosn = 0; - QRegularExpression escRE(QSL("\\\\(?:[0EabtnvfreGR\\\\]|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})")); + QRegularExpression escRE(QSL("\\\\(?:[0EabtnvfreGR\\\\]|d[0-9]{3}|o[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}" + "|U[0-9A-Fa-f]{6})")); QRegularExpressionMatchIterator matchI = escRE.globalMatch(input); while (matchI.hasNext()) { QRegularExpressionMatch match = matchI.next(); @@ -77,6 +79,9 @@ DataWindow::DataWindow(const QString &input, bool isEscaped) : Valid(false), Esc connect(btnDataClear, SIGNAL( clicked( bool )), SLOT(clear_data())); connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); connect(btnFromFile, SIGNAL( clicked( bool )), SLOT(from_file())); + connect(txtDataInput, SIGNAL( textChanged() ), this, SLOT(text_changed())); + + btnDataClear->setEnabled(!txtDataInput->toPlainText().isEmpty()); } DataWindow::~DataWindow() @@ -93,18 +98,32 @@ void DataWindow::clear_data() txtDataInput->clear(); } +void DataWindow::text_changed() +{ + bool escaped = m_isEscaped; + const QString &text = escapedData(escaped); + btnDataClear->setEnabled(!text.isEmpty()); + emit dataChanged(text, escaped, m_seg_no); +} + void DataWindow::okay() { Valid = true; - DataOutput = txtDataInput->toPlainText(); - if (DataOutput.contains('\n')) { - // Escape Line Feeds - DataOutput.replace('\n', QSL("\\n")); - Escaped = true; - } + DataOutput = escapedData(Escaped); close(); } +QString DataWindow::escapedData(bool &escaped) +{ + QString text = txtDataInput->toPlainText(); + if (text.contains('\n')) { + // Escape Line Feeds + text.replace('\n', QSL("\\n")); + escaped = true; + } + return text; +} + void DataWindow::from_file() { QSettings settings; @@ -160,3 +179,5 @@ void DataWindow::from_file() settings.setValue("studio/default_dir", filename.mid(0, filename.lastIndexOf(QDir::separator()))); } + +/* vim: set ts=4 sw=4 et : */ diff --git a/frontend_qt/datawindow.h b/frontend_qt/datawindow.h index c1803e04..714003dd 100644 --- a/frontend_qt/datawindow.h +++ b/frontend_qt/datawindow.h @@ -1,6 +1,6 @@ /* Zint Barcode Generator - the open source barcode generator - Copyright (C) 2009-2021 Robin Stuart + Copyright (C) 2009-2022 Robin Stuart This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef DATAWINDOW_H #define DATAWINDOW_H @@ -28,17 +28,28 @@ class DataWindow : public QDialog, private Ui::DataDialog Q_OBJECT public: - DataWindow(const QString &input, bool isEscaped); + DataWindow(const QString &input, bool isEscaped, int seg_no); ~DataWindow(); bool Valid; bool Escaped; QString DataOutput; +signals: + void dataChanged(const QString& text, bool escaped, int seg_no); + private slots: void clear_data(); + void text_changed(); void okay(); void from_file(); + +private: + QString escapedData(bool &escaped); + + bool m_isEscaped; + int m_seg_no; }; +/* vim: set ts=4 sw=4 et : */ #endif diff --git a/frontend_qt/mainWindow.ui b/frontend_qt/mainWindow.ui index 7725ead5..c4708cff 100644 --- a/frontend_qt/mainWindow.ui +++ b/frontend_qt/mainWindow.ui @@ -21,8 +21,8 @@ - 400 - 435 + 425 + 440 @@ -47,7 +47,7 @@ 0 - 10 + 5 @@ -57,6 +57,9 @@ + + false + QFrame::StyledPanel @@ -66,9 +69,6 @@ Qt::Horizontal - - false - Qt::CustomContextMenu @@ -149,13 +149,13 @@ 0 - 325 + 346 16777215 - 325 + 346 @@ -180,12 +180,12 @@ 0 - - Data to Enc&ode - Input data + + Data to Enc&ode + @@ -217,19 +217,19 @@ or import from file - - - Encode a sequence - - - 123&4.. - + - 60 + 22 16777215 + + Clear data and ECI (segment 0) + + + + @@ -267,13 +267,13 @@ or import from file 0 - - 34 - Set the ECI (Extended Channel Interpretation) code (ignored if disabled) + + 34 + None @@ -473,6 +473,39 @@ or import from file + + + + + 60 + 16777215 + + + + Encode a sequence + + + 123&4.. + + + + + + + + 22 + 16777215 + + + + Clear all data and ECIs and reset all settings +for this symbology to defaults + + + + + + @@ -501,12 +534,12 @@ or import from file 400 - - Composite Code - GS1 Composite symbol settings + + Composite Code + @@ -588,26 +621,49 @@ or import from file - + QLayout::SetMinimumSize - - - false - - - Data to be encoded in 2D component + + + + + false + + + Data to be encoded in 2D component Remember to place [square brackets] around AI identifiers - - - 2D Co&mponent Data: - - - txtComposite - - + + + 2D Co&mponent Data + + + txtComposite + + + + + + + false + + + + 22 + 16777215 + + + + Clear 2D Component data + + + + + + + @@ -660,13 +716,13 @@ Remember to place [square brackets] around AI identifiers 400 - - Additional ECI/Data Segments - Additional data segments with their own Extended Channel Interpretation (ECI) + + Additional ECI/Data Segments + @@ -700,12 +756,12 @@ Extended Channel Interpretation (ECI) 16777215 - - 34 - ECI for segment 1 + + 34 + None @@ -890,7 +946,7 @@ Extended Channel Interpretation (ECI) Data for segment 1 - + @@ -911,6 +967,22 @@ or import from file + + + + + 22 + 16777215 + + + + Clear segment 1 data and ECI + + + + + + @@ -945,12 +1017,12 @@ or import from file 16777215 - - 34 - ECI for segment 2 + + 34 + None @@ -1135,7 +1207,7 @@ or import from file Data for segment 2 - + @@ -1156,6 +1228,22 @@ or import from file + + + + + 22 + 16777215 + + + + Clear segment 2 data and ECI + + + + + + @@ -1190,12 +1278,12 @@ or import from file 16777215 - - 34 - ECI for segment 3 + + 34 + None @@ -1380,7 +1468,7 @@ or import from file Data for segment 3 - + @@ -1401,6 +1489,22 @@ or import from file + + + + + 22 + 16777215 + + + + Clear segment 3 data and ECI + + + + + + @@ -1451,8 +1555,10 @@ or import from file <tr><td>\G&nbsp;</td><td>Group Separator (0x1D)</td></tr> <tr><td>\R&nbsp;</td><td>Record Separator (0x1E)</td></tr> <tr><td>\\&nbsp;</td><td>Backslash (0x5C)</td></tr> +<tr><td>\dNNN&nbsp;</td><td>8-bit character (N decimal)</td></tr> <tr><td>\xNN&nbsp;</td><td>8-bit character (N hex)</td></tr> -<tr><td>\uNNNN&nbsp;</td><td>16-bit Unicode (N hex)</td></tr> +<tr><td>\uNNNN&nbsp;</td><td>16-bit Unicode BMP (N hex)</td></tr> +<tr><td>\UNNNNNN&nbsp;</td><td>20-bit Unicode (N hex)</td></tr> </table> @@ -1841,60 +1947,159 @@ in X-dimensions true - Change colour of ink or paper + Change colour of ink - Colour: + &Foreground: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - fgcolor + txt_fgcolor - - - Change ink colour + + + + 100 + 16777215 + - - &Foreground + + Change ink colour, format +is hexadecimal "RRGGBB" +or "RRGGBBAA" (alpha) + + + 8 - - - - false + + + + + 22 + 16777215 + + + + Change ink colour using picker - - + + + + true + - Change paper colour + Change colour of paper - Back&ground + Back&ground: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + txt_bgcolor + + + + + + + + 100 + 16777215 + + + + Change paper colour, format +is hexadecimal "RRGGBB" +or "RRGGBBAA" (alpha) + + + 8 + + + + + + + + 22 + 16777215 + + + + Change paper colour using picker + + + + + + + + + + true + + + Reset or reverse colours + + + Colours: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + btnReset + + + 100 + 16777215 + + - Reset to black on white + Reset colours to black on white &Reset - + + + + + 22 + 16777215 + + + + Swap foreground and background colours +(reflectance reversal) + + + + + + + Use CMYK colour space in EPS/TIF output @@ -1907,7 +2112,7 @@ in X-dimensions - + Add compliant quiet zones to whitespace @@ -1937,7 +2142,7 @@ in X-dimensions - + Rotate symbol by degrees @@ -1964,7 +2169,7 @@ in X-dimensions - + Use dots instead of squares for matrix symbols @@ -1998,7 +2203,7 @@ in X-dimensions - + false @@ -2051,15 +2256,15 @@ in X-dimensions - - false - - 40 - 20 + 2 + 22 + + false + diff --git a/frontend_qt/mainwindow.cpp b/frontend_qt/mainwindow.cpp index a22ee909..39aaf2df 100644 --- a/frontend_qt/mainwindow.cpp +++ b/frontend_qt/mainwindow.cpp @@ -13,6 +13,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ //#include #include @@ -55,6 +56,10 @@ static const QKeySequence copyPNGSeq(Qt::SHIFT | Qt::CTRL | Qt::Key_P); static const QKeySequence copySVGSeq(Qt::SHIFT | Qt::CTRL | Qt::Key_S); static const QKeySequence copyTIFSeq(Qt::SHIFT | Qt::CTRL | Qt::Key_T); +static const QKeySequence factoryResetSeq(Qt::SHIFT | Qt::CTRL | Qt::Key_R); + +static const QRegularExpression colorRE(QSL("^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$")); + struct bstyle_item { const QString text; int symbology; @@ -159,14 +164,19 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) restoreGeometry(settings.value(QSL("studio/window_geometry")).toByteArray()); - m_fgcolor.setRgb(settings.value(QSL("studio/ink/red"), 0).toInt(), - settings.value(QSL("studio/ink/green"), 0).toInt(), - settings.value(QSL("studio/ink/blue"), 0).toInt(), - settings.value(QSL("studio/ink/alpha"), 0xff).toInt()); - m_bgcolor.setRgb(settings.value(QSL("studio/paper/red"), 0xff).toInt(), - settings.value(QSL("studio/paper/green"), 0xff).toInt(), - settings.value(QSL("studio/paper/blue"), 0xff).toInt(), - settings.value(QSL("studio/paper/alpha"), 0xff).toInt()); + m_fgcolor_geometry = settings.value(QSL("studio/fgcolor_geometry")).toByteArray(); + m_bgcolor_geometry = settings.value(QSL("studio/bgcolor_geometry")).toByteArray(); + + fgcolor->setIcon(QIcon(QSL(":res/black-eye.svg"))); + bgcolor->setIcon(QIcon(QSL(":res/white-eye.svg"))); + btnReverse->setIcon(QIcon(QSL(":res/shuffle.svg"))); + + QRegularExpressionValidator *colorValidator = new QRegularExpressionValidator(colorRE, this); + txt_fgcolor->setValidator(colorValidator); + txt_bgcolor->setValidator(colorValidator); + + connect(txt_fgcolor, SIGNAL(textEdited(QString)), this, SLOT(fgcolor_edited())); + connect(txt_bgcolor, SIGNAL(textEdited(QString)), this, SLOT(bgcolor_edited())); const int cnt = (int) (sizeof(bstyle_items) / sizeof(bstyle_items[0])); for (int i = 0; i < cnt; i++) { @@ -182,34 +192,15 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) bstyle->setCurrentIndex(settings.value(QSL("studio/symbology"), 10).toInt()); - txtData->setText(settings.value(QSL("studio/data"), tr("Your Data Here!")).toString()); - /* Don't save seg data */ - txtComposite->setText(settings.value(QSL("studio/composite_text"), tr("Your Data Here!")).toString()); - chkComposite->setChecked(settings.value(QSL("studio/chk_composite")).toInt() ? true : false); - cmbCompType->setCurrentIndex(settings.value(QSL("studio/comp_type"), 0).toInt()); - cmbECI->setCurrentIndex(settings.value(QSL("studio/eci"), 0).toInt()); - /* Don't save seg ECIs */ - chkEscape->setChecked(settings.value(QSL("studio/chk_escape")).toInt() ? true : false); - chkData->setChecked(settings.value(QSL("studio/chk_data")).toInt() ? true : false); - chkRInit->setChecked(settings.value(QSL("studio/chk_rinit")).toInt() ? true : false); - chkGS1Parens->setChecked(settings.value(QSL("studio/chk_gs1parens")).toInt() ? true : false); - chkGS1NoCheck->setChecked(settings.value(QSL("studio/chk_gs1nocheck")).toInt() ? true : false); - chkAutoHeight->setChecked(settings.value(QSL("studio/appearance/autoheight"), 1).toInt() ? true : false); - chkCompliantHeight->setChecked( - settings.value(QSL("studio/appearance/compliantheight"), 1).toInt() ? true : false); - heightb->setValue(settings.value(QSL("studio/appearance/height"), 50.0f).toFloat()); - bwidth->setValue(settings.value(QSL("studio/appearance/border"), 0).toInt()); - spnWhitespace->setValue(settings.value(QSL("studio/appearance/whitespace"), 0).toInt()); - spnVWhitespace->setValue(settings.value(QSL("studio/appearance/vwhitespace"), 0).toInt()); - spnScale->setValue(settings.value(QSL("studio/appearance/scale"), 1.0).toFloat()); - btype->setCurrentIndex(settings.value(QSL("studio/appearance/border_type"), 0).toInt()); - cmbFontSetting->setCurrentIndex(settings.value(QSL("studio/appearance/font_setting"), 0).toInt()); - chkHRTShow->setChecked(settings.value(QSL("studio/appearance/chk_hrt_show"), 1).toInt() ? true : false); - chkCMYK->setChecked(settings.value(QSL("studio/appearance/chk_cmyk"), 0).toInt() ? true : false); - chkQuietZones->setChecked(settings.value(QSL("studio/appearance/chk_quiet_zones"), 0).toInt() ? true : false); - cmbRotate->setCurrentIndex(settings.value(QSL("studio/appearance/rotate"), 0).toInt()); - chkDotty->setChecked(settings.value(QSL("studio/appearance/chk_dotty"), 0).toInt() ? true : false); - spnDotSize->setValue(settings.value(QSL("studio/appearance/dot_size"), 4.0 / 5.0).toFloat()); + load_settings(settings); + + QIcon clearIcon(QSL(":res/delete.svg")); + btnClearData->setIcon(clearIcon); + btnClearDataSeg1->setIcon(clearIcon); + btnClearDataSeg2->setIcon(clearIcon); + btnClearDataSeg3->setIcon(clearIcon); + btnClearComposite->setIcon(clearIcon); + btnZap->setIcon(QIcon(QSL(":res/zap.svg"))); change_options(); @@ -222,6 +213,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) connect(bwidth, SIGNAL(valueChanged( int )), SLOT(update_preview())); connect(btype, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbFontSetting, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(txtData, SIGNAL(textChanged( const QString& )), SLOT(data_ui_set())); connect(txtData, SIGNAL(textChanged( const QString& )), SLOT(update_preview())); connect(txtDataSeg1, SIGNAL(textChanged( const QString& )), SLOT(data_ui_set())); connect(txtDataSeg1, SIGNAL(textChanged( const QString& )), SLOT(update_preview())); @@ -233,6 +225,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) connect(chkComposite, SIGNAL(toggled( bool )), SLOT(composite_ui_set())); connect(chkComposite, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(cmbCompType, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(btnClearComposite, SIGNAL(clicked( bool )), SLOT(clear_composite())); connect(cmbECI, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbECISeg1, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbECISeg2, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); @@ -249,11 +242,17 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) connect(spnScale, SIGNAL(valueChanged( double )), SLOT(change_print_scale())); connect(btnExit, SIGNAL(clicked( bool )), SLOT(quit_now())); connect(btnReset, SIGNAL(clicked( bool )), SLOT(reset_colours())); + connect(btnReverse, SIGNAL(clicked( bool )), SLOT(reverse_colours())); connect(btnMoreData, SIGNAL(clicked( bool )), SLOT(open_data_dialog())); connect(btnMoreDataSeg1, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg1())); connect(btnMoreDataSeg2, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg2())); connect(btnMoreDataSeg3, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg3())); + connect(btnClearData, SIGNAL(clicked( bool )), SLOT(clear_data())); + connect(btnClearDataSeg1, SIGNAL(clicked( bool )), SLOT(clear_data_seg1())); + connect(btnClearDataSeg2, SIGNAL(clicked( bool )), SLOT(clear_data_seg2())); + connect(btnClearDataSeg3, SIGNAL(clicked( bool )), SLOT(clear_data_seg3())); connect(btnSequence, SIGNAL(clicked( bool )), SLOT(open_sequence_dialog())); + connect(btnZap, SIGNAL(clicked( bool )), SLOT(zap())); connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(autoheight_ui_set())); connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkCompliantHeight, SIGNAL(toggled( bool )), SLOT(update_preview())); @@ -295,6 +294,9 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) m_copyTIFShortcut = new QShortcut(copyTIFSeq, this); connect(m_copyTIFShortcut, SIGNAL(activated()), SLOT(copy_to_clipboard_tif())); + m_factoryResetShortcut = new QShortcut(factoryResetSeq, this); + connect(m_factoryResetShortcut, SIGNAL(activated()), SLOT(factory_reset())); + QShortcut *helpShortcut = new QShortcut(QKeySequence::HelpContents, this); connect(helpShortcut, SIGNAL(activated()), SLOT(help())); QShortcut *quitShortcut = new QShortcut(quitKeySeq, this); @@ -305,6 +307,8 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl) bstyle->setFocus(); tabMain->installEventFilter(this); + txt_fgcolor->installEventFilter(this); + txt_bgcolor->installEventFilter(this); } MainWindow::~MainWindow() @@ -315,6 +319,8 @@ MainWindow::~MainWindow() #endif settings.setValue(QSL("studio/window_geometry"), saveGeometry()); + settings.setValue(QSL("studio/fgcolor_geometry"), m_fgcolor_geometry); + settings.setValue(QSL("studio/bgcolor_geometry"), m_bgcolor_geometry); settings.setValue(QSL("studio/tab_index"), tabMain->currentIndex()); settings.setValue(QSL("studio/symbology"), bstyle->currentIndex()); settings.setValue(QSL("studio/ink/red"), m_fgcolor.red()); @@ -356,6 +362,50 @@ MainWindow::~MainWindow() save_sub_settings(settings, m_bc.bc.symbol()); } +void MainWindow::load_settings(QSettings &settings) +{ + bool initial_load = m_symbology == 0; + QString initialData(initial_load ? tr("Your Data Here!") : ""); + + m_fgcolor.setRgb(settings.value(QSL("studio/ink/red"), 0).toInt(), + settings.value(QSL("studio/ink/green"), 0).toInt(), + settings.value(QSL("studio/ink/blue"), 0).toInt(), + settings.value(QSL("studio/ink/alpha"), 0xff).toInt()); + m_bgcolor.setRgb(settings.value(QSL("studio/paper/red"), 0xff).toInt(), + settings.value(QSL("studio/paper/green"), 0xff).toInt(), + settings.value(QSL("studio/paper/blue"), 0xff).toInt(), + settings.value(QSL("studio/paper/alpha"), 0xff).toInt()); + + txtData->setText(settings.value(QSL("studio/data"), initialData).toString()); + /* Don't save seg data */ + txtComposite->setText(settings.value(QSL("studio/composite_text"), initialData).toString()); + chkComposite->setChecked(settings.value(QSL("studio/chk_composite")).toInt() ? true : false); + cmbCompType->setCurrentIndex(settings.value(QSL("studio/comp_type"), 0).toInt()); + cmbECI->setCurrentIndex(settings.value(QSL("studio/eci"), 0).toInt()); + /* Don't save seg ECIs */ + chkEscape->setChecked(settings.value(QSL("studio/chk_escape")).toInt() ? true : false); + chkData->setChecked(settings.value(QSL("studio/chk_data")).toInt() ? true : false); + chkRInit->setChecked(settings.value(QSL("studio/chk_rinit")).toInt() ? true : false); + chkGS1Parens->setChecked(settings.value(QSL("studio/chk_gs1parens")).toInt() ? true : false); + chkGS1NoCheck->setChecked(settings.value(QSL("studio/chk_gs1nocheck")).toInt() ? true : false); + chkAutoHeight->setChecked(settings.value(QSL("studio/appearance/autoheight"), 1).toInt() ? true : false); + chkCompliantHeight->setChecked( + settings.value(QSL("studio/appearance/compliantheight"), 1).toInt() ? true : false); + heightb->setValue(settings.value(QSL("studio/appearance/height"), 50.0f).toFloat()); + bwidth->setValue(settings.value(QSL("studio/appearance/border"), 0).toInt()); + spnWhitespace->setValue(settings.value(QSL("studio/appearance/whitespace"), 0).toInt()); + spnVWhitespace->setValue(settings.value(QSL("studio/appearance/vwhitespace"), 0).toInt()); + spnScale->setValue(settings.value(QSL("studio/appearance/scale"), 1.0).toFloat()); + btype->setCurrentIndex(settings.value(QSL("studio/appearance/border_type"), 0).toInt()); + cmbFontSetting->setCurrentIndex(settings.value(QSL("studio/appearance/font_setting"), 0).toInt()); + chkHRTShow->setChecked(settings.value(QSL("studio/appearance/chk_hrt_show"), 1).toInt() ? true : false); + chkCMYK->setChecked(settings.value(QSL("studio/appearance/chk_cmyk"), 0).toInt() ? true : false); + chkQuietZones->setChecked(settings.value(QSL("studio/appearance/chk_quiet_zones"), 0).toInt() ? true : false); + cmbRotate->setCurrentIndex(settings.value(QSL("studio/appearance/rotate"), 0).toInt()); + chkDotty->setChecked(settings.value(QSL("studio/appearance/chk_dotty"), 0).toInt() ? true : false); + spnDotSize->setValue(settings.value(QSL("studio/appearance/dot_size"), 4.0 / 5.0).toFloat()); +} + QString MainWindow::get_zint_version(void) { QString zint_version; @@ -410,6 +460,14 @@ bool MainWindow::eventFilter(QObject *watched, QEvent *event) } } + if ((watched == txt_fgcolor || watched == txt_bgcolor) && event->type() == QEvent::FocusOut) { + if (watched == txt_fgcolor) { + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + } else { + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + } + } + return QWidget::eventFilter(watched, event); } @@ -417,9 +475,38 @@ void MainWindow::reset_colours() { m_fgcolor.setRgb(0, 0, 0, 0xff); m_bgcolor.setRgb(0xff, 0xff, 0xff, 0xff); + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); update_preview(); } +void MainWindow::reverse_colours() +{ + QColor temp = m_fgcolor; + m_fgcolor = m_bgcolor; + m_bgcolor = temp; + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + update_preview(); +} + +QString MainWindow::getColorStr(const QColor color, bool alpha_always) { + QString ret; + if (color.alpha() != 0xFF || alpha_always) { + ret = QString::asprintf("%02X%02X%02X%02X", color.red(), color.green(), color.blue(), color.alpha()); + } else { + ret = QString::asprintf("%02X%02X%02X", color.red(), color.green(), color.blue()); + } + return ret; +} + +void MainWindow::setColorTxtBtn(const QColor color, QLineEdit *txt, QPushButton* btn) { + int cursorPos = txt->cursorPosition(); + txt->setText(getColorStr(color)); + txt->setCursorPosition(cursorPos); + btn->setStyleSheet(QSL("QPushButton {background-color:") + color.name() + QSL(";}")); +} + bool MainWindow::save() { QSettings settings; @@ -513,6 +600,37 @@ bool MainWindow::save() return true; } +void MainWindow::factory_reset() +{ + QMessageBox msgBox(QMessageBox::Question, tr("Factory Reset"), + tr("This will clear all saved data and reset all settings for all symbologies to defaults."), + QMessageBox::Yes | QMessageBox::No, this); + msgBox.setInformativeText(tr("Do you want to continue?")); + msgBox.setDefaultButton(QMessageBox::Yes); + if (msgBox.exec() == QMessageBox::No) { + return; + } + + QSettings settings; +#if QT_VERSION < 0x60000 + settings.setIniCodec("UTF-8"); +#endif + settings.clear(); + + int symbology = bstyle_items[bstyle->currentIndex()].symbology; + + load_settings(settings); + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + + load_sub_settings(settings, symbology); + + settings.sync(); + + txtData->setFocus(Qt::OtherFocusReason); + update_preview(); +} + void MainWindow::about() { QString zint_version = get_zint_version(); @@ -522,24 +640,25 @@ void MainWindow::about() tr("

Zint Barcode Studio %1

" "

A free barcode generator

" "

Instruction manual is available at the project homepage:
" - "http://www.zint.org.uk" + "http://www.zint.org.uk.

" "

Copyright © 2006-2022 Robin Stuart and others.
" - "Qt backend by BogDan Vatra

" + "Qt backend by BogDan Vatra.
" + "Released under GNU GPL 3.0 or later.

" "

Qt version %2

" + "

\"QR Code\" is a Registered Trademark of Denso Corp.
" + "\"Telepen\" is a Registered Trademark of SB Electronics.
" + "\"Mailmark\" is a Registered Trademark of Royal Mail.

" "

With thanks to Harald Oehlmann, Norbert Szabó, Robert Elliott, Milton Neal, " "Git Lost, Alonso Schaich, Andre Maute and many others at Sourceforge.

" - "

Released under the GNU General Public License ver. 3 or later.
" - "\"QR Code\" is a Registered Trademark of Denso Corp.
" - "\"Telepen\" is a Registered Trademark of SB Electronics.

" "

Currently supported standards include:
" - "EN 798:1996, EN 12323:2005, ISO/IEC 15420:2009,
" - "ISO/IEC 15417:2007, ISO/IEC 15438:2015, ISO/IEC 16022:2006,
" - "ISO/IEC 16023:2000, ISO/IEC 16388:2007, ISO/IEC 18004:2015,
" - "ISO/IEC 20830:2021, ISO/IEC 24723:2010, ISO/IEC 24724:2011,
" - "ISO/IEC 24728:2006, ISO/IEC 24778:2008, ISO/IEC 16390:2007,
" - "ISO/IEC 21471:2019, AIM USS Code One (1994), ANSI-HIBC 2.6-2016,
" - "ANSI/AIM BC12-1998, ANSI/AIM BC6-2000, ANSI/AIM BC5-1995,
" - "AIM ISS-X-24, AIMD014 (v 1.63), AIM ITS/04-023 (2022)" + "ISO/IEC 24778:2008, ANSI/AIM BC12-1998, EN 798:1996,
" + "AIM ISS-X-24 (1995), ISO/IEC 15417:2007, EN 12323:2005,
" + "ISO/IEC 16388:2007, ANSI/AIM BC6-2000, ANSI/AIM BC5-1995,
" + "AIM USS Code One (1994), ISO/IEC 16022:2006, ISO/IEC 21471:2019,
" + "ISO/IEC 15420:2009, AIMD014 (v 1.63) (2008), ISO/IEC 24723:2010,
" + "ISO/IEC 24724:2011, ISO/IEC 20830:2021, ISO/IEC 16390:2007,
" + "ISO/IEC 16023:2000, ISO/IEC 24728:2006, ISO/IEC 15438:2015,
" + "ISO/IEC 18004:2015, ISO/IEC 23941:2022, AIM ITS/04-023 (2022)" "

").arg(zint_version).arg(QT_VERSION_STR)); } @@ -548,19 +667,86 @@ void MainWindow::help() QDesktopServices::openUrl(QSL("https://zint.org.uk/manual")); // TODO: manual.md } +QLineEdit *MainWindow::get_seg_textbox(int seg_no) +{ + static QLineEdit *textboxes[4] = { + txtData, txtDataSeg1, txtDataSeg2, txtDataSeg3 + }; + return textboxes[seg_no]; +} + +QComboBox *MainWindow::get_seg_eci(int seg_no) +{ + static QComboBox *ecis[4] = { + cmbECI, cmbECISeg1, cmbECISeg2, cmbECISeg3 + }; + return ecis[seg_no]; +} + +void MainWindow::clear_data() +{ + if (clear_data_eci_seg(0)) { + update_preview(); + } +} + +void MainWindow::clear_data_seg1() +{ + if (clear_data_eci_seg(1)) { + update_preview(); + } +} + +void MainWindow::clear_data_seg2() +{ + if (clear_data_eci_seg(2)) { + update_preview(); + } +} + +void MainWindow::clear_data_seg3() +{ + if (clear_data_eci_seg(3)) { + update_preview(); + } +} + +bool MainWindow::clear_data_eci_seg(int seg_no) +{ + QLineEdit *txt = get_seg_textbox(seg_no); + QComboBox *cmb = get_seg_eci(seg_no); + if (!txt->text().isEmpty() || cmb->currentIndex() != 0) { + txt->clear(); + cmb->setCurrentIndex(0); + txt->setFocus(Qt::OtherFocusReason); + return true; + } + return false; +} + +void MainWindow::clear_composite() +{ + if (!txtComposite->toPlainText().isEmpty()) { + txtComposite->clear(); + update_preview(); + } +} + void MainWindow::open_data_dialog_seg(const int seg_no) { if (seg_no < 0 || seg_no > 3) { return; } - static QLineEdit *edits[4] = { - txtData, txtDataSeg1, txtDataSeg2, txtDataSeg3 - }; - DataWindow dlg(edits[seg_no]->text(), chkEscape->isChecked()); + QLineEdit *seg_textbox = get_seg_textbox(seg_no); + QString originalText = seg_textbox->text(); + bool originalChkEscape = chkEscape->isChecked(); + DataWindow dlg(originalText, originalChkEscape, seg_no); + connect(&dlg, SIGNAL(dataChanged(const QString&, bool, int)), this, + SLOT(on_dataChanged(const QString&, bool, int))); (void) dlg.exec(); if (dlg.Valid) { - const bool updated = edits[seg_no]->text() != dlg.DataOutput; - edits[seg_no]->setText(dlg.DataOutput); + const bool updated = originalText != dlg.DataOutput; + seg_textbox->setText(dlg.DataOutput); if (updated) { static const QString updatedEscTxts[4] = { tr("Set \"Parse Escapes\", updated data"), @@ -574,14 +760,20 @@ void MainWindow::open_data_dialog_seg(const int seg_no) tr("Updated segment 2 data"), tr("Updated segment 3 data"), }; - if (dlg.Escaped && !chkEscape->isChecked()) { + if (dlg.Escaped && !originalChkEscape) { chkEscape->setChecked(true); statusBar->showMessage(updatedEscTxts[seg_no], tempMessageTimeout); } else { + chkEscape->setChecked(originalChkEscape); statusBar->showMessage(updatedTxts[seg_no], tempMessageTimeout); } } + } else { + seg_textbox->setText(originalText); // Restore + chkEscape->setChecked(originalChkEscape); } + disconnect(&dlg, SIGNAL(dataChanged(const QString&, bool, int)), this, + SLOT(on_dataChanged(const QString&, bool, int))); } void MainWindow::open_data_dialog() @@ -614,6 +806,35 @@ void MainWindow::open_sequence_dialog() #endif } +void MainWindow::zap() +{ + QSettings settings; +#if QT_VERSION < 0x60000 + settings.setIniCodec("UTF-8"); +#endif + settings.clear(); + + int symbology = bstyle_items[bstyle->currentIndex()].symbology; + + load_settings(settings); + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + + load_sub_settings(settings, symbology); + + txtData->setFocus(Qt::OtherFocusReason); + update_preview(); +} + +void MainWindow::on_dataChanged(const QString& text, bool escaped, int seg_no) +{ + QLineEdit *seg_textbox = get_seg_textbox(seg_no); + + chkEscape->setChecked(escaped); + seg_textbox->setText(text); + update_preview(); +} + void MainWindow::open_cli_dialog() { CLIWindow dlg(&m_bc, chkAutoHeight->isEnabled() && chkAutoHeight->isChecked(), @@ -624,26 +845,86 @@ void MainWindow::open_cli_dialog() void MainWindow::on_fgcolor_clicked() { - QColor temp = m_fgcolor; - m_fgcolor = QColorDialog::getColor(m_fgcolor, this, tr("Set foreground colour"), - QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel); - if (m_fgcolor.isValid()) { - update_preview(); - } else { - m_fgcolor = temp; - } + color_clicked(m_fgcolor, txt_fgcolor, fgcolor, tr("Set foreground colour"), m_fgcolor_geometry, + SLOT(fgcolor_changed(const QColor&))); } void MainWindow::on_bgcolor_clicked() { - QColor temp = m_bgcolor; - m_bgcolor = QColorDialog::getColor(m_bgcolor, this, tr("Set background colour"), - QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel); - if (m_bgcolor.isValid()) { - update_preview(); + color_clicked(m_bgcolor, txt_bgcolor, bgcolor, tr("Set background colour"), m_bgcolor_geometry, + SLOT(bgcolor_changed(const QColor&))); +} + +void MainWindow::color_clicked(QColor &color, QLineEdit *txt, QPushButton *btn, const QString& title, + QByteArray& geometry, const char *color_changed) +{ + QColor original = color; + + QColorDialog color_dialog(nullptr /*parent*/); + color_dialog.setWindowTitle(title); + color_dialog.setOptions(QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel); + color_dialog.setCurrentColor(color); + color_dialog.restoreGeometry(geometry); + connect(&color_dialog, SIGNAL(currentColorChanged(const QColor &)), this, color_changed); + + if (color_dialog.exec() && color_dialog.selectedColor().isValid()) { + color = color_dialog.selectedColor(); } else { - m_bgcolor = temp; + color = original; } + geometry = color_dialog.saveGeometry(); + disconnect(&color_dialog, SIGNAL(currentColorChanged(const QColor &)), this, color_changed); + + setColorTxtBtn(color, txt, btn); + update_preview(); +} + +void MainWindow::fgcolor_changed(const QColor& color) +{ + if (color.isValid()) { + m_fgcolor = color; + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + update_preview(); + } +} + +void MainWindow::bgcolor_changed(const QColor& color) +{ + if (color.isValid()) { + m_bgcolor = color; + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + update_preview(); + } +} + +void MainWindow::fgcolor_edited() +{ + color_edited(m_fgcolor, txt_fgcolor, fgcolor); +} + +void MainWindow::bgcolor_edited() +{ + color_edited(m_bgcolor, txt_bgcolor, bgcolor); +} + +void MainWindow::color_edited(QColor &color, QLineEdit *txt, QPushButton *btn) +{ + QColor new_color; + QString new_text = txt->text().trimmed(); + if (new_text.indexOf(colorRE) != 0) { + return; + } + int r = new_text.mid(0, 2).toInt(nullptr, 16); + int g = new_text.mid(2, 2).toInt(nullptr, 16); + int b = new_text.mid(4, 2).toInt(nullptr, 16); + int a = new_text.length() == 8 ? new_text.mid(6, 2).toInt(nullptr, 16) : 0xFF; + new_color.setRgb(r, g, b, a); + if (!new_color.isValid()) { + return; + } + color = new_color; + setColorTxtBtn(color, txt, btn); + update_preview(); } void MainWindow::autoheight_ui_set() @@ -1063,6 +1344,9 @@ void MainWindow::change_options() m_btnHeightPerRowDisable = nullptr; m_btnHeightPerRowDefault = nullptr; + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + if (symbology == BARCODE_CODE128) { QFile file(QSL(":/grpC128.ui")); if (!file.open(QIODevice::ReadOnly)) @@ -1671,6 +1955,9 @@ void MainWindow::change_options() chkQuietZones->setEnabled(!m_bc.bc.hasDefaultQuietZones(symbology)); chkDotty->setEnabled(m_bc.bc.isDotty(symbology)); + setColorTxtBtn(m_fgcolor, txt_fgcolor, fgcolor); + setColorTxtBtn(m_bgcolor, txt_bgcolor, bgcolor); + data_ui_set(); composite_ui_set(); autoheight_ui_set(); @@ -1693,37 +1980,72 @@ void MainWindow::data_ui_set() if (grpSegs->isHidden()) { return; } - if (txtDataSeg1->text().isEmpty()) { + + if (txtData->text().isEmpty()) { + lblSeg1->setEnabled(false); cmbECISeg1->setEnabled(false); + txtDataSeg1->setEnabled(false); + btnMoreDataSeg1->setEnabled(false); + btnClearDataSeg1->setEnabled(false); + lblSeg2->setEnabled(false); cmbECISeg2->setEnabled(false); txtDataSeg2->setEnabled(false); btnMoreDataSeg2->setEnabled(false); + btnClearDataSeg2->setEnabled(false); + lblSeg3->setEnabled(false); cmbECISeg3->setEnabled(false); txtDataSeg3->setEnabled(false); btnMoreDataSeg3->setEnabled(false); + btnClearDataSeg3->setEnabled(false); + return; + } + + lblSeg1->setEnabled(true); + txtDataSeg1->setEnabled(true); + btnMoreDataSeg1->setEnabled(true); + if (txtDataSeg1->text().isEmpty()) { + cmbECISeg1->setEnabled(false); + btnClearDataSeg1->setEnabled(false); + + lblSeg2->setEnabled(false); + cmbECISeg2->setEnabled(false); + txtDataSeg2->setEnabled(false); + btnMoreDataSeg2->setEnabled(false); + btnClearDataSeg2->setEnabled(false); + + lblSeg3->setEnabled(false); + cmbECISeg3->setEnabled(false); + txtDataSeg3->setEnabled(false); + btnMoreDataSeg3->setEnabled(false); + btnClearDataSeg3->setEnabled(false); } else { cmbECISeg1->setEnabled(true); + btnClearDataSeg1->setEnabled(true); + lblSeg2->setEnabled(true); txtDataSeg2->setEnabled(true); btnMoreDataSeg2->setEnabled(true); if (txtDataSeg2->text().isEmpty()) { cmbECISeg2->setEnabled(false); + btnClearDataSeg2->setEnabled(false); + lblSeg3->setEnabled(false); cmbECISeg3->setEnabled(false); txtDataSeg3->setEnabled(false); btnMoreDataSeg3->setEnabled(false); + btnClearDataSeg3->setEnabled(false); } else { cmbECISeg2->setEnabled(true); + btnClearDataSeg2->setEnabled(true); + + bool data_seg3_empty = txtDataSeg3->text().isEmpty(); lblSeg3->setEnabled(true); + cmbECISeg3->setEnabled(!data_seg3_empty); txtDataSeg3->setEnabled(true); btnMoreDataSeg3->setEnabled(true); - if (txtDataSeg3->text().isEmpty()) { - cmbECISeg3->setEnabled(false); - } else { - cmbECISeg3->setEnabled(true); - } + btnClearDataSeg3->setEnabled(!data_seg3_empty); } } } @@ -1735,6 +2057,7 @@ void MainWindow::composite_ui_set() lblCompType->setEnabled(enabled); cmbCompType->setEnabled(enabled); lblComposite->setEnabled(enabled); + btnClearComposite->setEnabled(enabled); txtComposite->setEnabled(enabled); if (enabled) { @@ -1890,7 +2213,9 @@ void MainWindow::update_preview() if (!grpComposite->isHidden() && chkComposite->isChecked()) { m_bc.bc.setPrimaryMessage(txtData->text()); m_bc.bc.setText(txtComposite->toPlainText()); + btnClearComposite->setEnabled(!txtComposite->toPlainText().isEmpty()); } else { + btnClearComposite->setEnabled(false); if (!grpSegs->isHidden() && !txtDataSeg1->text().isEmpty()) { std::vector segs; segs.push_back(Zint::QZintSeg(txtData->text(), cmbECI->currentIndex())); @@ -2437,6 +2762,7 @@ void MainWindow::update_preview() cmbECI->setEnabled(m_bc.bc.supportsECI()); lblECI->setEnabled(cmbECI->isEnabled()); } + btnClearData->setEnabled(!txtData->text().isEmpty()); chkGS1Parens->setEnabled(m_bc.bc.supportsGS1()); chkGS1NoCheck->setEnabled(m_bc.bc.supportsGS1()); chkRInit->setEnabled(m_bc.bc.supportsReaderInit() && (m_bc.bc.inputMode() & 0x07) != GS1_MODE); @@ -2491,6 +2817,7 @@ void MainWindow::createActions() QIcon copyIcon(QIcon::fromTheme(QSL("edit-copy"), QIcon(QSL(":res/copy.svg")))); QIcon cliIcon(QSL(":res/zint_black.ico")); QIcon saveIcon(QIcon::fromTheme(QSL("document-save"), QIcon(QSL(":res/download.svg")))); + QIcon zapIcon(QIcon(QSL(":res/zap.svg"))); QIcon aboutIcon(QSL(":res/zint-qt.ico")); QIcon helpIcon(QIcon::fromTheme(QSL("help-contents"), QIcon(QSL(":res/help-circle.svg")))); QIcon quitIcon(QIcon::fromTheme(QSL("window-close"), QIcon(QSL(":res/x.svg")))); @@ -2555,6 +2882,11 @@ void MainWindow::createActions() m_saveAsAct->setShortcut(QKeySequence::Save); connect(m_saveAsAct, SIGNAL(triggered()), this, SLOT(save())); + m_factoryResetAct = new QAction(zapIcon, tr("Factory &Reset..."), this); + m_factoryResetAct->setStatusTip(tr("Clear all data & settings")); + m_factoryResetAct->setShortcut(factoryResetSeq); + connect(m_factoryResetAct, SIGNAL(triggered()), this, SLOT(factory_reset())); + m_helpAct = new QAction(helpIcon, tr("&Help (online)"), this); m_helpAct->setStatusTip(tr("Online manual")); m_helpAct->setShortcut(QKeySequence::HelpContents); @@ -2598,6 +2930,8 @@ void MainWindow::createMenu() m_menu->addSeparator(); m_menu->addAction(m_saveAsAct); m_menu->addSeparator(); + m_menu->addAction(m_factoryResetAct); + m_menu->addSeparator(); m_menu->addAction(m_helpAct); m_menu->addAction(m_aboutAct); m_menu->addSeparator(); diff --git a/frontend_qt/mainwindow.h b/frontend_qt/mainwindow.h index fe2a63e3..ce633c90 100644 --- a/frontend_qt/mainwindow.h +++ b/frontend_qt/mainwindow.h @@ -1,6 +1,6 @@ /*************************************************************************** * Copyright (C) 2008 by BogDan Vatra * - * Copyright (C) 2009-2021 by Robin Stuart * + * Copyright (C) 2009-2022 by Robin Stuart * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef MAINWINDOW_H #define MAINWINDOW_H @@ -45,8 +45,14 @@ public: public slots: void update_preview(); void change_options(); + void on_fgcolor_clicked(); void on_bgcolor_clicked(); + void fgcolor_changed(const QColor& color); + void bgcolor_changed(const QColor& color); + void fgcolor_edited(); + void bgcolor_edited(); + void data_ui_set(); void composite_ui_set(); void composite_ean_check(); @@ -61,20 +67,29 @@ public slots: void structapp_ui_set(); void on_encoded(); void on_errored(); + void on_dataChanged(const QString& text, bool escaped, int seg_no); void filter_symbologies(); bool save(); + void factory_reset(); void about(); void help(); void quit_now(); void menu(); void reset_colours(); + void reverse_colours(); void open_data_dialog(); void open_data_dialog_seg1(); void open_data_dialog_seg2(); void open_data_dialog_seg3(); void open_sequence_dialog(); + void clear_data(); + void clear_data_seg1(); + void clear_data_seg2(); + void clear_data_seg3(); + void clear_composite(); + void zap(); void open_cli_dialog(); void copy_to_clipboard_bmp(); @@ -100,6 +115,16 @@ public slots: void errtxtBar_context_menu(const QPoint &pos); protected: + void load_settings(QSettings &settings); + + bool clear_data_eci_seg(int seg_no); + + void color_clicked(QColor &color, QLineEdit *txt, QPushButton *btn, const QString& title, QByteArray& geometry, + const char *color_changed); + void color_edited(QColor &color, QLineEdit *txt, QPushButton *btn); + QString getColorStr(const QColor color, bool alpha_always = false); + void setColorTxtBtn(const QColor color, QLineEdit *txt, QPushButton* btn); + void resizeEvent(QResizeEvent *event); bool event(QEvent *event) override; bool eventFilter(QObject *watched, QEvent *event); @@ -122,6 +147,9 @@ protected: void errtxtBar_clear(); void errtxtBar_set(bool isError); + QLineEdit *get_seg_textbox(int seg_no); + QComboBox *get_seg_eci(int seg_no); + QPoint get_context_menu_pos(const QPoint &pos, QWidget *widget); QWidget *get_widget(const QString &name); @@ -154,13 +182,15 @@ protected: void load_sub_settings(QSettings &settings, int symbology); private: - QColor m_fgcolor,m_bgcolor; + QColor m_fgcolor, m_bgcolor; + QByteArray m_fgcolor_geometry, m_bgcolor_geometry; BarcodeItem m_bc; QWidget *m_optionWidget; QGraphicsScene *scene; int m_symbology; QMenu *m_menu; QShortcut *m_saveAsShortcut; + QShortcut *m_factoryResetShortcut; QShortcut *m_openCLIShortcut; QShortcut *m_copyBMPShortcut; QShortcut *m_copyEMFShortcut; @@ -180,6 +210,7 @@ private: QAction *m_copyTIFAct; QAction *m_openCLIAct; QAction *m_saveAsAct; + QAction *m_factoryResetAct; QAction *m_aboutAct; QAction *m_helpAct; QAction *m_quitAct; @@ -190,4 +221,5 @@ private: QPushButton *m_btnHeightPerRowDefault; }; +/* vim: set ts=4 sw=4 et : */ #endif diff --git a/frontend_qt/res/black-eye.svg b/frontend_qt/res/black-eye.svg new file mode 100644 index 00000000..f60d2cf5 --- /dev/null +++ b/frontend_qt/res/black-eye.svg @@ -0,0 +1 @@ + diff --git a/frontend_qt/res/delete.svg b/frontend_qt/res/delete.svg index 8c6074b9..5e090f6e 100644 --- a/frontend_qt/res/delete.svg +++ b/frontend_qt/res/delete.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/frontend_qt/res/shuffle.svg b/frontend_qt/res/shuffle.svg new file mode 100644 index 00000000..8cfb5db5 --- /dev/null +++ b/frontend_qt/res/shuffle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend_qt/res/white-eye.svg b/frontend_qt/res/white-eye.svg new file mode 100644 index 00000000..3895f3c6 --- /dev/null +++ b/frontend_qt/res/white-eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend_qt/res/zap.svg b/frontend_qt/res/zap.svg new file mode 100644 index 00000000..8fdafa93 --- /dev/null +++ b/frontend_qt/res/zap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend_qt/resources.qrc b/frontend_qt/resources.qrc index 9ab4e939..42a5c3de 100644 --- a/frontend_qt/resources.qrc +++ b/frontend_qt/resources.qrc @@ -34,12 +34,16 @@ grpVIN.ui res/zint-qt.ico res/zint_black.ico + res/black-eye.svg res/check.svg res/copy.svg res/delete.svg res/download.svg res/help-circle.svg res/menu.svg + res/shuffle.svg + res/white-eye.svg res/x.svg + res/zap.svg diff --git a/frontend_qt/sequencewindow.cpp b/frontend_qt/sequencewindow.cpp index 564aabfc..ebcff88a 100644 --- a/frontend_qt/sequencewindow.cpp +++ b/frontend_qt/sequencewindow.cpp @@ -1,6 +1,6 @@ /* Zint Barcode Generator - the open source barcode generator - Copyright (C) 2009 - 2021 Robin Stuart + Copyright (C) 2009-2022 Robin Stuart This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* vim: set ts=4 sw=4 et : */ +/* SPDX-License-Identifier: GPL-3.0-or-later */ //#include #include @@ -46,11 +46,13 @@ SequenceWindow::SequenceWindow(BarcodeItem *bc) : m_bc(bc) spnSeqEndVal->setValue(settings.value(QSL("studio/sequence/end_value"), 10).toInt()); spnSeqIncVal->setValue(settings.value(QSL("studio/sequence/increment"), 1).toInt()); linSeqFormat->setText(settings.value(QSL("studio/sequence/format"), QSL("$$$$$$")).toString()); + txtSeqPreview->setPlainText(settings.value(QSL("studio/sequence/preview"), QSL("")).toString()); QIcon closeIcon(QIcon::fromTheme(QSL("window-close"), QIcon(QSL(":res/x.svg")))); - QIcon clearIcon(QIcon::fromTheme(QSL("edit-clear"), QIcon(QSL(":res/delete.svg")))); + QIcon clearIcon(QSL(":res/delete.svg")); btnSeqClose->setIcon(closeIcon); btnSeqClear->setIcon(clearIcon); + btnSeqClear->setEnabled(!txtSeqPreview->toPlainText().isEmpty()); connect(btnSeqClose, SIGNAL( clicked( bool )), SLOT(close())); connect(btnSeqClear, SIGNAL( clicked( bool )), SLOT(clear_preview())); @@ -72,6 +74,7 @@ SequenceWindow::~SequenceWindow() settings.setValue(QSL("studio/sequence/end_value"), spnSeqEndVal->value()); settings.setValue(QSL("studio/sequence/increment"), spnSeqIncVal->value()); settings.setValue(QSL("studio/sequence/format"), linSeqFormat->text()); + settings.setValue(QSL("studio/sequence/preview"), txtSeqPreview->toPlainText()); } void SequenceWindow::clear_preview() @@ -166,8 +169,10 @@ void SequenceWindow::check_generate() preview_copy = txtSeqPreview->toPlainText(); if (preview_copy.isEmpty()) { btnSeqExport->setEnabled(false); + btnSeqClear->setEnabled(false); } else { btnSeqExport->setEnabled(true); + btnSeqClear->setEnabled(true); } } @@ -211,3 +216,5 @@ void SequenceWindow::generate_sequence() ExportWindow dlg(m_bc, txtSeqPreview->toPlainText()); dlg.exec(); } + +/* vim: set ts=4 sw=4 et : */ diff --git a/tools/update_version.php b/tools/update_version.php index fae1a029..ffd7deb9 100644 --- a/tools/update_version.php +++ b/tools/update_version.php @@ -2,8 +2,9 @@ /* Update Zint version number in various files */ /* libzint - the open source barcode library - Copyright (C) 2020 - 2021 Robin Stuart + Copyright (C) 2020-2022 Robin Stuart */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* Run from project directory * * php tools/update_version.php ZINT_VERSION_MAJOR ZINT_VERSION_MINOR ZINT_VERSION_RELEASE [ZINT_VERSION_BUILD] @@ -15,7 +16,6 @@ * php tools/update_version.php 3 4 5 9 * cd docs; make */ -/* vim: set ts=4 sw=4 et : */ $basename = basename(__FILE__); $dirname = dirname(__FILE__); @@ -51,6 +51,7 @@ if ($build) { $rc_str1 = "$major,$minor,$release,$build"; $rc_str2 = "$major.$minor.$release.$build"; +/* `$to_do` is no. of lines that should get replaced/changed, not no. of replacements */ function version_replace($to_do, $file, $match_pattern, $replace_pattern, $replace_str) { global $basename; @@ -151,6 +152,10 @@ if (!file_put_contents($file, implode("\n", $lines))) { exit("$basename: ERROR: Could not write file \"$file\"" . PHP_EOL); } +// README.linux + +version_replace(3, $data_dirname . 'README.linux', '/zint-[0-9]/', '/[0-9.]+/', $v_base_str); + // zint.spec version_replace(1, $data_dirname . 'zint.spec', '/^Version:/', '/[0-9.]+/', $v_base_str); @@ -243,7 +248,7 @@ if ($build !== 9) { // Don't update if marking version as dev // docs/zint.1.pmd -version_replace(1, $data_dirname . 'docs/zint.1.pmd', '/^% zint\(1\) Version /', '/[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?( \(dev\))?/', $v_str); +version_replace(1, $data_dirname . 'docs/zint.1.pmd', '/^% ZINT\(1\) Version /', '/[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?( \(dev\))?/', $v_str); // frontend_qt/res/qtZint.rc @@ -304,3 +309,5 @@ print '!!! REMEMBER: run "autoconf" and "./configure" in "backend_tcl/" !!!' . print '!!! REMEMBER: update version and date in "ChangeLog" !!!' . PHP_EOL; print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' . PHP_EOL; print PHP_EOL; + +/* vim: set ts=4 sw=4 et : */