- 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
This commit is contained in:
gitlost 2022-12-02 21:39:01 +00:00
parent 6393813cff
commit c8033695d9
127 changed files with 4032 additions and 1248 deletions

View file

@ -31,8 +31,14 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#else
#include <sys/stat.h> /* mkdir(2) */
#endif
#include "common.h"
#include "output.h"
#include "font.h"
@ -241,7 +247,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
done = 1;
break;
case BARCODE_CODE128:
case BARCODE_CODE128B:
case BARCODE_CODE128AB:
case BARCODE_HIBC_128:
case BARCODE_NVE18:
/* ISO/IEC 15417:2007 4.4.2 */
@ -250,7 +256,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
break;
case BARCODE_DPLEIT:
case BARCODE_DPIDENT:
/* Using CODE39 values TODO: Find doc */
/* Using C25INTER values TODO: Find doc */
*left = *right = 10.0f;
done = 1;
break;
@ -486,7 +492,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
#ifdef ZINT_TEST /* Wrapper for direct testing */
INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hide_text,
float *left, float *right, float *top, float *bottom) {
return out_quiet_zones(symbol, hide_text, left, right, top, bottom);
return out_quiet_zones(symbol, hide_text, left, right, top, bottom);
}
#endif
@ -742,4 +748,90 @@ INTERNAL void out_upcean_split_text(int upceanflag, unsigned char text[],
}
}
/* 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/ */
static int out_maybe_mkdir(const char* path)
{
#ifdef _WIN32
DWORD dwAttrib;
/* Try to make the directory */
if (CreateDirectory(path, NULL) != 0) { /* Non-zero on success */
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 */
if ((dwAttrib = GetFileAttributes(path)) == (DWORD) -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
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;
if (!(outfile = fopen(filename, mode))) {
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 */
}
}
outfile = fopen(filename, mode);
}
return outfile;
}
/* vim: set ts=4 sw=4 et : */