diff --git a/backend/dmatrix.c b/backend/dmatrix.c index 89c7521f..5df83505 100755 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -1178,11 +1178,18 @@ int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int leng } } - /* Skip rectangular symbols in square only mode */ - while (symbol->option_3 == DM_SQUARE && matrixH[calcsize] != matrixW[calcsize]) { - calcsize++; - } - + if (symbol->option_3 == DM_SQUARE) { + /* Skip rectangular symbols in square only mode */ + while (matrixH[calcsize] != matrixW[calcsize]) { + calcsize++; + } + } else if (symbol->option_3 != DM_DMRE) { + /* Skip DMRE symbols */ + while (isDMRE[calcsize]) { + calcsize++; + } + } + symbolsize = optionsize; if (calcsize > optionsize) { symbolsize = calcsize; diff --git a/backend/dmatrix.h b/backend/dmatrix.h index 3df50596..75ebffa2 100644 --- a/backend/dmatrix.h +++ b/backend/dmatrix.h @@ -88,11 +88,6 @@ static const int text_value[] = { 22, 23, 24, 25, 26, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31 }; -// Activate DMRE Extensions -//#define DMRE -#ifdef DMRE -// With Rectangular extensions - // Position in option array [symbol option value - 1] // The position in the option array is by increasing total data codewords with square first @@ -110,28 +105,45 @@ static const int intsymbol[] = { 26, /* 41: 26x48 , 90*/ 29, /* 42: 26x64 ,118*/ 0 }; - + // Number of DM Sizes #define DMSIZESCOUNT 42 // Number of 144x144 for special interlace #define INTSYMBOL144 41 -// Horizontal matrix size - -static const int matrixH[] = { - /*0*/ 10, /* 10x10 ,3 */ 12, /* 12x12 ,5 */ 8, /* 8x18 ,5 */ 14, /* 14x14 , 8 */ - /*4*/ 8, /* 8x32 ,10 */ 16, /* 16x16 ,12 */ 12, /* 12x26 ,16 */ 18, /* 18x18 ,18 */ - /*8*/ 8, /* 8x48 ,18 */ 20, /* 20x20 ,22 */ 12, /* 12x36 ,22 */ 8, /* 8x64 ,24 */ - /*12*/ 22, /* 22x22 ,30 */ 16, /* 16x36 ,32 */ 24, /* 24x24 ,36 */ 12, /* 12x64 ,43 */ - /*16*/ 26, /* 26x26 ,44 */ 16, /* 16x48 ,49 */ 24, /* 24x32 ,49 */ 26, /* 26x32 ,52 */ - /*20*/ 24, /* 24x36 ,55 */ 32, /* 32x32 ,62 */ 16, /* 16x64 ,62 */ 26, /* 26x40 ,70 */ - /*24*/ 24, /* 24x48 ,80 */ 36, /* 36x36 ,86 */ 26, /* 26x48 ,90 */ 24, /* 24x64 ,108*/ - /*28*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/ 44, /* 44x44 ,144*/ 48, /* 48x48,174 */ - /*32*/ 52, /* 52x52,204 */ 64, /* 64x64,280 */ 72, /* 72x72,368 */ 80, /* 80x80,456 */ - /*36*/ 88, /* 88x88,576 */ 96, /* 96x96,696 */ 104, /*104x104,816*/ 120, /*120x120,1050*/ - /*40*/ 132, /*132x132,1304*/144/*144x144,1558*/ -}; - +// Is the current code a DMRE code ? +// This is the case, if intsymbol index >= 30 + +static const int isDMRE[] = { + /*0*/ 0, /* 10x10 ,3 */ 0, /* 12x12 ,5 */ 0, /* 8x18 ,5 */ 0, /* 14x14 , 8 */ + /*4*/ 0, /* 8x32 ,10 */ 0, /* 16x16 ,12 */ 0, /* 12x26 ,16 */ 0, /* 18x18 ,18 */ + /*8*/ 1, /* 8x48 ,18 */ 0, /* 20x20 ,22 */ 0, /* 12x36 ,22 */ 1, /* 8x64 ,24 */ + /*12*/ 0, /* 22x22 ,30 */ 0, /* 16x36 ,32 */ 0, /* 24x24 ,36 */ 1, /* 12x64 ,43 */ + /*16*/ 0, /* 26x26 ,44 */ 0, /* 16x48 ,49 */ 1, /* 24x32 ,49 */ 1, /* 26x32 ,52 */ + /*20*/ 1, /* 24x36 ,55 */ 0, /* 32x32 ,62 */ 1, /* 16x64 ,62 */ 1, /* 26x40 ,70 */ + /*24*/ 1, /* 24x48 ,80 */ 0, /* 36x36 ,86 */ 1, /* 26x48 ,90 */ 1, /* 24x64 ,108*/ + /*28*/ 0, /* 40x40 ,114*/ 1, /* 26x64 ,118*/ 0, /* 44x44 ,144*/ 0, /* 48x48,174 */ + /*32*/ 0, /* 52x52,204 */ 0, /* 64x64,280 */ 0, /* 72x72,368 */ 0, /* 80x80,456 */ + /*36*/ 0, /* 88x88,576 */ 0, /* 96x96,696 */ 0, /*104x104,816*/ 0, /*120x120,1050*/ + /*40*/ 0, /*132x132,1304*/0 /*144x144,1558*/ +}; + +// Horizontal matrix size + +static const int matrixH[] = { + /*0*/ 10, /* 10x10 ,3 */ 12, /* 12x12 ,5 */ 8, /* 8x18 ,5 */ 14, /* 14x14 , 8 */ + /*4*/ 8, /* 8x32 ,10 */ 16, /* 16x16 ,12 */ 12, /* 12x26 ,16 */ 18, /* 18x18 ,18 */ + /*8*/ 8, /* 8x48 ,18 */ 20, /* 20x20 ,22 */ 12, /* 12x36 ,22 */ 8, /* 8x64 ,24 */ + /*12*/ 22, /* 22x22 ,30 */ 16, /* 16x36 ,32 */ 24, /* 24x24 ,36 */ 12, /* 12x64 ,43 */ + /*16*/ 26, /* 26x26 ,44 */ 16, /* 16x48 ,49 */ 24, /* 24x32 ,49 */ 26, /* 26x32 ,52 */ + /*20*/ 24, /* 24x36 ,55 */ 32, /* 32x32 ,62 */ 16, /* 16x64 ,62 */ 26, /* 26x40 ,70 */ + /*24*/ 24, /* 24x48 ,80 */ 36, /* 36x36 ,86 */ 26, /* 26x48 ,90 */ 24, /* 24x64 ,108*/ + /*28*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/ 44, /* 44x44 ,144*/ 48, /* 48x48,174 */ + /*32*/ 52, /* 52x52,204 */ 64, /* 64x64,280 */ 72, /* 72x72,368 */ 80, /* 80x80,456 */ + /*36*/ 88, /* 88x88,576 */ 96, /* 96x96,696 */ 104, /*104x104,816*/ 120, /*120x120,1050*/ + /*40*/ 132, /*132x132,1304*/144/*144x144,1558*/ +}; + // Vertical matrix sizes static const int matrixW[] = { @@ -228,53 +240,5 @@ static const int matrixrsblock[] = { /*40*/ 62, /*132x132*/ 62 /*144x144*/ }; -#else -// No Rectangular extensions - -static const int intsymbol[] = { - 0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2, 4, 6, 9, 11, 14 -}; - -// Number of DM Sizes -#define DMSIZESCOUNT 30 -// Number of 144x144 for special interlace -#define INTSYMBOL144 29 - -static const int matrixH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48, - 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 -}; - -static const int matrixW[] = { - 10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44, - 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 -}; - -static const int matrixFH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24, - 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 -}; - -static const int matrixFW[] = { - 10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22, - 24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 -}; - -static const int matrixbytes[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 -}; - -static const int matrixdatablock[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 -}; - -static const int matrixrsblock[] = { - 5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68, - 42, 56, 36, 48, 56, 68, 56, 68, 62, 62 -}; - -#endif #endif diff --git a/backend/zint.h b/backend/zint.h index 7ea19673..7fd94199 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -202,6 +202,7 @@ extern "C" { #define SJIS_MODE 4 #define DM_SQUARE 100 +#define DM_DMRE 101 #define ZINT_WARN_INVALID_OPTION 2 #define ZINT_ERROR_TOO_LONG 5 diff --git a/backend_tcl/zint.c b/backend_tcl/zint.c index affd4dd2..45707b85 100644 --- a/backend_tcl/zint.c +++ b/backend_tcl/zint.c @@ -429,13 +429,13 @@ static int Encode(Tcl_Interp *interp, int objc, "-bind", "-box", "-barcode", "-height", "-whitesp", "-border", "-fg", "-bg", "-cols", "-vers", "-rotate", "-secure", "-mode", "-primary", "-scale", "-format", - "-notext", "-square", "-init", "-smalltext", "-to", + "-notext", "-square", "-dmre", "-init", "-smalltext", "-to", NULL}; enum iOption { iBind, iBox, iBarcode, iHeight, iWhiteSp, iBorder, iFG, iBG, iCols, iVers, iRotate, iSecure, iMode, iPrimary, iScale, iFormat, - iNoText, iSquare, iInit, iSmallText, iTo + iNoText, iSquare, iDMRE, iInit, iSmallText, iTo }; int optionIndex; int intValue; @@ -458,6 +458,7 @@ static int Encode(Tcl_Interp *interp, int objc, case iSmallText: case iNoText: case iSquare: + case iDMRE: /* >> Binary options */ if (TCL_OK != Tcl_GetBooleanFromObj(interp, objv[optionPos+1], &intValue)) @@ -558,6 +559,12 @@ static int Encode(Tcl_Interp *interp, int objc, case iSquare: hSymbol->option_3 = (intValue?DM_SQUARE:0); break; + case iDMRE: + /* DM_SQUARE overwrites DM_DMRE */ + if (hSymbol->option_3 != DM_DMRE) { + Symbol->option_3 = (intValue?DM_DMRE:0); + } + break; case iScale: if (doubleValue < 0.01) { Tcl_SetObjResult(interp, diff --git a/frontend/Makefile.mingw b/frontend/Makefile.mingw index a4fbd536..412a4fdf 100644 --- a/frontend/Makefile.mingw +++ b/frontend/Makefile.mingw @@ -6,7 +6,7 @@ # make clean cleans up a previous compilation and any object or editor files # -ZINT_VERSION:=-DZINT_VERSION=\"2.4.4\" +ZINT_VERSION:=-DZINT_VERSION=\"2.5.0\" CC := gcc CFLAGS := -D_WIN32 -O2 -fms-extensions -mms-bitfields -fno-exceptions -fomit-frame-pointer -Wall -I../backend diff --git a/frontend/main.c b/frontend/main.c index 60aa8e55..a67c6db4 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -101,6 +101,7 @@ void usage(void) { " --binary Treat input as Binary data\n" " --notext Remove human readable text\n" " --square Force Data Matrix symbols to be square\n" + " --dmre Allow Data Matrix Rectangular Extended\n" " --init Create reader initialisation symbol (Code 128)\n" " --smalltext Use half-size text in PNG images\n" " --batch Treat each line of input as a separate data set\n" @@ -409,6 +410,7 @@ int main(int argc, char **argv) { {"binary", 0, 0, 0}, {"notext", 0, 0, 0}, {"square", 0, 0, 0}, + {"dmre", 0, 0, 0}, {"init", 0, 0, 0}, {"smalltext", 0, 0, 0}, {"batch", 0, 0, 0}, @@ -471,6 +473,11 @@ int main(int argc, char **argv) { if (!strcmp(long_options[option_index].name, "square")) { my_symbol->option_3 = DM_SQUARE; } + /* Square overwrites DMRE */ + if (!strcmp(long_options[option_index].name, "dmre") + && my_symbol->option_3 != DM_SQUARE) { + my_symbol->option_3 = DM_DMRE; + } if (!strcmp(long_options[option_index].name, "scale")) { my_symbol->scale = (float) (atof(optarg)); if (my_symbol->scale < 0.01) { diff --git a/frontend_qt4/grpDM.ui b/frontend_qt4/grpDM.ui index fa087dc6..1d542a64 100644 --- a/frontend_qt4/grpDM.ui +++ b/frontend_qt4/grpDM.ui @@ -207,7 +207,6 @@ 16 x 48 - @@ -283,6 +281,16 @@ + + + + Allow DMRE in Automatic Mode + + + false + + + diff --git a/frontend_qt4/mainWindow.ui b/frontend_qt4/mainWindow.ui index 9e18eec0..f3affd47 100644 --- a/frontend_qt4/mainWindow.ui +++ b/frontend_qt4/mainWindow.ui @@ -24,7 +24,7 @@ - Zint Barcode Studio 2.4 + Zint Barcode Studio 2.5 diff --git a/frontend_qt4/mainwindow.cpp b/frontend_qt4/mainwindow.cpp index b0b9f401..8aec13de 100644 --- a/frontend_qt4/mainwindow.cpp +++ b/frontend_qt4/mainwindow.cpp @@ -362,6 +362,7 @@ void MainWindow::change_options() connect(m_optionWidget->findChild("radDM200HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); connect(m_optionWidget->findChild("cmbDM200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild("chkDMRectangle"), SIGNAL(stateChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("chkDMRE"), SIGNAL(stateChanged( int )), SLOT(update_preview())); } if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_QRCODE) @@ -718,8 +719,12 @@ void MainWindow::update_preview() m_bc.bc.setWidth(m_optionWidget->findChild("cmbDM200Size")->currentIndex()); if(m_optionWidget->findChild("chkDMRectangle")->isChecked()) m_bc.bc.setOption3(DM_SQUARE); - else - m_bc.bc.setOption3(0); + else { + if(m_optionWidget->findChild("chkDMRE")->isChecked()) + m_bc.bc.setOption3(DM_DMRE); + else + m_bc.bc.setOption3(0); + } break; case BARCODE_QRCODE: diff --git a/win32/zint_cmdline_vc6/readme.txt b/win32/zint_cmdline_vc6/readme.txt index 9c0d0bc2..d9328f7b 100644 --- a/win32/zint_cmdline_vc6/readme.txt +++ b/win32/zint_cmdline_vc6/readme.txt @@ -2,7 +2,7 @@ Harald Oehlmann 2016-01-12 Why to use VC6 ? -It avoids DLL Hell as the runtime is present on all WIndows Versions sinc XP. +It avoids DLL Hell as the runtime is present on all Windows Versions since XP. I compile on Windows 10 64 bit. How to compile: @@ -15,10 +15,10 @@ a) zlib (current version: 1.2.8) cd $ZR\..\zlib nmake -f win32\Makefile.msc -> generates zlib.lib, zlib1.dll --> generates $ZR\--\lpng\libpng.lib +-> generates $ZR\..\lpng\libpng.lib b) lpng (current version: 1.6.20) * put libpng to $ZR/../lpng cd $ZR\..\lpng nmake -f scripts\makefile.vcwin32 --> generates $ZR\--\lpng\libpng.lib +-> generates $ZR\..\lpng\libpng.lib c) open the files in this folder with the msvc6 gui and compile \ No newline at end of file diff --git a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp index fb037456..2e499ce7 100644 --- a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp +++ b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp @@ -39,9 +39,10 @@ RSC=rc.exe # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\backend" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "NO_PNG" /YX /FD /D ZINT_VERSION="\"2.7.3\"" /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\backend" /I "..\..\..\zlib" /I "..\..\..\lpng" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /D ZINT_VERSION="\"2.7.3\"" /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -49,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpng.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"Release/zint.exe" /libpath:"..\..\..\zlib" /libpath:"..\..\..\lpng" !ELSEIF "$(CFG)" == "zint_cmdline_vc6 - Win32 Debug" @@ -65,7 +66,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\backend" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "NO_PNG" /YX /FD /D /D /D /GZ ZINT_VERSION="\"2.7.3\"" /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\backend" /I "..\..\..\lpng" /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ZINT_VERSION="\"2.7.4\"" /YX /FD /D /D /D /D /D /D /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe @@ -73,7 +74,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/zint.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpng.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/zint.exe" /pdbtype:sept /libpath:"..\..\..\lpng" /libpath:"..\..\..\zlib" +# SUBTRACT LINK32 /nodefaultlib !ENDIF diff --git a/zint.nsi b/zint.nsi index 6ef348ef..77acfed3 100644 --- a/zint.nsi +++ b/zint.nsi @@ -10,7 +10,7 @@ ;****************************************************************************** !define PRODUCT_NAME "Zint" !define PRODUCT_EXE "qtZint.exe" -!define PRODUCT_VERSION "2.4.0.0" +!define PRODUCT_VERSION "2.5.0.0" !define PRODUCT_WEB_SITE "http://www.zint.org.uk" !define PRODUCT_PUBLISHER "Robin Stuart & BogDan Vatra" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_EXE}" diff --git a/zint.spec b/zint.spec index 3f0502ca..2a2a8a88 100644 --- a/zint.spec +++ b/zint.spec @@ -1,5 +1,5 @@ Name: zint -Version: 2.4.4 +Version: 2.5.0 Release: 2%{?dist} Summary: A barcode generator and library License: GPLv3+