Add BARCODE_MEMORY_FILE to symbol->output_options to allow

outputting to in-memory buffer `symbol->memfile` instead of to
  file `symbol->outfile`, ticket #301
Add "README.clang-tidy" and ".clang-tidy" options file
Suppress some warnings
This commit is contained in:
gitlost 2023-12-27 19:20:19 +00:00
parent 070162214b
commit 98f86727cc
59 changed files with 2407 additions and 1262 deletions

View file

@ -35,10 +35,11 @@
#include <math.h>
#include <stdio.h>
#include "common.h"
#include "filemem.h"
#include "output.h"
/* Output Ultracode rectangle colour as PostScript setrgbcolor/setcmykcolor */
static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) {
static void ps_put_colour(const int is_rgb, const int colour, struct filemem *const fmp) {
const int idx = colour >= 1 && colour <= 8 ? colour - 1 : 6 /*black*/;
if (is_rgb) {
/* Use RGB colour space */
@ -52,8 +53,8 @@ static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) {
"0 0 0", /* 6: Black (7) */
"1 1 1", /* 7: White (8) */
};
fputs(ps_rgbs[idx], feps);
fputs(" setrgbcolor\n", feps);
fm_puts(ps_rgbs[idx], fmp);
fm_puts(" setrgbcolor\n", fmp);
} else {
static const char ps_cmyks[8][8] = {
"1 0 0 0", /* 0: Cyan (1) */
@ -65,8 +66,8 @@ static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) {
"0 0 0 1", /* 6: Black (7) */
"0 0 0 0", /* 7: White (8) */
};
fputs(ps_cmyks[idx], feps);
fputs(" setcmykcolor\n", feps);
fm_puts(ps_cmyks[idx], fmp);
fm_puts(" setcmykcolor\n", fmp);
}
}
@ -107,51 +108,52 @@ INTERNAL void ps_convert_test(const unsigned char *string, unsigned char *ps_str
#endif
/* Helper to output RGB colour */
static void ps_put_rgbcolor(const float red, const float green, const float blue, FILE *feps) {
out_putsf("", 2, red, feps);
out_putsf(" ", 2, green, feps);
out_putsf(" ", 2, blue, feps);
fputs(" setrgbcolor\n", feps);
static void ps_put_rgbcolor(const float red, const float green, const float blue,
struct filemem *const fmp) {
fm_putsf("", 2, red, fmp);
fm_putsf(" ", 2, green, fmp);
fm_putsf(" ", 2, blue, fmp);
fm_puts(" setrgbcolor\n", fmp);
}
/* Helper to output CMYK colour */
static void ps_put_cmykcolor(const float cyan, const float magenta, const float yellow, const float black,
FILE *feps) {
out_putsf("", 2, cyan, feps);
out_putsf(" ", 2, magenta, feps);
out_putsf(" ", 2, yellow, feps);
out_putsf(" ", 2, black, feps);
fputs(" setcmykcolor\n", feps);
struct filemem *const fmp) {
fm_putsf("", 2, cyan, fmp);
fm_putsf(" ", 2, magenta, fmp);
fm_putsf(" ", 2, yellow, fmp);
fm_putsf(" ", 2, black, fmp);
fm_puts(" setcmykcolor\n", fmp);
}
/* Helper to output rectangle */
static void ps_put_rect(const struct zint_symbol *symbol, const struct zint_vector_rect *rect, const int type,
FILE *feps) {
struct filemem *const fmp) {
if (type == 0 || type == 1) {
out_putsf("", 2, rect->height, feps);
out_putsf(" ", 2, (symbol->vector->height - rect->y) - rect->height, feps);
fm_putsf("", 2, rect->height, fmp);
fm_putsf(" ", 2, (symbol->vector->height - rect->y) - rect->height, fmp);
}
out_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, rect->x, feps);
out_putsf(" ", 2, rect->width, feps);
fputs(" R\n", feps);
fm_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, rect->x, fmp);
fm_putsf(" ", 2, rect->width, fmp);
fm_puts(" R\n", fmp);
}
/* Helper to output circle/disc */
static void ps_put_circle(const struct zint_symbol *symbol, const struct zint_vector_circle *circle,
const float radius, const int type, FILE *feps) {
const float radius, const int type, struct filemem *const fmp) {
if (circle->width) {
out_putsf("", 2, circle->x, feps);
out_putsf(" ", 2, symbol->vector->height - circle->y, feps);
out_putsf(" ", 4, radius, feps);
out_putsf(" ", 4, circle->width, feps);
fputs(" C\n", feps);
fm_putsf("", 2, circle->x, fmp);
fm_putsf(" ", 2, symbol->vector->height - circle->y, fmp);
fm_putsf(" ", 4, radius, fmp);
fm_putsf(" ", 4, circle->width, fmp);
fm_puts(" C\n", fmp);
} else {
if (type == 0 || type == 1) {
out_putsf("", 2, symbol->vector->height - circle->y, feps);
out_putsf(" ", 4, radius, feps);
fm_putsf("", 2, symbol->vector->height - circle->y, fmp);
fm_putsf(" ", 4, radius, fmp);
}
out_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, circle->x, feps);
fputs(" D\n", feps);
fm_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, circle->x, fmp);
fm_puts(" D\n", fmp);
}
}
@ -168,7 +170,8 @@ static int ps_count_rectangles(const struct zint_symbol *symbol) {
}
INTERNAL int ps_plot(struct zint_symbol *symbol) {
FILE *feps;
struct filemem fm;
struct filemem *const fmp = &fm;
unsigned char fgred, fggrn, fgblu, bgred, bggrn, bgblu, bgalpha;
int fgcyan, fgmagenta, fgyellow, fgblack, bgcyan, bgmagenta, bgyellow, bgblack;
float red_ink = 0.0f, green_ink = 0.0f, blue_ink = 0.0f; /* Suppress `-Wmaybe-uninitialized` */
@ -190,21 +193,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
int iso_latin1 = 0;
int have_circles_with_width = 0, have_circles_without_width = 0;
const int upcean = is_upcean(symbol->symbology);
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT;
const int is_rgb = (symbol->output_options & CMYK_COLOUR) == 0;
if (symbol->vector == NULL) {
strcpy(symbol->errtxt, "646: Vector header NULL");
return ZINT_ERROR_INVALID_DATA;
}
if (output_to_stdout) {
feps = stdout;
} else {
if (!(feps = out_fopen(symbol->outfile, "w"))) {
sprintf(symbol->errtxt, "645: Could not open output file (%d: %.30s)", errno, strerror(errno));
return ZINT_ERROR_FILE_ACCESS;
}
if (!fm_open(fmp, symbol, "w")) {
sprintf(symbol->errtxt, "645: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err));
return ZINT_ERROR_FILE_ACCESS;
}
if (is_rgb) {
@ -266,52 +263,52 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
}
/* Start writing the header */
fputs("%!PS-Adobe-3.0 EPSF-3.0\n", feps);
fm_puts("%!PS-Adobe-3.0 EPSF-3.0\n", fmp);
if (ZINT_VERSION_BUILD) {
fprintf(feps, "%%%%Creator: Zint %d.%d.%d.%d\n",
fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d.%d\n",
ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD);
} else {
fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
}
fputs("%%Title: Zint Generated Symbol\n"
"%%Pages: 0\n", feps);
fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n",
fm_puts("%%Title: Zint Generated Symbol\n"
"%%Pages: 0\n", fmp);
fm_printf(fmp, "%%%%BoundingBox: 0 0 %d %d\n",
(int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
fputs("%%EndComments\n", feps);
fm_puts("%%EndComments\n", fmp);
/* Definitions */
if (have_circles_without_width) {
/* Disc: y radius x D */
fputs("/D { newpath 3 1 roll 0 360 arc fill } bind def\n", feps);
fm_puts("/D { newpath 3 1 roll 0 360 arc fill } bind def\n", fmp);
}
if (have_circles_with_width) {
/* Circle (ring): x y radius width C (adapted from BWIPP renmaxicode.ps) */
fputs("/C { newpath 4 1 roll 3 copy 0 360 arc closepath 4 -1 roll add 360 0 arcn closepath fill }"
" bind def\n", feps);
fm_puts("/C { newpath 4 1 roll 3 copy 0 360 arc closepath 4 -1 roll add 360 0 arcn closepath fill }"
" bind def\n", fmp);
}
if (symbol->vector->hexagons) {
/* Hexagon: radius half_radius half_sqrt3_radius x y */
if (symbol->vector->hexagons->rotation == 0 || symbol->vector->hexagons->rotation == 180) {
fputs("/H { newpath moveto 2 copy exch neg exch rmoveto 2 index neg 0 exch rlineto 2 copy neg rlineto"
fm_puts("/H { newpath moveto 2 copy exch neg exch rmoveto 2 index neg 0 exch rlineto 2 copy neg rlineto"
" 2 copy rlineto 3 -1 roll 0 exch rlineto exch neg exch rlineto closepath fill }"
" bind def\n", feps);
" bind def\n", fmp);
} else {
fputs("/H { newpath moveto 2 copy neg exch neg rmoveto 2 index 0 rlineto 2 copy exch rlineto"
fm_puts("/H { newpath moveto 2 copy neg exch neg rmoveto 2 index 0 rlineto 2 copy exch rlineto"
" 2 copy neg exch rlineto 3 -1 roll neg 0 rlineto neg exch neg rlineto closepath fill }"
" bind def\n", feps);
" bind def\n", fmp);
}
/* Copy r hr hsr for repeat use without having to specify them subsequently */
fputs("/J { 3 copy } bind def\n", feps);
fm_puts("/J { 3 copy } bind def\n", fmp);
/* TODO: Save repeating x also */
}
if (symbol->vector->rectangles || draw_background) {
/* Rectangle: h y x w */
fputs("/R { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill }"
" bind def\n", feps);
fm_puts("/R { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill }"
" bind def\n", fmp);
}
if (symbol->vector->rectangles || have_circles_without_width) {
/* Copy h y (rect) or y r (disc) for repeat use without having to specify them subsequently */
fputs("/I { 2 copy } bind def\n", feps);
fm_puts("/I { 2 copy } bind def\n", fmp);
}
/* Now the actual representation */
@ -319,21 +316,21 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
/* Background */
if (draw_background) {
if (is_rgb) {
ps_put_rgbcolor(red_paper, green_paper, blue_paper, feps);
ps_put_rgbcolor(red_paper, green_paper, blue_paper, fmp);
} else {
ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, feps);
ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, fmp);
}
out_putsf("", 2, symbol->vector->height, feps);
out_putsf(" 0 0 ", 2, symbol->vector->width, feps); /* y x w */
fputs(" R\n", feps);
fm_putsf("", 2, symbol->vector->height, fmp);
fm_putsf(" 0 0 ", 2, symbol->vector->width, fmp); /* y x w */
fm_puts(" R\n", fmp);
}
if (symbol->symbology != BARCODE_ULTRA) {
if (is_rgb) {
ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps);
ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp);
} else {
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps);
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp);
}
}
@ -362,22 +359,22 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
if (colour_rect_flag == 0) {
/* Set foreground colour */
if (is_rgb) {
ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps);
ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp);
} else {
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps);
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp);
}
colour_rect_flag = 1;
}
} else {
/* Set new colour */
ps_put_colour(is_rgb, rect->colour, feps);
ps_put_colour(is_rgb, rect->colour, fmp);
}
}
if (i + 1 < u_i && rect->height == ultra_rects[i + 1]->height && rect->y == ultra_rects[i + 1]->y) {
ps_put_rect(symbol, rect, type_latch ? 2 : 1, feps);
ps_put_rect(symbol, rect, type_latch ? 2 : 1, fmp);
type_latch = 1;
} else {
ps_put_rect(symbol, rect, type_latch ? 3 : 0, feps);
ps_put_rect(symbol, rect, type_latch ? 3 : 0, fmp);
type_latch = 0;
}
}
@ -385,10 +382,10 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
type_latch = 0;
for (rect = symbol->vector->rectangles; rect; rect = rect->next) {
if (rect->next && rect->height == rect->next->height && rect->y == rect->next->y) {
ps_put_rect(symbol, rect, type_latch ? 2 : 1, feps);
ps_put_rect(symbol, rect, type_latch ? 2 : 1, fmp);
type_latch = 1;
} else {
ps_put_rect(symbol, rect, type_latch ? 3 : 0, feps);
ps_put_rect(symbol, rect, type_latch ? 3 : 0, fmp);
type_latch = 0;
}
}
@ -400,18 +397,18 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
float hy = symbol->vector->height - hex->y;
if (previous_diameter != hex->diameter) {
previous_diameter = hex->diameter;
out_putsf("", 4, 0.5f * previous_diameter /*radius*/, feps);
out_putsf(" ", 4, 0.43301270189221932338f * previous_diameter /*half_sqrt3_radius*/, feps);
out_putsf(" ", 4, 0.25f * previous_diameter /*half_radius*/, feps);
fputc('\n', feps);
fm_putsf("", 4, 0.5f * previous_diameter /*radius*/, fmp);
fm_putsf(" ", 4, 0.43301270189221932338f * previous_diameter /*half_sqrt3_radius*/, fmp);
fm_putsf(" ", 4, 0.25f * previous_diameter /*half_radius*/, fmp);
fm_putc('\n', fmp);
}
if (hex->next) {
out_putsf("J ", 2, hex->x, feps);
fm_putsf("J ", 2, hex->x, fmp);
} else {
out_putsf("", 2, hex->x, feps);
fm_putsf("", 2, hex->x, fmp);
}
out_putsf(" ", 2, hy, feps);
fputs(" H\n", feps);
fm_putsf(" ", 2, hy, fmp);
fm_puts(" H\n", fmp);
}
/* Circles */
@ -425,25 +422,25 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
if (circle->colour) { /* Legacy - no longer used */
/* A 'white' circle */
if (is_rgb) {
ps_put_rgbcolor(red_paper, green_paper, blue_paper, feps);
ps_put_rgbcolor(red_paper, green_paper, blue_paper, fmp);
} else {
ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, feps);
ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, fmp);
}
ps_put_circle(symbol, circle, radius, 0 /*type*/, feps);
ps_put_circle(symbol, circle, radius, 0 /*type*/, fmp);
if (circle->next) {
if (is_rgb) {
ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps);
ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp);
} else {
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps);
ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp);
}
}
} else {
/* A 'black' circle */
if (circle->next && circle->y == circle->next->y && circle->diameter == circle->next->diameter) {
ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, feps);
ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, fmp);
type_latch = 1;
} else {
ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, feps);
ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, fmp);
type_latch = 0;
}
}
@ -465,70 +462,61 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
}
if (iso_latin1) {
/* Change encoding to ISO 8859-1, see Postscript Language Reference Manual 2nd Edition Example 5.6 */
fprintf(feps, "/%s findfont\n", font);
fputs("dup length dict begin\n"
fm_printf(fmp, "/%s findfont\n", font);
fm_puts("dup length dict begin\n"
"{1 index /FID ne {def} {pop pop} ifelse} forall\n"
"/Encoding ISOLatin1Encoding def\n"
"currentdict\n"
"end\n"
"/Helvetica-ISOLatin1 exch definefont pop\n", feps);
"/Helvetica-ISOLatin1 exch definefont pop\n", fmp);
font = "Helvetica-ISOLatin1";
}
do {
ps_convert(string->text, ps_string);
if (string->fsize != previous_fsize) {
fprintf(feps, "/%s findfont", font);
fm_printf(fmp, "/%s findfont", font);
/* Compensate for Helvetica being smaller than Zint's OCR-B */
out_putsf( " ", 2, upcean ? string->fsize * 1.07f : string->fsize, feps);
fputs(" scalefont setfont\n", feps);
fm_putsf( " ", 2, upcean ? string->fsize * 1.07f : string->fsize, fmp);
fm_puts(" scalefont setfont\n", fmp);
previous_fsize = string->fsize;
}
/* Unhack the guard whitespace `gws_left_fudge`/`gws_right_fudge` hack */
if (upcean && string->halign == 1 && string->text[0] == '<') {
const float gws_left_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */
out_putsf(" ", 2, string->x + gws_left_fudge, feps);
fm_putsf(" ", 2, string->x + gws_left_fudge, fmp);
} else if (upcean && string->halign == 2 && string->text[0] == '>') {
const float gws_right_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */
out_putsf(" ", 2, string->x - gws_right_fudge, feps);
fm_putsf(" ", 2, string->x - gws_right_fudge, fmp);
} else {
out_putsf(" ", 2, string->x, feps);
fm_putsf(" ", 2, string->x, fmp);
}
out_putsf(" ", 2, symbol->vector->height - string->y, feps);
fputs(" moveto\n", feps);
fm_putsf(" ", 2, symbol->vector->height - string->y, fmp);
fm_puts(" moveto\n", fmp);
if (string->rotation != 0) {
fputs(" gsave\n", feps);
fprintf(feps, " %d rotate\n", 360 - string->rotation);
fm_puts(" gsave\n", fmp);
fm_printf(fmp, " %d rotate\n", 360 - string->rotation);
}
if (string->halign == 0 || string->halign == 2) { /* Need width for middle or right align */
fprintf(feps, " (%s) stringwidth pop" /* Returns "width height" - discard "height" */
fm_printf(fmp, " (%s) stringwidth pop" /* Returns "width height" - discard "height" */
" %s 0 rmoveto\n", ps_string, string->halign == 2 ? "neg" : "-2 div");
}
fprintf(feps, " (%s) show\n", ps_string);
fm_printf(fmp, " (%s) show\n", ps_string);
if (string->rotation != 0) {
fputs(" grestore\n", feps);
fm_puts(" grestore\n", fmp);
}
string = string->next;
} while (string);
}
if (ferror(feps)) {
sprintf(symbol->errtxt, "647: Incomplete write to output (%d: %.30s)", errno, strerror(errno));
if (!output_to_stdout) {
(void) fclose(feps);
}
if (fm_error(fmp)) {
sprintf(symbol->errtxt, "647: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err));
(void) fm_close(fmp, symbol);
return ZINT_ERROR_FILE_WRITE;
}
if (output_to_stdout) {
if (fflush(feps) != 0) {
sprintf(symbol->errtxt, "648: Incomplete flush to output (%d: %.30s)", errno, strerror(errno));
return ZINT_ERROR_FILE_WRITE;
}
} else {
if (fclose(feps) != 0) {
sprintf(symbol->errtxt, "649: Failure on closing output file (%d: %.30s)", errno, strerror(errno));
return ZINT_ERROR_FILE_WRITE;
}
if (!fm_close(fmp, symbol)) {
sprintf(symbol->errtxt, "649: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err));
return ZINT_ERROR_FILE_WRITE;
}
return error_number;