From b78fa8cf2f22f1d4bcdc9d8e363101ab7751adf1 Mon Sep 17 00:00:00 2001 From: Harald Oehlmann Date: Tue, 4 Aug 2020 15:49:25 +0200 Subject: [PATCH] - Compile-able with MS-VC6 - Compile-able with MS-VC2015+QT5.18 - transbarency in TCL backend - correct TCL demo - README changes --- README | 8 + backend/ps.c | 13 +- backend/svg.c | 3 +- backend_qt/qzint.cpp | 10 +- backend_tcl/demo/demo.tcl | 2 +- backend_tcl/zint.c | 196 +++++++++++------- .../howto_build_qzint_using_msvs2015.txt | 39 ++-- 7 files changed, 164 insertions(+), 107 deletions(-) diff --git a/README b/README index 035751c0..262462bc 100644 --- a/README +++ b/README @@ -261,6 +261,14 @@ Bugs: - Human readable representation: Code128, Code39, Code93 special characters are shown by a blank. - ITF14: Ticket 201: allow bind option +Version 2.9.1 not released jet: +Changes: +- Implement transparency support + - -nobackground option added + - -fg and -bg may contain an alpha channel + - structure zint_symbol may now contain an alpha channel as output +- Added DPD Symbology +Bugs: CONTACT US ---------- diff --git a/backend/ps.c b/backend/ps.c index 943ad0e1..3b78704b 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -113,19 +113,18 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { int colour_index, colour_rect_counter; char ps_color[30]; int draw_background = 1; - - if (strlen(symbol->bgcolour) > 6) { - if ((ctoi(symbol->bgcolour[6]) == 0) && (ctoi(symbol->bgcolour[7]) == 0)) { - draw_background = 0; - } - } - struct zint_vector_rect *rect; struct zint_vector_hexagon *hex; struct zint_vector_circle *circle; struct zint_vector_string *string; const char *locale = NULL; + if (strlen(symbol->bgcolour) > 6) { + if ((ctoi(symbol->bgcolour[6]) == 0) && (ctoi(symbol->bgcolour[7]) == 0)) { + draw_background = 0; + } + } + if (symbol->output_options & BARCODE_STDOUT) { feps = stdout; } else { diff --git a/backend/svg.c b/backend/svg.c index 3c0d1c34..17b8fc42 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -132,6 +132,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { struct zint_vector_string *string; char colour_code[7]; + int html_len; #ifdef _MSC_VER char* html_string; @@ -151,7 +152,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { bg_alpha = (16 * ctoi(symbol->bgcolour[6])) + ctoi(symbol->bgcolour[7]); } - int html_len = strlen((char *)symbol->text) + 1; + html_len = strlen((char *)symbol->text) + 1; for (i = 0; i < (int) strlen((char *)symbol->text); i++) { switch(symbol->text[i]) { diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp index a0282d23..2896b14b 100644 --- a/backend_qt/qzint.cpp +++ b/backend_qt/qzint.cpp @@ -20,6 +20,9 @@ #include #include #include +/* the following include was necessary to compile with QT 5.18 on Windows */ +/* QT 8.7 did not require it. */ +#include namespace Zint { static const char* fontstyle = "Arial"; @@ -84,13 +87,8 @@ namespace Zint { } strcpy(m_zintSymbol->fgcolour, m_fgColor.name().toLatin1().right(6)); - if (m_fgColor.alpha() != 0xff) { - strcat(m_zintSymbol->fgcolour, m_fgColor.name(QColor::HexArgb).toLatin1().mid(1,2)); - } strcpy(m_zintSymbol->bgcolour, m_bgColor.name().toLatin1().right(6)); - if (m_bgColor.alpha() != 0xff) { - strcat(m_zintSymbol->bgcolour, m_bgColor.name(QColor::HexArgb).toLatin1().mid(1,2)); - } + strcpy(m_zintSymbol->primary, m_primaryMessage.toLatin1().left(127)); } diff --git a/backend_tcl/demo/demo.tcl b/backend_tcl/demo/demo.tcl index ba5c89e6..b61ce7c1 100644 --- a/backend_tcl/demo/demo.tcl +++ b/backend_tcl/demo/demo.tcl @@ -52,7 +52,7 @@ proc Generate {} { ::zintimg blank ::zintimg configure -width 0 -height 0 catch { - zint encode [.e get] ::zintimg -barcode [.c get] -scale $sx {*}[.o get]} e] + zint encode [.e get] ::zintimg -barcode [.c get] -scale $sx {*}[.o get] } } } diff --git a/backend_tcl/zint.c b/backend_tcl/zint.c index 233ac079..d4ea3ecc 100644 --- a/backend_tcl/zint.c +++ b/backend_tcl/zint.c @@ -39,39 +39,39 @@ 2016-10-14 2.5.2 HaO - Include the upstream reverted image format 2016-12-12 2.5.3 HaO -- No changes here, take 2.5.1 framework files +- No changes here, take 2.5.1 framework files 2017-05-12 2.6.0 HaO -- No changes here, take 2.6 framework files +- No changes here, take 2.6 framework files 2017-08-29 2.6.1 HaO -- Framework 2.6.1 extensions -- EAN/UPC Codes with included check digit -- UPNQR Code -- Misspelled symbology: AztecRunes +- Framework 2.6.1 extensions +- EAN/UPC Codes with included check digit +- UPNQR Code +- Misspelled symbology: AztecRunes 2017-10-23 2.6.2 HaO -- Framework 2.6.2 bugfixes -- Allow dll unload - 2018-02-13 2.6.3 HaO - - Framework trunk update - - Added VIN and MailMark symbologies. - 2018-11-02 2.6.4 HaO - - Framework trunk update - - Add options -bold, -dotted, -dotsize, -dmre, -eci - - Implemented ECI logic +- Framework 2.6.2 bugfixes +- Allow dll unload + 2018-02-13 2.6.3 HaO + - Framework trunk update + - Added VIN and MailMark symbologies. + 2018-11-02 2.6.4 HaO + - Framework trunk update + - Add options -bold, -dotted, -dotsize, -dmre, -eci + - Implemented ECI logic 2019-09-01 2.6.5 HaO - - Framework 2.6.5 update - - Add option -gssep + - Framework 2.6.5 update + - Add option -gssep 2019-09-18 2.6.6 HaO - - Framework 2.6.6 update + - Framework 2.6.6 update 2019-10-07 2.6.7 HaO - - Framework 2.6.7 update + - Framework 2.6.7 update 2019-12-05 2.7.0 HaO - - Framework 2.7.0 update + - Framework 2.7.0 update - Add symbology rmqr 2020-02-01 2.7.1 HaO - - Framework 2.7.1 update - 2020-04-06 HaO - - Added option -fullmultibyte - 2020-04-07 2.8.0 HaO + - Framework 2.7.1 update + 2020-04-06 HaO + - Added option -fullmultibyte + 2020-04-07 2.8.0 HaO - Added symbology "UltraCode". 2020-05-19 HaO - Added option -separator to specify stacked symbology separator width @@ -95,6 +95,11 @@ - RSS14Omni-CC -> GS1DataBarStackedOmni-CC - RSSExpandedStacked-CC -> GS1DataBarExpandedStacked-CC *** Potential incompatibility *** +2020-08-04 2.10.0 HaO +- added symbology "DPDCode" +- Alpha channel support added: + - added option -nobackground + - also allow RRGGBBAA for -fg and -bg options */ #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) @@ -206,7 +211,7 @@ static char *s_code_list[] = { "ISBN", "RM4SCC", "Datamatrix", - "EAN14", + "EAN14", "VIN", "CodablockF", "NVE18", @@ -216,6 +221,7 @@ static char *s_code_list[] = { "GS1DataBarSstackedOmni", "GS1DataBarExpandedStacked", "Planet", + "DPDCode", "MicroPDF417", "USPSIntelligentMail", "Plessey", @@ -234,7 +240,7 @@ static char *s_code_list[] = { "HIBC-CodablockF", "HIBCAztec", "DotCode", - "HanXin", + "HanXin", "MailMark", "AztecRunes", "Code32", @@ -251,8 +257,8 @@ static char *s_code_list[] = { "Channel", "CodeOne", "GridMatrix", - "UPNQR", - "UltraCode", + "UPNQR", + "UltraCode", "rMQR", NULL}; @@ -266,7 +272,7 @@ static int s_code_number[] = { BARCODE_CODE39, BARCODE_EXCODE39, BARCODE_EANX, - BARCODE_EANX_CHK, + BARCODE_EANX_CHK, BARCODE_GS1_128, BARCODE_CODABAR, BARCODE_CODE128, @@ -281,7 +287,7 @@ static int s_code_number[] = { BARCODE_DBAR_EXP, BARCODE_TELEPEN, BARCODE_UPCA, - BARCODE_UPCA_CHK, + BARCODE_UPCA_CHK, BARCODE_UPCE, BARCODE_UPCE_CHK, BARCODE_POSTNET, @@ -303,8 +309,8 @@ static int s_code_number[] = { BARCODE_ISBNX, BARCODE_RM4SCC, BARCODE_DATAMATRIX, - BARCODE_EAN14, - BARCODE_VIN, + BARCODE_EAN14, + BARCODE_VIN, BARCODE_CODABLOCKF, BARCODE_NVE18, BARCODE_JAPANPOST, @@ -313,6 +319,7 @@ static int s_code_number[] = { BARCODE_DBAR_OMNSTK, BARCODE_DBAR_EXPSTK, BARCODE_PLANET, + BARCODE_DPD, BARCODE_MICROPDF417, BARCODE_USPS_IMAIL, BARCODE_PLESSEY, @@ -330,9 +337,9 @@ static int s_code_number[] = { BARCODE_HIBC_MICPDF, BARCODE_HIBC_BLOCKF, BARCODE_HIBC_AZTEC, - BARCODE_DOTCODE, - BARCODE_HANXIN, - BARCODE_MAILMARK, + BARCODE_DOTCODE, + BARCODE_HANXIN, + BARCODE_MAILMARK, BARCODE_AZRUNE, BARCODE_CODE32, BARCODE_EANX_CC, @@ -348,8 +355,8 @@ static int s_code_number[] = { BARCODE_CHANNEL, BARCODE_CODEONE, BARCODE_GRIDMATRIX, - BARCODE_UPNQR, - BARCODE_ULTRA, + BARCODE_UPNQR, + BARCODE_ULTRA, BARCODE_RMQR, 0}; @@ -384,7 +391,7 @@ static char *s_eci_list[] = { "big5", /*28: ** Big-5 (Taiwan) Chinese Character Set*/ "euc-cn", /*29: ** GB (PRC) Chinese Character Set*/ "iso2022-kr", /*30: ** Korean Character Set (KSX1001:1998)*/ - NULL + NULL }; /* The ECI numerical number to pass to ZINT */ @@ -419,11 +426,12 @@ static char help_message[] = "zint tcl(stub,obj) dll\n" " -box bool: box around bar code, size set be -border\n" " -height integer: Symbol height in modules\n" " -whitesp integer: horizontal quiet zone in modules\n" - " -fg color: set foreground color as 6 hex rrggbb\n" - " -bg color: set background color as 6 hex rrggbb\n" + " -fg color: set foreground color as 6 or 8 hex rrggbbaa\n" + " -bg color: set background color as 6 or 8 hex rrggbbaa\n" + " -nobackground bool: set background transparent\n" " -cols integer: PDF417, Codablock F: number of columns\n" " -rows integer: Codablock F: number of rows\n" - " -vers integer: Symbology option\n" + " -vers integer: Symbology option\n" " -dmre bool: Allow Data Matrix Rectangular Extended\n" " -separator 0..4 (default: 1) : Stacked symbologies: separator width\n" " -rotate angle: Image rotation by 0,90 or 270 degrees\n" @@ -433,9 +441,9 @@ static char help_message[] = "zint tcl(stub,obj) dll\n" " -dotty bool: use dots instead of boxes for matrix codes\n" " -dotsize number: radius ratio of dots from 0.01 to 1.0\n" " -scale double: Scale the image to this factor\n" - " -format binary|unicode|gs1: input data format. Default:unicode\n" - " -fullmultibyte: allow multibyte compaction for xQR, HanXin, Gridmatrix\n" - " -gssep bool: for gs1, use gs as separator instead fnc1 (Datamatrix only)\n" + " -format binary|unicode|gs1: input data format. Default:unicode\n" + " -fullmultibyte: allow multibyte compaction for xQR, HanXin, Gridmatrix\n" + " -gssep bool: for gs1, use gs as separator instead fnc1 (Datamatrix only)\n" " -eci number: ECI to use\n" " -notext bool: no interpretation line\n" " -square bool: force Data Matrix symbols to be square\n" @@ -494,8 +502,8 @@ EXPORT int Zint_Init (Tcl_Interp *interp) //------------------------------------------------------------------------------ EXPORT int Zint_Unload (Tcl_Interp *Interp, int Flags) { - // Allow unload - return TCL_OK; + // Allow unload + return TCL_OK; } /*----------------------------------------------------------------------------*/ /* >>>>> Called routine */ @@ -593,7 +601,7 @@ static int Encode(Tcl_Interp *interp, int objc, int destY0 = 0; int destWidth = 0; int destHeight = 0; - int ECIIndex = 0; + int ECIIndex = 0; int fFullMultiByte = 0; int addon_gap = 0; int Separator = 1; @@ -624,13 +632,14 @@ static int Encode(Tcl_Interp *interp, int objc, char *optionList[] = { "-addongap", "-barcode", "-bg", "-bind", "-bold", "-border", "-box", "-cols", "-dmre", "-dotsize", "-dotty", "-eci", "-fg", "-format", - "-gssep", "-height", "-init", "-mode", "-notext", "-primary", - "-rotate", "-rows", "-scale", "-secure", "-smalltext", "-square", - "-to", "-vers", "-whitesp", "-fullmultibyte", "-separator", NULL}; + "-gssep", "-height", "-init", "-mode", "-nobackground", "-notext", + "-primary", "-rotate", "-rows", "-scale", "-secure", "-smalltext", + "-square", "-to", "-vers", "-whitesp", "-fullmultibyte", + "-separator", NULL}; enum iOption { iAddonGap, iBarcode, iBG, iBind, iBold, iBorder, iBox, iCols, iDMRE, iDotSize, iDotty, iECI, iFG, iFormat, iGSSep, iHeight, - iInit, iMode, iNoText, iPrimary, iRotate, iRows, + iInit, iMode, iNoBackground, iNoText, iPrimary, iRotate, iRows, iScale, iSecure, iSmallText, iSquare, iTo, iVers, iWhiteSp, iFullMultiByte, iSeparator }; @@ -654,12 +663,13 @@ static int Encode(Tcl_Interp *interp, int objc, case iBox: case iDMRE: case iDotty: - case iGSSep: + case iGSSep: case iInit: + case iNoBackground: case iNoText: case iSmallText: - case iSquare: - case iFullMultiByte: + case iSquare: + case iFullMultiByte: /* >> Binary options */ if (TCL_OK != Tcl_GetBooleanFromObj(interp, objv[optionPos+1], &intValue)) @@ -671,9 +681,9 @@ static int Encode(Tcl_Interp *interp, int objc, case iBG: /* >> Colors */ pStr = Tcl_GetStringFromObj(objv[optionPos+1],&lStr); - if (lStr != 6) { + if (lStr != 6 && lStr != 8) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("Color is not 6 hex",-1)); + Tcl_NewStringObj("Color is not 6 or 8 hex",-1)); fError = 1; } break; @@ -774,10 +784,10 @@ static int Encode(Tcl_Interp *interp, int objc, } else { hSymbol->output_options &= ~GS1_GS_SEPARATOR; } - break; - case iFullMultiByte: - fFullMultiByte = intValue; - break; + break; + case iFullMultiByte: + fFullMultiByte = intValue; + break; case iECI: if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], (const char **) s_eci_list,"-eci", optionPos, &ECIIndex) @@ -803,12 +813,17 @@ static int Encode(Tcl_Interp *interp, int objc, } break; case iFG: - strncpy(hSymbol->fgcolour, pStr, 6); - hSymbol->fgcolour[6]='\0'; + strncpy(hSymbol->fgcolour, pStr, lStr); + hSymbol->fgcolour[lStr]='\0'; break; case iBG: - strncpy(hSymbol->bgcolour, pStr, 6); - hSymbol->bgcolour[6]='\0'; + strncpy(hSymbol->bgcolour, pStr, lStr); + hSymbol->bgcolour[lStr]='\0'; + break; + case iNoBackground: + if (intValue) { + strcpy(hSymbol->bgcolour, "ffffff00"); + } break; case iNoText: hSymbol->show_hrt = (intValue?0:1); @@ -987,7 +1002,7 @@ static int Encode(Tcl_Interp *interp, int objc, } } /*------------------------------------------------------------------------*/ - /* >>> option_3 is set by two values depending on the symbology */ + /* >>> option_3 is set by two values depending on the symbology */ /* On wrong symbology, the option is ignored(as does the zint program)*/ if (fFullMultiByte && is_fullmultibyte(hSymbol)) { hSymbol->option_3 = ZINT_FULL_MULTIBYTE; @@ -1034,10 +1049,10 @@ static int Encode(Tcl_Interp *interp, int objc, /*------------------------------------------------------------------------*/ /* >>> Build symbol graphic */ if (! fError ) { - int ErrorNumber; - Tk_PhotoHandle hPhoto; - /*--------------------------------------------------------------------*/ - /* call zint graphic creation to buffer */ + int ErrorNumber; + Tk_PhotoHandle hPhoto; + /*--------------------------------------------------------------------*/ + /* call zint graphic creation to buffer */ ErrorNumber = ZBarcode_Encode_and_Buffer(hSymbol, (unsigned char *) pStr, lStr, rotate_angle); /*--------------------------------------------------------------------*/ @@ -1058,15 +1073,37 @@ static int Encode(Tcl_Interp *interp, int objc, fError = 1; } else { Tk_PhotoImageBlock sImageBlock; - sImageBlock.pixelPtr = (unsigned char *) hSymbol->bitmap; - sImageBlock.width = hSymbol->bitmap_width; - sImageBlock.height = hSymbol->bitmap_height; - sImageBlock.pitch = 3*hSymbol->bitmap_width; - sImageBlock.pixelSize = 3; - sImageBlock.offset[0] = 0; - sImageBlock.offset[1] = 1; - sImageBlock.offset[2] = 2; - sImageBlock.offset[3] = 0; + char * pImageRGBA = NULL; + if (hSymbol->alphamap == NULL) { + sImageBlock.pixelPtr = (unsigned char *) hSymbol->bitmap; + sImageBlock.width = hSymbol->bitmap_width; + sImageBlock.height = hSymbol->bitmap_height; + sImageBlock.pitch = 3*hSymbol->bitmap_width; + sImageBlock.pixelSize = 3; + sImageBlock.offset[0] = 0; + sImageBlock.offset[1] = 1; + sImageBlock.offset[2] = 2; + sImageBlock.offset[3] = 0; + } else { + int index; + /* Alpha channel present - prepare the image data in rgba order */ + pImageRGBA = ckalloc(hSymbol->bitmap_width*hSymbol->bitmap_height*4); + for (index = 0; index < hSymbol->bitmap_width*hSymbol->bitmap_height; index++) { + pImageRGBA[index*4] = hSymbol->bitmap[index*3]; + pImageRGBA[index*4+1] = hSymbol->bitmap[index*3+1]; + pImageRGBA[index*4+2] = hSymbol->bitmap[index*3+2]; + pImageRGBA[index*4+3] = hSymbol->alphamap[index]; + } + sImageBlock.pixelPtr = (unsigned char *) pImageRGBA; + sImageBlock.width = hSymbol->bitmap_width; + sImageBlock.height = hSymbol->bitmap_height; + sImageBlock.pitch = 4*hSymbol->bitmap_width; + sImageBlock.pixelSize = 4; + sImageBlock.offset[0] = 0; + sImageBlock.offset[1] = 1; + sImageBlock.offset[2] = 2; + sImageBlock.offset[3] = 3; + } if (0 == destWidth) { destWidth = hSymbol->bitmap_width; } @@ -1079,6 +1116,9 @@ static int Encode(Tcl_Interp *interp, int objc, { fError = 1; } + if (pImageRGBA != NULL) { + ckfree(pImageRGBA); + } } } /*------------------------------------------------------------------------*/ diff --git a/frontend_qt/howto_build_qzint_using_msvs2015.txt b/frontend_qt/howto_build_qzint_using_msvs2015.txt index e132a1cb..44605080 100644 --- a/frontend_qt/howto_build_qzint_using_msvs2015.txt +++ b/frontend_qt/howto_build_qzint_using_msvs2015.txt @@ -2,28 +2,29 @@ Harald Oehlmann 2017-03-29 How to build qzint.exe using: -- QT 5.7 installed in C:\qt\Qt5.7.1 - 32 bit (use the offline installer and the 32 bit package) +- QT 5.15.0 source package - MS Visual Studio 2015 (VC12) Build static Qt: --------------- -- Download: qt-opensource-windows-x86-msvc2015-5.7.1.exe -- Klick option "source" and deselect all other special modules. -- Install to C:\qt\5.7.1 (or another folder, then change the folders in the following) -- Install Python (ActivePython-2.7.13.2713-win64-x64-401787.exe) +- Go to: https://www.qt.io/offline-installers +- Download the zip "Qt 5.15.x source packages" (nearly 1 GB): + http://download.qt.io/official_releases/qt/5.15/5.15.0/single/qt-everywhere-src-5.15.0.zip +- Unzip to C:\qt resulting in having the source in c:\qt\qt-everywhere-src-5.15.0 +- Install Python (ActivePython-3.7.4.0000-win64-x64-e0b99d60.msi) and make it available within the path. - Start the VS2015 x86 native console by the start menu entry: Visual Studio 2015\Visual Studio Tools\Windows Desktop Command Prompts\VS2015 x86 Native Tools-Eingabeaufforderung -- cd C:\Qt\5.7.1\5.7\Src -- set QMAKESPEC=win32-msvc2015 -- configure.bat -static -release -prefix c:\qt\5.7.1static -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -qt-sql-sqlite -no-openssl -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -mp +- cd C:\qt\qt-everywhere-src-5.15.0 +- configure.bat -static -release -prefix c:\qt\5.15.0static -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -no-openssl -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -mp One may set another destination folder after the -prefix option. Attention, the upper command is one long line. - nmake - nmake install - The last 3 commands run around 3 hours + The last 3 commands run around 3 hours. + Make sure, that python may be found in the path. +- the huge source folder may be deleted to save around 6GB of space. Zint Folder structure: ---------------------- @@ -44,17 +45,27 @@ Build targets "Release Library" for zlib and libpng. Build zint: ----------- - Start in the start menu: "VS2015 x86 Native Tools-Eingabeaufforderung" -- set QTDIR=C:\Qt\5.7.1static -- set PATH=C:\Qt\5.7.1static\bin;%PATH% -- set QMAKESPEC=win32-msvc2015 +- set QTDIR=C:\Qt\5.15.0static +- set PATH=C:\Qt\5.15.0static\bin;%PATH% +- set QMAKESPEC=win32-msvc - cd $ZH - cd backend_qt - qmake backend_qt.pro - nmake clean - nmake release - + - cd ..\frontend_qt - qmake frontend_qt.pro - nmake clean - nmake release -> qzint.exe is in the release folder + +Note: +For me, qt5core.lib was not found in the last step. +I only found the solution to add: + +QMAKE_LIBDIR += C:/qt/5.15.0static/lib + +into frontend_qt.pro + +There is for sure a better solution. \ No newline at end of file