2020-05-22 05:22:28 +12:00
|
|
|
/* output.c - Common routines for raster/vector
|
|
|
|
|
|
|
|
libzint - the open source barcode library
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
Copyright (C) 2020-2023 Robin Stuart <rstuart114@gmail.com>
|
2020-05-22 05:22:28 +12:00
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the project nor the names of its contributors
|
|
|
|
may be used to endorse or promote products derived from this software
|
|
|
|
without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
|
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
SUCH DAMAGE.
|
|
|
|
*/
|
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
libzint: fix some confusing error messages introduced by segment stuff
general: new escape chars \U, \d and \o
backend_qt: fudge rendering of border rectangles due to scaling/translation
rounding errors TODO: better fudge
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
libzint: remove STATIC_UNLESS_ZINT_TEST, use wrappers
CMake: add find package QtSvg, remove QtXml
manual: split symbology and general specs and sort, move DAFT to 4-state,
UPC/EAN -> EAN/UPC, DataBar -> GS1 DataBar always, expand MAILMARK info,
various other fiddlings
man page: options or -> |, expand MSI Plessey check digit options
README.linux: add packages info
license: add SPDX-License-Identifier to touched files
2022-06-10 08:52:02 +12:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
2020-05-22 05:22:28 +12:00
|
|
|
|
2021-11-07 13:21:02 +13:00
|
|
|
#include <assert.h>
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
#include <errno.h>
|
2021-06-20 00:11:23 +12:00
|
|
|
#include <math.h>
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#include <direct.h>
|
|
|
|
#else
|
|
|
|
#include <sys/stat.h> /* mkdir(2) */
|
|
|
|
#endif
|
2020-05-22 05:22:28 +12:00
|
|
|
#include "common.h"
|
|
|
|
#include "output.h"
|
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
#define OUT_SSET_F (IS_NUM_F | IS_UHX_F | IS_LHX_F) /* SSET "0123456789ABCDEFabcdef" */
|
2020-05-22 05:22:28 +12:00
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
/* Helper to check an individual colour option is good */
|
|
|
|
static int out_check_colour(struct zint_symbol *symbol, const char *colour, const char *name) {
|
|
|
|
const char *comma1, *comma2, *comma3;
|
|
|
|
int val;
|
|
|
|
|
|
|
|
if ((comma1 = strchr(colour, ',')) == NULL) {
|
|
|
|
const int len = (int) strlen(colour);
|
|
|
|
if ((len != 6) && (len != 8)) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "880: Malformed %s RGB colour (6 or 8 characters only)", name);
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
if (!is_sane(OUT_SSET_F, (unsigned char *) colour, len)) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "881: Malformed %s RGB colour '%s' (hexadecimal only)", name, colour);
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2020-05-22 05:22:28 +12:00
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
/* CMYK comma-separated percentages */
|
|
|
|
if ((comma2 = strchr(comma1 + 1, ',')) == NULL || (comma3 = strchr(comma2 + 1, ',')) == NULL
|
|
|
|
|| strchr(comma3 + 1, ',') != NULL) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "882: Malformed %s CMYK colour (4 decimal numbers, comma-separated)", name);
|
2020-05-22 05:22:28 +12:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
if (comma1 - colour > 3 || comma2 - (comma1 + 1) > 3 || comma3 - (comma2 + 1) > 3 || strlen(comma3 + 1) > 3) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "883: Malformed %s CMYK colour (3 digit maximum per number)", name);
|
2020-05-22 05:22:28 +12:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
if ((val = to_int((const unsigned char *) colour, (int) (comma1 - colour))) == -1 || val > 100) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "884: Malformed %s CMYK colour C (decimal 0-100 only)", name);
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
if ((val = to_int((const unsigned char *) (comma1 + 1), (int) (comma2 - (comma1 + 1)))) == -1 || val > 100) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "885: Malformed %s CMYK colour M (decimal 0-100 only)", name);
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
if ((val = to_int((const unsigned char *) (comma2 + 1), (int) (comma3 - (comma2 + 1)))) == -1 || val > 100) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "886: Malformed %s CMYK colour Y (decimal 0-100 only)", name);
|
2020-05-22 05:22:28 +12:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
if ((val = to_int((const unsigned char *) (comma3 + 1), (int) strlen(comma3 + 1))) == -1 || val > 100) {
|
2023-02-11 03:44:10 +13:00
|
|
|
sprintf(symbol->errtxt, "887: Malformed %s CMYK colour K (decimal 0-100 only)", name);
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check colour options are good (`symbol->fgcolour`, `symbol->bgcolour`) */
|
|
|
|
INTERNAL int out_check_colour_options(struct zint_symbol *symbol) {
|
2020-05-22 05:22:28 +12:00
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
if (out_check_colour(symbol, symbol->fgcolour, "foreground") != 0) {
|
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
if (out_check_colour(symbol, symbol->bgcolour, "background") != 0) {
|
2020-05-22 05:22:28 +12:00
|
|
|
return ZINT_ERROR_INVALID_OPTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
- `zint_symbol->fgcolour` & `bgcolour` buffer lengths extended 10
-> 16 to allow for "C,M,Y,K" comma-separated decimal percentage
strings
- API/CLI/GUI: allow foreground/background colours to be specified
as comma-separated decimal "C,M,Y,K" strings where "C", "M" etc.
are percentages (0-100) (ticket #281, 3rd point)
- output.c: new funcs `out_colour_get_rgb()` & `out_colour_get_cmyk()`
and use in bmp/emf/gif etc.
- PCX: add alpha support
- GUI: fix fg/gbcolor icon background not being reset on zap
- GUI: Rearrange some Appearance tab inputs (Border Type <-> Width,
Show Text <-> Font, Text/Font <-> Printing Scale/Size) to flow
more naturally (hopefully)
- GUI: save button "Save As..." -> "Save..." and add icon
- CLI: add --bgcolor/colour & --fgcolor/colour synonyms
2023-01-30 08:51:11 +13:00
|
|
|
/* Return RGB(A) from (well-formed) colour string. Returns 0 if RGB or converted CMYK, 1 if RGBA */
|
|
|
|
INTERNAL int out_colour_get_rgb(const char *colour, unsigned char *red, unsigned char *green, unsigned char *blue,
|
|
|
|
unsigned char *alpha) {
|
|
|
|
const char *comma1, *comma2, *comma3;
|
|
|
|
int black, val;
|
|
|
|
|
|
|
|
if ((comma1 = strchr(colour, ',')) == NULL) {
|
|
|
|
*red = 16 * ctoi(colour[0]) + ctoi(colour[1]);
|
|
|
|
*green = 16 * ctoi(colour[2]) + ctoi(colour[3]);
|
|
|
|
*blue = 16 * ctoi(colour[4]) + ctoi(colour[5]);
|
|
|
|
if (alpha) {
|
|
|
|
*alpha = colour[6] ? 16 * ctoi(colour[6]) + ctoi(colour[7]) : 0xFF;
|
|
|
|
return colour[6] ? 1 : 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
comma2 = strchr(comma1 + 1, ',');
|
|
|
|
comma3 = strchr(comma2 + 1, ',');
|
|
|
|
|
|
|
|
black = 100 - to_int((const unsigned char *) (comma3 + 1), (int) strlen(comma3 + 1));
|
|
|
|
|
|
|
|
val = 100 - to_int((const unsigned char *) colour, (int) (comma1 - colour)); /* Cyan */
|
|
|
|
*red = (int) roundf((0xFF * val * black) / 10000.0f);
|
|
|
|
|
|
|
|
val = 100 - to_int((const unsigned char *) (comma1 + 1), (int) (comma2 - (comma1 + 1))); /* Magenta */
|
|
|
|
*green = (int) roundf((0xFF * val * black) / 10000.0f);
|
|
|
|
|
|
|
|
val = 100 - to_int((const unsigned char *) (comma2 + 1), (int) (comma3 - (comma2 + 1))); /* Yellow */
|
|
|
|
*blue = (int) roundf((0xFF * val * black) / 10000.0f);
|
|
|
|
|
|
|
|
if (alpha) {
|
|
|
|
*alpha = 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return CMYK from (well-formed) colour string. Returns 0 if CMYK, 1 if converted RBG, 2 if converted RGBA */
|
|
|
|
INTERNAL int out_colour_get_cmyk(const char *colour, int *cyan, int *magenta, int *yellow, int *black,
|
|
|
|
unsigned char *rgb_alpha) {
|
|
|
|
const char *comma1;
|
|
|
|
unsigned char red, green, blue, alpha;
|
|
|
|
int have_alpha, k;
|
|
|
|
|
|
|
|
if ((comma1 = strchr(colour, ',')) != NULL) {
|
|
|
|
const char *const comma2 = strchr(comma1 + 1, ',');
|
|
|
|
const char *const comma3 = strchr(comma2 + 1, ',');
|
|
|
|
*cyan = to_int((const unsigned char *) colour, (int) (comma1 - colour));
|
|
|
|
*magenta = to_int((const unsigned char *) (comma1 + 1), (int) (comma2 - (comma1 + 1)));
|
|
|
|
*yellow = to_int((const unsigned char *) (comma2 + 1), (int) (comma3 - (comma2 + 1)));
|
|
|
|
*black = to_int((const unsigned char *) (comma3 + 1), (int) strlen(comma3 + 1));
|
|
|
|
if (rgb_alpha) {
|
|
|
|
*rgb_alpha = 0xFF;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
have_alpha = out_colour_get_rgb(colour, &red, &green, &blue, &alpha);
|
|
|
|
|
|
|
|
k = red;
|
|
|
|
if (green > k) {
|
|
|
|
k = green;
|
|
|
|
}
|
|
|
|
if (blue > k) {
|
|
|
|
k = blue;
|
|
|
|
}
|
|
|
|
if (k == 0) {
|
|
|
|
*cyan = *magenta = *yellow = 0;
|
|
|
|
*black = 100;
|
|
|
|
} else {
|
|
|
|
*cyan = (int) roundf((k - red) * 100.0f / k);
|
|
|
|
*magenta = (int) roundf((k - green) * 100.0f / k);
|
|
|
|
*yellow = (int) roundf((k - blue) * 100.0f / k);
|
|
|
|
*black = (int) roundf(((0xFF - k) * 100.0f) / 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rgb_alpha) {
|
|
|
|
*rgb_alpha = have_alpha ? alpha : 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1 + have_alpha;
|
|
|
|
}
|
|
|
|
|
2023-11-20 08:39:54 +13:00
|
|
|
/* Convert internal colour chars "WCBMRYGK" to RGB */
|
|
|
|
INTERNAL int out_colour_char_to_rgb(const char ch, unsigned char *red, unsigned char *green, unsigned char *blue) {
|
|
|
|
static const char chars[] = "WCBMRYGK";
|
|
|
|
static const unsigned char colours[8][3] = {
|
|
|
|
{ 0xff, 0xff, 0xff, }, /* White */
|
|
|
|
{ 0, 0xff, 0xff, }, /* Cyan */
|
|
|
|
{ 0, 0, 0xff, }, /* Blue */
|
|
|
|
{ 0xff, 0, 0xff, }, /* Magenta */
|
|
|
|
{ 0xff, 0, 0, }, /* Red */
|
|
|
|
{ 0xff, 0xff, 0, }, /* Yellow */
|
|
|
|
{ 0, 0xff, 0, }, /* Green */
|
|
|
|
{ 0, 0, 0, }, /* Black */
|
|
|
|
};
|
|
|
|
int i = posn(chars, ch);
|
|
|
|
int ret = i != -1;
|
|
|
|
|
|
|
|
if (i == -1) {
|
|
|
|
i = 7; /* Black (zeroize) */
|
|
|
|
}
|
|
|
|
if (red) {
|
|
|
|
*red = colours[i][0];
|
|
|
|
}
|
|
|
|
if (green) {
|
|
|
|
*green = colours[i][1];
|
|
|
|
}
|
|
|
|
if (blue) {
|
|
|
|
*blue = colours[i][2];
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-05-22 05:22:28 +12:00
|
|
|
/* Return minimum quiet zones for each symbology */
|
2023-06-12 12:25:55 +12:00
|
|
|
static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, const int comp_xoffset,
|
2021-09-25 00:21:24 +12:00
|
|
|
float *left, float *right, float *top, float *bottom) {
|
2020-07-16 06:00:12 +12:00
|
|
|
int done = 0;
|
|
|
|
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 0.0f;
|
2020-05-22 05:22:28 +12:00
|
|
|
|
2020-07-16 06:00:12 +12:00
|
|
|
/* These always have quiet zones set (previously used whitespace_width) */
|
2020-05-22 05:22:28 +12:00
|
|
|
switch (symbol->symbology) {
|
|
|
|
case BARCODE_CODE16K:
|
2020-07-16 06:00:12 +12:00
|
|
|
/* BS EN 12323:2005 Section 4.5 (c) */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*left = 10.0f;
|
|
|
|
*right = 1.0f;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
2020-05-22 05:22:28 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_CODE49:
|
|
|
|
/* ANSI/AIM BC6-2000 Section 2.4 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*left = 10.0f;
|
|
|
|
*right = 1.0f;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
2020-05-22 05:22:28 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_CODABLOCKF:
|
|
|
|
case BARCODE_HIBC_BLOCKF:
|
|
|
|
/* AIM ISS-X-24 Section 4.6.1 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_ITF14:
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.3.2.2 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_EANX:
|
|
|
|
case BARCODE_EANX_CHK:
|
|
|
|
case BARCODE_EANX_CC:
|
|
|
|
case BARCODE_ISBNX:
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.2.3.4 */
|
2020-07-16 06:00:12 +12:00
|
|
|
switch (ustrlen(symbol->text)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
case 13: /* EAN-13/ISBN */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 10 ? 1.0f : 11.0f - comp_xoffset; /* Need at least 1X for CC-A/B */
|
|
|
|
*right = 7.0f - (comp_xoffset != 0);
|
2021-09-25 00:21:24 +12:00
|
|
|
} else if (!hide_text) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 10 ? 1.0f : 11.0f - comp_xoffset; /* Need for outside left digit */
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
2023-06-12 12:25:55 +12:00
|
|
|
case 16: /* EAN-13/ISBN + 2 digit add-on */
|
|
|
|
case 19: /* EAN-13/ISBN + 5 digit add-on */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 10 ? 1.0f : 11.0f - comp_xoffset; /* Need at least 1X for CC-A/B */
|
2021-09-25 00:21:24 +12:00
|
|
|
*right = 5.0f;
|
|
|
|
} else if (!hide_text) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 10 ? 1.0f : 11.0f - comp_xoffset; /* Need for outside left digit */
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
2023-06-12 12:25:55 +12:00
|
|
|
case 5: /* EAN-5 add-on */
|
|
|
|
case 2: /* EAN-2 add-on */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*right = 5.0f;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
2023-06-12 12:25:55 +12:00
|
|
|
case 8: /* EAN-8 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 6 ? 1.0f : 7.0f - comp_xoffset; /* Need at least 1X for CC-A/B */
|
|
|
|
*right = 7.0f - (comp_xoffset != 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default: /* EAN-8 + 2/5 digit add-on */
|
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
|
|
|
*left = comp_xoffset >= 6 ? 1.0f : 7.0f - comp_xoffset; /* Need at least 1X for CC-A/B */
|
|
|
|
*right = 5.0f;
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_UPCA:
|
|
|
|
case BARCODE_UPCA_CHK:
|
|
|
|
case BARCODE_UPCA_CC:
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.2.3.4 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 8 ? 1.0f : 9.0f - comp_xoffset; /* Need at least 1X for CC-A/B */
|
|
|
|
if (ustrlen(symbol->text) > 12) { /* UPC-A + add-on */
|
2021-09-25 00:21:24 +12:00
|
|
|
*right = 5.0f;
|
|
|
|
} else {
|
2023-06-12 12:25:55 +12:00
|
|
|
*right = 9.0f - (comp_xoffset != 0);
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
|
|
|
} else if (!hide_text) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 8 ? 1.0f : 9.0f - comp_xoffset; /* Need for outside left digit */
|
|
|
|
if (ustrlen(symbol->text) <= 12) { /* No add-on */
|
|
|
|
*right = 9.0f - (comp_xoffset != 0); /* Need for outside right digit */
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
}
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_UPCE:
|
|
|
|
case BARCODE_UPCE_CHK:
|
|
|
|
case BARCODE_UPCE_CC:
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.2.3.4 */
|
2021-09-25 00:21:24 +12:00
|
|
|
if (!(symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 8 ? 1.0f : 9.0f - comp_xoffset;
|
|
|
|
if (ustrlen(symbol->text) > 8) { /* UPC-E + add-on */
|
2021-09-25 00:21:24 +12:00
|
|
|
*right = 5.0f;
|
|
|
|
} else {
|
2023-06-12 12:25:55 +12:00
|
|
|
*right = 7.0f - (comp_xoffset != 0);
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
|
|
|
} else if (!hide_text) {
|
2023-06-12 12:25:55 +12:00
|
|
|
*left = comp_xoffset >= 8 ? 1.0f : 9.0f - comp_xoffset; /* Need for outside left digit */
|
|
|
|
if (ustrlen(symbol->text) <= 8) { /* No add-on */
|
|
|
|
*right = 7.0f - (comp_xoffset != 0); /* Need for outside right digit */
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
}
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (done) {
|
|
|
|
return done;
|
|
|
|
}
|
|
|
|
|
2021-09-25 00:21:24 +12:00
|
|
|
/* Only do others if flag set */
|
|
|
|
if (!(symbol->output_options & BARCODE_QUIET_ZONES) || (symbol->output_options & BARCODE_NO_QUIET_ZONES)) {
|
2021-10-21 11:05:30 +13:00
|
|
|
return 0;
|
2020-07-16 06:00:12 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (symbol->symbology) {
|
|
|
|
case BARCODE_CODE11:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* No known standard. Following ITF-14, set to 10X */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_C25INTER:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* ISO/IEC 16390:2007 Section 4.4 10X */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_C25STANDARD:
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_C25IATA:
|
|
|
|
case BARCODE_C25LOGIC:
|
|
|
|
case BARCODE_C25IND:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* No known standards. Following C25INTER, set to 10X */
|
|
|
|
*left = *right = 10.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_CODE39:
|
|
|
|
case BARCODE_EXCODE39:
|
|
|
|
case BARCODE_LOGMARS:
|
|
|
|
case BARCODE_PZN:
|
|
|
|
case BARCODE_VIN:
|
|
|
|
case BARCODE_HIBC_39:
|
|
|
|
case BARCODE_CODE32:
|
|
|
|
/* ISO/IEC 16388:2007 Section 4.4 (d) */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 10.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_GS1_128: /* GS1-128 */
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_EAN14:
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.4.4.2 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 10.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2023-06-12 12:25:55 +12:00
|
|
|
case BARCODE_GS1_128_CC:
|
|
|
|
/* GS1 General Specifications 21.0.1 Sections 5.11.2.1 (CC-A), 5.11.2.2 (CC-B) & 5.11.2.3 (CC-C) */
|
|
|
|
{
|
|
|
|
int comp_roffset = 0; /* Right offset of linear */
|
|
|
|
int min_qz; /* Minimum quiet zone - 1X for CC-A/B, 2X for CC-C */
|
|
|
|
int x;
|
|
|
|
for (x = symbol->width - 1; x >= 0 && !module_is_set(symbol, symbol->rows - 1, x); x--) {
|
|
|
|
comp_roffset++;
|
|
|
|
}
|
|
|
|
/* Determine if CC-C by counting initial start pattern */
|
|
|
|
for (x = 0; x < 8 && module_is_set(symbol, 0, x); x++);
|
|
|
|
min_qz = x == 8 ? 2 : 1;
|
|
|
|
*left = comp_xoffset >= 10 - min_qz ? min_qz : 10.0f - comp_xoffset;
|
|
|
|
*right = comp_roffset >= 10 - min_qz ? min_qz : 10.0f - comp_roffset;
|
|
|
|
}
|
|
|
|
done = 1;
|
|
|
|
break;
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_CODABAR:
|
|
|
|
/* BS EN 798:1995 Section 4.4.1 (d) */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 10.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_CODE128:
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
case BARCODE_CODE128AB:
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_HIBC_128:
|
|
|
|
case BARCODE_NVE18:
|
|
|
|
/* ISO/IEC 15417:2007 4.4.2 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 10.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_DPLEIT:
|
|
|
|
case BARCODE_DPIDENT:
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
/* Using C25INTER values TODO: Find doc */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_CODE93:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* ANSI/AIM BC5-1995 Section 2.4 */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_FLAT:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* TODO: Find doc (application defined according to TEC-IT) */
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_DBAR_OMN: /* GS1 Databar Omnidirectional */
|
|
|
|
case BARCODE_DBAR_LTD: /* GS1 Databar Limited */
|
|
|
|
case BARCODE_DBAR_EXP: /* GS1 Databar Expanded */
|
|
|
|
case BARCODE_DBAR_STK: /* GS1 DataBar Stacked */
|
|
|
|
case BARCODE_DBAR_OMNSTK: /* GS1 DataBar Stacked Omnidirectional */
|
|
|
|
case BARCODE_DBAR_EXPSTK: /* GS1 Databar Expanded Stacked */
|
2021-01-29 12:41:54 +13:00
|
|
|
/* GS1 General Specifications 21.0.1 Section 5.5.1.1 - Quiet Zones: None required */
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2023-06-12 12:25:55 +12:00
|
|
|
|
|
|
|
/* GS1 General Specifications 21.0.1 Sections 5.11.2.1 (CC-A) & 5.11.2.2 (CC-B) require 1X either side
|
|
|
|
but this may be supplied by the positioning of the linear component */
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_DBAR_OMN_CC:
|
|
|
|
case BARCODE_DBAR_LTD_CC:
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Always have at least 1X to right of CC-A/B */
|
|
|
|
if (comp_xoffset > 1) { /* Exclude DBAR_LTD_CC with CC-A which always has 1X to left */
|
|
|
|
*left = 1.0f;
|
|
|
|
}
|
|
|
|
done = 1;
|
|
|
|
break;
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_DBAR_STK_CC:
|
|
|
|
case BARCODE_DBAR_OMNSTK_CC:
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Always have at least 1X to left of CC-A/B */
|
|
|
|
*right = 1.0f;
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_DBAR_EXP_CC:
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_DBAR_EXPSTK_CC:
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Always have at least 1X to left and right of CC-A/B */
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_TELEPEN:
|
|
|
|
case BARCODE_TELEPEN_NUM:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* Appears to be ~10X from diagram in Telepen Barcode Symbology information and History */
|
|
|
|
/* TODO: Find better doc */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_POSTNET:
|
|
|
|
case BARCODE_PLANET:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* USPS DMM 300 2006 (2011) 5.7 Barcode in Address Block
|
|
|
|
left/right 0.125" / 0.025" (X max) = 5, top/bottom 0.04" / 0.025" (X max) = 1.6 */
|
|
|
|
*left = *right = 5.0f;
|
|
|
|
*top = *bottom = 1.6f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2022-08-21 07:45:51 +12:00
|
|
|
case BARCODE_CEPNET:
|
|
|
|
/* CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) 3.8 Localização */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
*top = *bottom = 1.6f; /* As POSTNET (1.016mm == 0.025") */
|
|
|
|
done = 1;
|
|
|
|
break;
|
2020-07-16 06:00:12 +12:00
|
|
|
|
|
|
|
case BARCODE_MSI_PLESSEY:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* TODO Find doc (TEC-IT says 12X so use that for the moment) */
|
|
|
|
*left = *right = 12.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_FIM:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* USPS DMM 300 2006 (2011) 708.9.3 (top/bottom zero)
|
|
|
|
right 0.125" (min) / 0.03925" (X max) ~ 3.18, left 1.25" - 0.66725" (max width of barcode)
|
|
|
|
- 0.375 (max right) = 0.20775" / 0.03925" (X max) ~ 5.29 */
|
|
|
|
*right = (float) (0.125 / 0.03925);
|
|
|
|
*left = (float) (0.20775 / 0.03925);
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_PHARMA:
|
|
|
|
case BARCODE_PHARMA_TWO:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Laetus Pharmacode Guide 2.2 from 6mm depending on context, 6mm / 1mm (Pharma Two X) = 6 */
|
|
|
|
*left = *right = 6.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_PDF417:
|
2020-07-30 09:35:31 +12:00
|
|
|
case BARCODE_PDF417COMP:
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_HIBC_PDF:
|
|
|
|
/* ISO/IEC 15438:2015 Section 5.8.3 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 2.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_MICROPDF417:
|
|
|
|
case BARCODE_HIBC_MICPDF:
|
|
|
|
/* ISO/IEC 24728:2006 Section 5.8.3 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 1.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_MAXICODE:
|
|
|
|
/* ISO/IEC 16023:2000 Section 4.11.5 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 1.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_QRCODE:
|
|
|
|
case BARCODE_UPNQR:
|
|
|
|
case BARCODE_HIBC_QR:
|
|
|
|
/* ISO/IEC 18004:2015 Section 9.1 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 4.0f;
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_DPD:
|
2022-11-11 11:13:41 +13:00
|
|
|
/* DPD Parcel Label Specification Version 2.4.1 Section 4.6.1.2, 5mm / 0.4mm (X max) = 12.5 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = 12.5f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_MICROQR:
|
|
|
|
/* ISO/IEC 18004:2015 Section 9.1 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 2.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_RMQR:
|
|
|
|
/* ISO/IEC JTC1/SC31N000 Section 6.3.10 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 2.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_AUSPOST:
|
|
|
|
case BARCODE_AUSREPLY:
|
|
|
|
case BARCODE_AUSROUTE:
|
|
|
|
case BARCODE_AUSREDIRECT:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Customer Barcode Technical Specifications (2012) left/right 6mm / 0.6mm = 10,
|
|
|
|
top/bottom 2mm / 0.6mm ~ 3.33 (X max) */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
*top = *bottom = (float) (2.0 / 0.6);
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_RM4SCC:
|
2022-12-09 02:48:31 +13:00
|
|
|
/* Royal Mail Know How User's Manual Appendix C: using CBC, same as MAILMARK_4S, 2mm all round,
|
2021-06-20 00:11:23 +12:00
|
|
|
use X max (25.4mm / 39) i.e. 20 bars per 25.4mm */
|
|
|
|
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_DATAMATRIX:
|
|
|
|
case BARCODE_HIBC_DM:
|
|
|
|
/* ISO/IEC 16022:2006 Section 7.1 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 1.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_JAPANPOST:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Japan Post Zip/Barcode Manual p.13 2mm all round, X 0.6mm, 2mm / 0.6mm ~ 3.33 */
|
|
|
|
*left = *right = *top = *bottom = (float) (2.0 / 0.6);
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_KOREAPOST:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* TODO Find doc (TEC-IT uses 10X but says not exactly specified - do the same for the moment) */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
2020-07-30 07:43:08 +12:00
|
|
|
case BARCODE_USPS_IMAIL:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* USPS-B-3200 (2015) Section 2.3.2 left/right 0.125", top/bottom 0.026", use X max (1 / 39)
|
|
|
|
i.e. 20 bars per inch */
|
|
|
|
*left = *right = 0.125f * 39.0f; /* 4.875 */
|
|
|
|
*top = *bottom = 0.026f * 39.0f; /* 1.014 */
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_PLESSEY:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* TODO Find doc (see MSI_PLESSEY) */
|
|
|
|
*left = *right = 12.0f;
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_KIX:
|
2022-12-09 02:48:31 +13:00
|
|
|
/* Handleiding KIX code brochure - same as RM4SCC/MAILMARK_4S */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_AZTEC:
|
|
|
|
case BARCODE_HIBC_AZTEC:
|
|
|
|
case BARCODE_AZRUNE:
|
|
|
|
/* ISO/IEC 24778:2008 Section 4.1 (c) & Annex A.1 (Rune) - no quiet zone required */
|
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_DAFT:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Generic so unlikely to be defined */
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
case BARCODE_DOTCODE:
|
|
|
|
/* ISS DotCode Rev. 4.0 Section 4.1 (3) (c) */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 3.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_HANXIN:
|
|
|
|
/* ISO/IEC DIS 20830:2019 Section 4.2.8 (also Section 6.2) */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 3.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2022-12-09 02:48:31 +13:00
|
|
|
case BARCODE_MAILMARK_4S:
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Royal Mail Mailmark Barcode Definition Document Section 3.5.2, 2mm all round, use X max (25.4mm / 39)
|
|
|
|
i.e. 20 bars per 25.4mm */
|
|
|
|
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
2022-12-10 03:51:26 +13:00
|
|
|
case BARCODE_UPU_S10:
|
|
|
|
/* Universal Postal Union S10 Section 8 */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
|
|
|
break;
|
2022-12-09 02:48:31 +13:00
|
|
|
case BARCODE_MAILMARK_2D:
|
|
|
|
/* Royal Mail Mailmark Barcode Definition Document, Section 2.4 */
|
|
|
|
*left = *right = *top = *bottom = 4.0f;
|
|
|
|
done = 1;
|
|
|
|
break;
|
2020-07-16 06:00:12 +12:00
|
|
|
case BARCODE_CHANNEL:
|
|
|
|
/* ANSI/AIM BC12-1998 Section 4.4 (c) */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = 1.0f;
|
|
|
|
*right = 2.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_CODEONE:
|
2021-09-25 00:21:24 +12:00
|
|
|
/* USS Code One AIM 1994 Section 2.2.4 No quiet zone required for Versions A to H */
|
|
|
|
if (symbol->option_2 == 9 || symbol->option_2 == 10) { /* Section 2.3.2 Versions S & T */
|
2023-07-08 12:02:51 +12:00
|
|
|
*left = *right = *bottom = 1.0f;
|
2021-09-25 00:21:24 +12:00
|
|
|
}
|
|
|
|
done = 1;
|
2020-07-16 06:00:12 +12:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BARCODE_GRIDMATRIX:
|
|
|
|
/* AIMD014 (v 1.63) Section 7.1 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 6.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
|
|
|
break;
|
|
|
|
case BARCODE_ULTRA:
|
|
|
|
/* AIMD/TSC15032-43 (v 0.99c) Section 9.2 */
|
2021-06-20 00:11:23 +12:00
|
|
|
*left = *right = *top = *bottom = 1.0f;
|
2020-07-16 06:00:12 +12:00
|
|
|
done = 1;
|
2022-07-21 23:29:53 +12:00
|
|
|
break;
|
2022-07-04 10:54:42 +12:00
|
|
|
|
|
|
|
case BARCODE_BC412:
|
2022-07-21 23:29:53 +12:00
|
|
|
/* SEMI T1-95 Table 4 */
|
|
|
|
*left = *right = 10.0f;
|
|
|
|
done = 1;
|
2020-05-22 05:22:28 +12:00
|
|
|
break;
|
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
|
|
|
|
return done; /* For self-checking */
|
2020-05-22 05:22:28 +12:00
|
|
|
}
|
|
|
|
|
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
libzint: fix some confusing error messages introduced by segment stuff
general: new escape chars \U, \d and \o
backend_qt: fudge rendering of border rectangles due to scaling/translation
rounding errors TODO: better fudge
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
libzint: remove STATIC_UNLESS_ZINT_TEST, use wrappers
CMake: add find package QtSvg, remove QtXml
manual: split symbology and general specs and sort, move DAFT to 4-state,
UPC/EAN -> EAN/UPC, DataBar -> GS1 DataBar always, expand MAILMARK info,
various other fiddlings
man page: options or -> |, expand MSI Plessey check digit options
README.linux: add packages info
license: add SPDX-License-Identifier to touched files
2022-06-10 08:52:02 +12:00
|
|
|
#ifdef ZINT_TEST /* Wrapper for direct testing */
|
2023-06-12 12:25:55 +12:00
|
|
|
INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hide_text, const int comp_xoffset,
|
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
libzint: fix some confusing error messages introduced by segment stuff
general: new escape chars \U, \d and \o
backend_qt: fudge rendering of border rectangles due to scaling/translation
rounding errors TODO: better fudge
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
libzint: remove STATIC_UNLESS_ZINT_TEST, use wrappers
CMake: add find package QtSvg, remove QtXml
manual: split symbology and general specs and sort, move DAFT to 4-state,
UPC/EAN -> EAN/UPC, DataBar -> GS1 DataBar always, expand MAILMARK info,
various other fiddlings
man page: options or -> |, expand MSI Plessey check digit options
README.linux: add packages info
license: add SPDX-License-Identifier to touched files
2022-06-10 08:52:02 +12:00
|
|
|
float *left, float *right, float *top, float *bottom) {
|
2023-06-12 12:25:55 +12:00
|
|
|
return out_quiet_zones(symbol, hide_text, comp_xoffset, left, right, top, bottom);
|
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
libzint: fix some confusing error messages introduced by segment stuff
general: new escape chars \U, \d and \o
backend_qt: fudge rendering of border rectangles due to scaling/translation
rounding errors TODO: better fudge
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
libzint: remove STATIC_UNLESS_ZINT_TEST, use wrappers
CMake: add find package QtSvg, remove QtXml
manual: split symbology and general specs and sort, move DAFT to 4-state,
UPC/EAN -> EAN/UPC, DataBar -> GS1 DataBar always, expand MAILMARK info,
various other fiddlings
man page: options or -> |, expand MSI Plessey check digit options
README.linux: add packages info
license: add SPDX-License-Identifier to touched files
2022-06-10 08:52:02 +12:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-11-20 08:39:54 +13:00
|
|
|
/* Set left (x), top (y), right and bottom offsets for whitespace, also right quiet zone */
|
2021-10-21 11:05:30 +13:00
|
|
|
INTERNAL void out_set_whitespace_offsets(const struct zint_symbol *symbol, const int hide_text,
|
2023-11-20 08:39:54 +13:00
|
|
|
const int comp_xoffset, float *p_xoffset, float *p_yoffset, float *p_roffset, float *p_boffset,
|
|
|
|
float *p_qz_right, const float scaler, int *p_xoffset_si, int *p_yoffset_si, int *p_roffset_si,
|
|
|
|
int *p_boffset_si, int *p_qz_right_si) {
|
2021-06-20 00:11:23 +12:00
|
|
|
float qz_left, qz_right, qz_top, qz_bottom;
|
2020-05-22 05:22:28 +12:00
|
|
|
|
2023-06-12 12:25:55 +12:00
|
|
|
out_quiet_zones(symbol, hide_text, comp_xoffset, &qz_left, &qz_right, &qz_top, &qz_bottom);
|
2020-05-22 05:22:28 +12:00
|
|
|
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_xoffset = symbol->whitespace_width + qz_left;
|
|
|
|
*p_roffset = symbol->whitespace_width + qz_right;
|
2020-05-22 05:22:28 +12:00
|
|
|
if (symbol->output_options & BARCODE_BOX) {
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_xoffset += symbol->border_width;
|
|
|
|
*p_roffset += symbol->border_width;
|
2020-05-22 05:22:28 +12:00
|
|
|
}
|
|
|
|
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_yoffset = symbol->whitespace_height + qz_top;
|
|
|
|
*p_boffset = symbol->whitespace_height + qz_bottom;
|
2022-11-11 11:13:41 +13:00
|
|
|
if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP)) {
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_yoffset += symbol->border_width;
|
2023-12-15 23:51:51 +13:00
|
|
|
if (!(symbol->output_options & BARCODE_BIND_TOP)) { /* Trumps BARCODE_BOX & BARCODE_BIND */
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_boffset += symbol->border_width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p_qz_right) {
|
|
|
|
*p_qz_right = qz_right;
|
2020-05-22 05:22:28 +12:00
|
|
|
}
|
2021-09-21 01:56:27 +12:00
|
|
|
|
|
|
|
if (scaler) {
|
2023-11-20 08:39:54 +13:00
|
|
|
if (p_xoffset_si) {
|
|
|
|
*p_xoffset_si = (int) (*p_xoffset * scaler);
|
|
|
|
}
|
|
|
|
if (p_yoffset_si) {
|
|
|
|
*p_yoffset_si = (int) (*p_yoffset * scaler);
|
2021-09-21 01:56:27 +12:00
|
|
|
}
|
2023-11-20 08:39:54 +13:00
|
|
|
if (p_roffset_si) {
|
|
|
|
*p_roffset_si = (int) (*p_roffset * scaler);
|
2021-09-21 01:56:27 +12:00
|
|
|
}
|
2023-11-20 08:39:54 +13:00
|
|
|
if (p_boffset_si) {
|
|
|
|
*p_boffset_si = (int) (*p_boffset * scaler);
|
2021-09-21 01:56:27 +12:00
|
|
|
}
|
2023-11-20 08:39:54 +13:00
|
|
|
if (p_qz_right_si) {
|
|
|
|
*p_qz_right_si = (int) (qz_right * scaler);
|
2021-09-21 01:56:27 +12:00
|
|
|
}
|
|
|
|
}
|
2020-05-22 05:22:28 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Set composite offset and main width excluding add-on (for start of add-on calc) and add-on text, returning
|
2023-11-20 08:39:54 +13:00
|
|
|
EAN/UPC type */
|
2023-06-12 12:25:55 +12:00
|
|
|
INTERNAL int out_process_upcean(const struct zint_symbol *symbol, const int comp_xoffset, int *p_main_width,
|
2023-11-20 08:39:54 +13:00
|
|
|
unsigned char addon[6], int *p_addon_len, int *p_addon_gap) {
|
2023-06-12 12:25:55 +12:00
|
|
|
int main_width; /* Width of main linear symbol, excluding add-on */
|
2023-11-20 08:39:54 +13:00
|
|
|
int upceanflag; /* EAN/UPC type flag */
|
2020-07-16 06:00:12 +12:00
|
|
|
int i, j, latch;
|
2023-06-12 12:25:55 +12:00
|
|
|
const int text_length = (int) ustrlen(symbol->text);
|
2020-07-16 06:00:12 +12:00
|
|
|
|
|
|
|
latch = 0;
|
|
|
|
j = 0;
|
|
|
|
/* Isolate add-on text */
|
|
|
|
for (i = 6; i < text_length && j < 5; i++) {
|
|
|
|
if (latch == 1) {
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Use dummy space-filled add-on if no hrt */
|
|
|
|
addon[j] = symbol->show_hrt ? symbol->text[i] : ' ';
|
2020-07-16 06:00:12 +12:00
|
|
|
j++;
|
|
|
|
} else if (symbol->text[i] == '+') {
|
|
|
|
latch = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addon[j] = '\0';
|
|
|
|
if (latch) {
|
2023-11-20 08:39:54 +13:00
|
|
|
*p_addon_len = (int) ustrlen(addon);
|
2021-06-20 00:11:23 +12:00
|
|
|
if (symbol->symbology == BARCODE_UPCA || symbol->symbology == BARCODE_UPCA_CHK
|
|
|
|
|| symbol->symbology == BARCODE_UPCA_CC) {
|
2020-07-16 06:00:12 +12:00
|
|
|
*p_addon_gap = symbol->option_2 >= 9 && symbol->option_2 <= 12 ? symbol->option_2 : 9;
|
|
|
|
} else {
|
|
|
|
*p_addon_gap = symbol->option_2 >= 7 && symbol->option_2 <= 12 ? symbol->option_2 : 7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
upceanflag = 0;
|
|
|
|
main_width = symbol->width;
|
|
|
|
if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CHK)
|
|
|
|
|| (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) {
|
|
|
|
switch (text_length) {
|
|
|
|
case 13: /* EAN-13 */
|
|
|
|
case 16: /* EAN-13 + EAN-2 */
|
|
|
|
case 19: /* EAN-13 + EAN-5 */
|
2021-09-21 01:56:27 +12:00
|
|
|
main_width = 95 + comp_xoffset; /* EAN-13 main symbol 95 modules wide */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 13;
|
|
|
|
break;
|
|
|
|
case 2:
|
2023-06-12 12:25:55 +12:00
|
|
|
/* EAN-2 can't have add-on or be composite */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 2;
|
|
|
|
break;
|
|
|
|
case 5:
|
2023-06-12 12:25:55 +12:00
|
|
|
/* EAN-5 can't have add-on or be composite */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 5;
|
|
|
|
break;
|
|
|
|
default:
|
2021-09-21 01:56:27 +12:00
|
|
|
main_width = 68 + comp_xoffset; /* EAN-8 main symbol 68 modules wide */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CHK)
|
|
|
|
|| (symbol->symbology == BARCODE_UPCA_CC)) {
|
2021-09-21 01:56:27 +12:00
|
|
|
main_width = 95 + comp_xoffset; /* UPC-A main symbol 95 modules wide */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 12;
|
|
|
|
} else if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CHK)
|
|
|
|
|| (symbol->symbology == BARCODE_UPCE_CC)) {
|
2021-09-21 01:56:27 +12:00
|
|
|
main_width = 51 + comp_xoffset; /* UPC-E main symbol 51 modules wide */
|
2020-07-16 06:00:12 +12:00
|
|
|
upceanflag = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p_main_width = main_width;
|
|
|
|
|
|
|
|
return upceanflag;
|
|
|
|
}
|
|
|
|
|
2021-06-20 00:11:23 +12:00
|
|
|
/* Calculate large bar height i.e. linear bars with zero row height that respond to the symbol height.
|
2021-10-21 11:05:30 +13:00
|
|
|
If scaler `si` non-zero (raster), then large_bar_height if non-zero or else row heights will be rounded
|
|
|
|
to nearest pixel and symbol height adjusted */
|
2023-02-11 03:44:10 +13:00
|
|
|
INTERNAL float out_large_bar_height(struct zint_symbol *symbol, const int si, int *row_heights_si,
|
|
|
|
int *symbol_height_si) {
|
2021-06-20 00:11:23 +12:00
|
|
|
float fixed_height = 0.0f;
|
|
|
|
int zero_count = 0;
|
|
|
|
int round_rows = 0;
|
|
|
|
int i;
|
2021-11-07 13:21:02 +13:00
|
|
|
float large_bar_height = 0.0f; /* Not used if zero_count zero */
|
2020-07-16 06:00:12 +12:00
|
|
|
|
2021-11-07 13:21:02 +13:00
|
|
|
if (si) {
|
|
|
|
for (i = 0; i < symbol->rows; i++) {
|
|
|
|
if (symbol->row_height[i]) {
|
|
|
|
fixed_height += symbol->row_height[i];
|
|
|
|
if (!round_rows && !isfintf(symbol->row_height[i] * si)) {
|
|
|
|
round_rows = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
zero_count++;
|
2021-06-20 00:11:23 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
}
|
|
|
|
|
2021-11-07 13:21:02 +13:00
|
|
|
if (zero_count) {
|
|
|
|
large_bar_height = stripf((symbol->height - fixed_height) / zero_count);
|
|
|
|
assert(large_bar_height >= 0.5f); /* Min row height as set by `set_height()` */
|
|
|
|
if (!isfintf(large_bar_height * si)) {
|
|
|
|
large_bar_height = stripf(roundf(large_bar_height * si) / si);
|
|
|
|
}
|
|
|
|
symbol->height = stripf(large_bar_height * zero_count + fixed_height);
|
|
|
|
/* Note should never happen that have both zero_count and round_rows */
|
|
|
|
} else {
|
|
|
|
if (round_rows) {
|
|
|
|
float total_height = 0.0f;
|
|
|
|
for (i = 0; i < symbol->rows; i++) {
|
|
|
|
if (!isfintf(symbol->row_height[i] * si)) {
|
|
|
|
symbol->row_height[i] = roundf(symbol->row_height[i] * si) / si;
|
|
|
|
}
|
|
|
|
total_height += symbol->row_height[i];
|
|
|
|
}
|
|
|
|
symbol->height = stripf(total_height);
|
|
|
|
}
|
2021-06-20 00:11:23 +12:00
|
|
|
}
|
2021-11-07 13:21:02 +13:00
|
|
|
|
|
|
|
if (row_heights_si) {
|
|
|
|
assert(symbol_height_si);
|
|
|
|
*symbol_height_si = 0;
|
2021-06-20 00:11:23 +12:00
|
|
|
for (i = 0; i < symbol->rows; i++) {
|
2021-11-07 13:21:02 +13:00
|
|
|
if (symbol->row_height[i]) {
|
|
|
|
row_heights_si[i] = (int) roundf(symbol->row_height[i] * si);
|
|
|
|
} else {
|
|
|
|
row_heights_si[i] = (int) roundf(large_bar_height * si);
|
2021-06-20 00:11:23 +12:00
|
|
|
}
|
2021-11-07 13:21:02 +13:00
|
|
|
*symbol_height_si += row_heights_si[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < symbol->rows; i++) {
|
|
|
|
if (symbol->row_height[i]) {
|
2021-06-20 00:11:23 +12:00
|
|
|
fixed_height += symbol->row_height[i];
|
2021-11-07 13:21:02 +13:00
|
|
|
} else {
|
|
|
|
zero_count++;
|
2021-06-20 00:11:23 +12:00
|
|
|
}
|
2021-11-07 13:21:02 +13:00
|
|
|
}
|
|
|
|
if (zero_count) {
|
|
|
|
large_bar_height = stripf((symbol->height - fixed_height) / zero_count);
|
|
|
|
assert(large_bar_height >= 0.5f); /* Min row height as set by `set_height()` */
|
|
|
|
symbol->height = stripf(large_bar_height * zero_count + fixed_height);
|
2021-06-20 00:11:23 +12:00
|
|
|
}
|
2020-07-16 06:00:12 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
return large_bar_height;
|
|
|
|
}
|
|
|
|
|
2023-05-10 11:47:44 +12:00
|
|
|
#ifdef _WIN32
|
|
|
|
/* Convert UTF-8 to Windows wide chars. Ticket #288, props Marcel */
|
|
|
|
#define utf8_to_wide(u, w, r) \
|
|
|
|
{ \
|
|
|
|
int lenW; /* Includes NUL terminator */ \
|
|
|
|
if ((lenW = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u, -1, NULL, 0)) == 0) return r; \
|
|
|
|
w = (wchar_t *) z_alloca(sizeof(wchar_t) * lenW); \
|
|
|
|
if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u, -1, w, lenW) == 0) return r; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do `fopen()` on Windows, assuming `filename` is UTF-8 encoded. Ticket #288, props Marcel */
|
|
|
|
INTERNAL FILE *out_win_fopen(const char *filename, const char *mode) {
|
|
|
|
wchar_t *filenameW, *modeW;
|
|
|
|
|
|
|
|
utf8_to_wide(filename, filenameW, NULL);
|
|
|
|
utf8_to_wide(mode, modeW, NULL);
|
|
|
|
|
|
|
|
return _wfopen(filenameW, modeW);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
/* Make a directory; already existing dir okay */
|
|
|
|
/* Adapted from https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950 and
|
|
|
|
https://nachtimwald.com/2019/07/10/recursive-create-directory-in-c-revisited/ */
|
2023-05-10 11:47:44 +12:00
|
|
|
static int out_maybe_mkdir(const char *path) {
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
#ifdef _WIN32
|
|
|
|
DWORD dwAttrib;
|
2023-05-10 11:47:44 +12:00
|
|
|
wchar_t *pathW;
|
|
|
|
|
|
|
|
/* Assumes `path` is UTF-8 encoded */
|
|
|
|
utf8_to_wide(path, pathW, 0);
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
|
|
|
|
/* Try to make the directory */
|
2023-05-10 11:47:44 +12:00
|
|
|
if (CreateDirectoryW(pathW, NULL) != 0) { /* Non-zero on success */
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* If it fails for any reason but already exists, fail */
|
|
|
|
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* Check if the existing path is a directory */
|
2023-05-10 11:47:44 +12:00
|
|
|
if ((dwAttrib = GetFileAttributesW(pathW)) == (DWORD) -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
/* Try to make the directory */
|
|
|
|
if (mkdir(path, 0777) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* If it fails for any reason but already exists, fail */
|
|
|
|
if (errno != EEXIST) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* Check if the existing path is a directory */
|
|
|
|
if (stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create output file, creating sub-directories if necessary. Returns `fopen()` FILE pointer */
|
|
|
|
INTERNAL FILE *out_fopen(const char filename[256], const char *mode) {
|
|
|
|
FILE *outfile;
|
|
|
|
|
2023-05-10 11:47:44 +12:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (!(outfile = out_win_fopen(filename, mode))) {
|
|
|
|
#else
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
if (!(outfile = fopen(filename, mode))) {
|
2023-05-10 11:47:44 +12:00
|
|
|
#endif
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
char dirname[256];
|
|
|
|
char *d;
|
|
|
|
#ifdef _WIN32
|
|
|
|
char *dirend = strrchr(filename, '\\');
|
|
|
|
if (!dirend) {
|
|
|
|
dirend = strrchr(filename, '/');
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
char *dirend = strrchr(filename, '/');
|
|
|
|
#endif
|
|
|
|
if (!dirend) {
|
|
|
|
return outfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adapted from https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950 */
|
|
|
|
/* Remove filename, leaving directories */
|
|
|
|
memcpy(dirname, filename, dirend - filename);
|
|
|
|
dirname[dirend - filename] = '/';
|
|
|
|
dirname[dirend - filename + 1] = '\0';
|
|
|
|
#if _WIN32
|
|
|
|
for (d = dirname; *d; d++) { /* Convert to Unix separators */
|
|
|
|
if (*d == '\\') {
|
|
|
|
*d = '/';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
for (d = dirname + 1; *d; d++) { /* Ignore slash at start if any */
|
|
|
|
if (*d == '/' && *(d - 1) != '/') { /* Ignore double-slashes */
|
|
|
|
*d = '\0'; /* Temporarily truncate */
|
|
|
|
if (out_maybe_mkdir(dirname) != 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*d = '/'; /* Restore */
|
|
|
|
}
|
|
|
|
}
|
2023-05-10 11:47:44 +12:00
|
|
|
#ifdef _WIN32
|
|
|
|
outfile = out_win_fopen(filename, mode);
|
|
|
|
#else
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
outfile = fopen(filename, mode);
|
2023-05-10 11:47:44 +12:00
|
|
|
#endif
|
- API: add new zint_symbol `dpmm` field for output resolution (BMP/
EMF/PCX/PNG/TIF only, i.e. excluding EPS, GIF & SVG)
- Add support for specifying scale by X-dimension and resolution
with new option `--scalexdimdp` for CLI/Tcl & new API function
`ZBarcode_Scale_From_XdimDp()` (+ `ZBarcode_XdimDp_From_Scale()`
& `ZBarcode_Default_Xdim()`) and new GUI popup; manual: document
- BMP/EMF/PCX/PNG/TIF: use new `dpmm` resolution field (for EMF
following Inkscape)
- backend_qt: add `dpmm()`, `vectorWidth()`, `vectorHeight()`,
`noPng()`, `getVersion()`, `takesGS1AIData()`, & `XdimDp` stuff
incl. new `QZintXdimDp` struct for passing around scale vars &
use in `getAsCLI()`; add comments
- Raise `scale` limit to 200 (from 100) to allow for large dpmm
- output: create directories & subdirectories as necessary for
output path using new function `out_fopen()` and use in BMP/EMF/
EPS/GIF/PCX/PNG/SVG/TIF
- DPLEIT/DPIDENT: format HRT according to (incomplete)
documentation, and set default height to 72X (from 50X)
- CODE128B renamed to CODE128AB as can use subsets A and/or B
- CODABAR: fix minimum height calc
- EMF: fix indexing of handles (zero-based not 1-based)
- GUI: fix symbology zap (previous technique of clearing and
re-loading settings without doing a sync no longer works);
fix UPCEAN guard descent enable
- MAILMARK: better error message if input < 14 characters
- GUI: add "Default" button for DAFT tracker ratio & enable/disable
various default buttons; use new `takesGS1AIData()` to
enable/disable GS1-specific checkboxes
- CLI: use new `validate_float()` to parse float options (7
significant digits allowed only, no scientific notation)
- DATAMATRIX/GRIDMATRIX/PDF417/QR/ULTRA: micro-optimize structapp
ID parse
- library/CLI: fiddle with static asserts (make CHAR_BIT sensitive,
supposedly)
- win32/README: update building libpng (assembly removed)
- README.linux: document incompatibility of Qt6 >= 6.3
- manual: expand Barcode Studio waffle
- test suite: change range separator to hyphen and allow multiple
excludes
2022-12-03 10:39:01 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
return outfile;
|
|
|
|
}
|
|
|
|
|
2023-06-12 12:25:55 +12:00
|
|
|
/* Output float without trailing zeroes to `fp` with decimal pts `dp` (precision) */
|
|
|
|
INTERNAL void out_putsf(const char *const prefix, const int dp, const float arg, FILE *fp) {
|
|
|
|
int i, end;
|
|
|
|
char buf[256]; /* Assuming `dp` reasonable */
|
|
|
|
const int len = sprintf(buf, "%.*f", dp, arg);
|
|
|
|
|
|
|
|
if (*prefix) {
|
|
|
|
fputs(prefix, fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adapted from https://stackoverflow.com/a/36202854/664741 */
|
|
|
|
for (i = len - 1, end = len; i >= 0; i--) {
|
|
|
|
if (buf[i] == '0') {
|
|
|
|
if (end == i + 1) {
|
|
|
|
end = i;
|
|
|
|
}
|
|
|
|
} else if (!z_isdigit(buf[i]) && buf[i] != '-') { /* If not digit or minus then decimal point */
|
|
|
|
if (end == i + 1) {
|
|
|
|
end = i;
|
|
|
|
} else {
|
|
|
|
buf[i] = '.'; /* Overwrite any locale-specific setting for decimal point */
|
|
|
|
}
|
|
|
|
buf[end] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fputs(buf, fp);
|
|
|
|
}
|
|
|
|
|
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
libzint: fix some confusing error messages introduced by segment stuff
general: new escape chars \U, \d and \o
backend_qt: fudge rendering of border rectangles due to scaling/translation
rounding errors TODO: better fudge
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
libzint: remove STATIC_UNLESS_ZINT_TEST, use wrappers
CMake: add find package QtSvg, remove QtXml
manual: split symbology and general specs and sort, move DAFT to 4-state,
UPC/EAN -> EAN/UPC, DataBar -> GS1 DataBar always, expand MAILMARK info,
various other fiddlings
man page: options or -> |, expand MSI Plessey check digit options
README.linux: add packages info
license: add SPDX-License-Identifier to touched files
2022-06-10 08:52:02 +12:00
|
|
|
/* vim: set ts=4 sw=4 et : */
|