1
0
mirror of https://git.code.sf.net/p/zint/code synced 2025-12-18 10:27:09 +00:00

- raster.c: Need ceilf(symbol->height * si) to avoid heap-buffer-overflow;

also avoid distributive multiplication with floats to lessen chances of
  platform variation (#204 ARM-Cortex crash)
- raster.c: Don't allow for text if scale < 1.0
- raster.c: Cast some indexes to (size_t) to allow for large scale
- vector.c: Check malloc()s and return ZINT_ERROR_MEMORY on fail
- raster/vector.c: various var name changes & other code fiddling
- library.c: Check that scale/height/whitespace/border are reasonable values:
  scale (0.01-100), height (0-500), whitespace_width/height (0-100),
  border_width (0-100)
- CLI: allow both e.g. '-height' and '--height' (getopt_long_only())
- gif.c: fix GIF_ZLW_PAGE_SIZE -> GIF_LZW_PAGE_SIZE
- GUI: allow whitespace/scale to 100
This commit is contained in:
gitlost
2021-09-20 14:56:27 +01:00
parent 5766b39845
commit 9bae0b86f9
19 changed files with 870 additions and 814 deletions

View File

@@ -30,7 +30,6 @@
*/
/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#include <math.h>
#ifdef _MSC_VER
@@ -45,11 +44,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol);
INTERNAL int svg_plot(struct zint_symbol *symbol);
INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle);
static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float width, float height) {
static struct zint_vector_rect *vector_plot_create_rect(struct zint_symbol *symbol,
const float x, const float y, const float width, const float height) {
struct zint_vector_rect *rect;
rect = (struct zint_vector_rect *) malloc(sizeof(struct zint_vector_rect));
if (!rect) return NULL;
if (!rect) {
strcpy(symbol->errtxt, "691: Insufficient memory for vector rectangle");
return NULL;
}
rect->next = NULL;
rect->x = x;
@@ -61,23 +64,25 @@ static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float
return rect;
}
static int vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_rect *rect,
static void vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_rect *rect,
struct zint_vector_rect **last_rect) {
if (!rect) return 0;
if (*last_rect)
(*last_rect)->next = rect;
else
symbol->vector->rectangles = rect; // first rectangle
*last_rect = rect;
return 1;
}
static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y, float diameter) {
static struct zint_vector_hexagon *vector_plot_create_hexagon(struct zint_symbol *symbol,
const float x, const float y, const float diameter) {
struct zint_vector_hexagon *hexagon;
hexagon = (struct zint_vector_hexagon *) malloc(sizeof(struct zint_vector_hexagon));
if (!hexagon) return NULL;
if (!hexagon) {
strcpy(symbol->errtxt, "692: Insufficient memory for vector hexagon");
return NULL;
}
hexagon->next = NULL;
hexagon->x = x;
hexagon->y = y;
@@ -87,24 +92,26 @@ static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y,
return hexagon;
}
static int vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vector_hexagon *hexagon,
static void vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vector_hexagon *hexagon,
struct zint_vector_hexagon **last_hexagon) {
if (!hexagon) return 0;
if (*last_hexagon)
(*last_hexagon)->next = hexagon;
else
symbol->vector->hexagons = hexagon; // first hexagon
*last_hexagon = hexagon;
return 1;
}
static struct zint_vector_circle *vector_plot_create_circle(float x, float y, float diameter, float width,
int colour) {
static struct zint_vector_circle *vector_plot_create_circle(struct zint_symbol *symbol,
const float x, const float y, const float diameter, const float width,
const int colour) {
struct zint_vector_circle *circle;
circle = (struct zint_vector_circle *) malloc(sizeof(struct zint_vector_circle));
if (!circle) return NULL;
if (!circle) {
strcpy(symbol->errtxt, "693: Insufficient memory for vector circle");
return NULL;
}
circle->next = NULL;
circle->x = x;
circle->y = y;
@@ -115,25 +122,26 @@ static struct zint_vector_circle *vector_plot_create_circle(float x, float y, fl
return circle;
}
static int vector_plot_add_circle(struct zint_symbol *symbol, struct zint_vector_circle *circle,
static void vector_plot_add_circle(struct zint_symbol *symbol, struct zint_vector_circle *circle,
struct zint_vector_circle **last_circle) {
if (!circle) return 0;
if (*last_circle)
(*last_circle)->next = circle;
else
symbol->vector->circles = circle; // first circle
*last_circle = circle;
return 1;
}
static int vector_plot_add_string(struct zint_symbol *symbol,
unsigned char *text, float x, float y, float fsize, float width, int halign,
struct zint_vector_string **last_string) {
static int vector_plot_add_string(struct zint_symbol *symbol, const unsigned char *text,
const float x, const float y, const float fsize, const float width, const int halign,
struct zint_vector_string **last_string) {
struct zint_vector_string *string;
string = (struct zint_vector_string *) malloc(sizeof(struct zint_vector_string));
if (!string) return 0;
if (!string) {
strcpy(symbol->errtxt, "694: Insufficient memory for vector string");
return 0;
}
string->next = NULL;
string->x = x;
string->y = y;
@@ -142,8 +150,12 @@ static int vector_plot_add_string(struct zint_symbol *symbol,
string->length = (int) ustrlen(text);
string->rotation = 0;
string->halign = halign;
string->text = (unsigned char *) malloc(ustrlen(text) + 1);
if (!string->text) { free(string); return 0; }
string->text = (unsigned char *) malloc(string->length + 1);
if (!string->text) {
free(string);
strcpy(symbol->errtxt, "695: Insufficient memory for vector string text");
return 0;
}
ustrcpy(string->text, text);
if (*last_string)
@@ -201,7 +213,7 @@ INTERNAL void vector_free(struct zint_symbol *symbol) {
}
}
static void vector_scale(struct zint_symbol *symbol, int file_type) {
static void vector_scale(struct zint_symbol *symbol, const int file_type) {
struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
struct zint_vector_circle *circle;
@@ -254,10 +266,9 @@ static void vector_scale(struct zint_symbol *symbol, int file_type) {
string->fsize *= scale;
string = string->next;
}
return;
}
static void vector_rotate(struct zint_symbol *symbol, int rotate_angle) {
static void vector_rotate(struct zint_symbol *symbol, const int rotate_angle) {
// Rotates the image
struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
@@ -355,8 +366,6 @@ static void vector_rotate(struct zint_symbol *symbol, int rotate_angle) {
symbol->vector->height = symbol->vector->width;
symbol->vector->width = temp;
}
return;
}
static void vector_reduce_rectangles(struct zint_symbol *symbol) {
@@ -382,45 +391,39 @@ static void vector_reduce_rectangles(struct zint_symbol *symbol) {
rect = rect->next;
}
return;
}
INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type) {
int error_number;
float large_bar_height;
int textdone = 0;
int main_width;
int comp_offset = 0;
int comp_xoffset = 0;
unsigned char addon[6];
int addon_gap = 0;
float addon_text_posn = 0.0f;
float addon_bar_height = 0.0f;
float addon_text_yposn = 0.0f;
float xoffset, yoffset, roffset, boffset;
float textoffset;
float default_text_posn;
float row_height, row_posn;
float yposn;
int upceanflag = 0;
int addon_latch = 0;
unsigned char textpart1[5], textpart2[7], textpart3[7], textpart4[2];
float textpos;
int hide_text;
int i, r;
int text_height; /* Font pixel size (so whole integers) */
float text_gap; /* Gap between barcode and text */
float guard_height;
int upcae_outside_text_height = 0; /* UPC-A/E outside digits font size */
float digit_ascent_factor = 0.25f; /* Assuming digit ascent roughly 25% less than font size */
float text_gap; /* Gap between barcode and text */
float dot_overspill = 0.0f;
float dot_offset = 0.0f;
int rect_count, last_row_start = 0;
int this_row;
struct zint_vector *vector;
struct zint_vector_rect *rectangle, *rect, *last_rectangle = NULL;
struct zint_vector_hexagon *last_hexagon = NULL;
struct zint_vector_rect *rect, *last_rectangle = NULL;
struct zint_vector_hexagon *hexagon, *last_hexagon = NULL;
struct zint_vector_string *last_string = NULL;
struct zint_vector_circle *last_circle = NULL;
struct zint_vector_circle *circle, *last_circle = NULL;
// Free any previous rendering structures
vector_free(symbol);
@@ -433,7 +436,10 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
// Allocate memory
vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector));
if (!vector) return ZINT_ERROR_MEMORY;
if (!vector) {
strcpy(symbol->errtxt, "696: Insufficient memory for vector header");
return ZINT_ERROR_MEMORY;
}
vector->rectangles = NULL;
vector->hexagons = NULL;
vector->circles = NULL;
@@ -444,10 +450,11 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
main_width = symbol->width;
if (is_extendable(symbol->symbology)) {
upceanflag = output_process_upcean(symbol, &main_width, &comp_offset, addon, &addon_gap);
upceanflag = output_process_upcean(symbol, &main_width, &comp_xoffset, addon, &addon_gap);
}
output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset);
output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset, 0 /*scaler*/,
NULL, NULL, NULL, NULL);
/* Note font sizes scaled by 2 so really twice these values */
if (upceanflag) {
@@ -456,18 +463,22 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
upcae_outside_text_height = symbol->output_options & SMALL_TEXT ? 6 : 7;
/* Negative to move close to barcode (less digit ascent, then add 0.5X) */
text_gap = -text_height * digit_ascent_factor + 0.5f;
/* Guard bar height (none for EAN-2 and EAN-5) */
guard_height = upceanflag != 2 && upceanflag != 5 ? 5.0f : 0.0f; /* TODO: use zint_symbol field */
} else {
text_height = symbol->output_options & SMALL_TEXT ? 6 : 7;
text_gap = text_height * 0.1f;
guard_height = 0.0f;
}
hide_text = ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0));
if (hide_text) {
textoffset = upceanflag && upceanflag != 2 && upceanflag != 5 ? 5.0f : 0.0f; /* Allow for guard bars */
textoffset = guard_height;
} else {
if (upceanflag) {
textoffset = text_height + 0.2f + text_gap; /* Add fudge for anti-aliasing of digits */
/* Add fudge for anti-aliasing of digits */
textoffset = (text_height > guard_height ? text_height : guard_height) + 0.2f + text_gap;
} else {
textoffset = text_height * 1.25f + text_gap; /* Allow +25% for characters descending below baseline */
}
@@ -487,16 +498,8 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
vector->width = symbol->width + dot_overspill + (xoffset + roffset);
vector->height = symbol->height + textoffset + dot_overspill + (yoffset + boffset);
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) {
default_text_posn = symbol->height + text_height + text_gap + symbol->whitespace_height
+ symbol->border_width * 2;
} else {
default_text_posn = symbol->height + text_height + text_gap + symbol->whitespace_height;
}
// Plot Maxicode symbols
if (symbol->symbology == BARCODE_MAXICODE) {
struct zint_vector_circle *circle;
float bull_x, bull_y, bull_d_incr, bull_width;
const float two_div_sqrt3 = 1.1547f; /* 2 / √3 */
const float sqrt3_div_two = 0.866f; /* √3 / 2 == 1.5 / √3 */
@@ -519,13 +522,17 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
bull_d_incr = (hex_diameter * 9 - hex_ydiameter) / 5.0f;
bull_width = bull_d_incr / 2.0f;
circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width,
0);
circle = vector_plot_create_circle(symbol, bull_x, bull_y,
hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, 0);
if (!circle) return ZINT_ERROR_MEMORY;
vector_plot_add_circle(symbol, circle, &last_circle);
circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width,
0);
circle = vector_plot_create_circle(symbol, bull_x, bull_y,
hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, 0);
if (!circle) return ZINT_ERROR_MEMORY;
vector_plot_add_circle(symbol, circle, &last_circle);
circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr - bull_width, bull_width, 0);
circle = vector_plot_create_circle(symbol, bull_x, bull_y,
hex_ydiameter + bull_d_incr - bull_width, bull_width, 0);
if (!circle) return ZINT_ERROR_MEMORY;
vector_plot_add_circle(symbol, circle, &last_circle);
/* Hexagons */
@@ -536,7 +543,8 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
for (i = 0; i < symbol->width - odd_row; i++) {
if (module_is_set(symbol, r, i)) {
const float xposn = i * hex_diameter + xposn_offset;
struct zint_vector_hexagon *hexagon = vector_plot_create_hexagon(xposn, yposn, hex_diameter);
hexagon = vector_plot_create_hexagon(symbol, xposn, yposn, hex_diameter);
if (!hexagon) return ZINT_ERROR_MEMORY;
vector_plot_add_hexagon(symbol, hexagon, &last_hexagon);
}
}
@@ -546,10 +554,9 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
for (r = 0; r < symbol->rows; r++) {
for (i = 0; i < symbol->width; i++) {
if (module_is_set(symbol, r, i)) {
struct zint_vector_circle *circle = vector_plot_create_circle(
i + dot_offset + xoffset,
r + dot_offset + yoffset,
symbol->dot_size, 0, 0);
circle = vector_plot_create_circle(symbol, i + dot_offset + xoffset, r + dot_offset + yoffset,
symbol->dot_size, 0, 0);
if (!circle) return ZINT_ERROR_MEMORY;
vector_plot_add_circle(symbol, circle, &last_circle);
}
}
@@ -557,27 +564,27 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
// Plot rectangles - most symbols created here
} else {
rect_count = 0;
row_posn = yoffset;
yposn = yoffset;
for (r = 0; r < symbol->rows; r++) {
this_row = r;
float row_height = symbol->row_height[r] ? symbol->row_height[r] : large_bar_height;
last_row_start = rect_count;
row_height = symbol->row_height[this_row] ? symbol->row_height[this_row] : large_bar_height;
i = 0;
if (symbol->symbology == BARCODE_ULTRA) {
do {
int module_fill = module_colour_is_set(symbol, this_row, i);
int module_fill = module_colour_is_set(symbol, r, i);
int block_width = 0;
do {
block_width++;
} while (i + block_width < symbol->width
&& module_colour_is_set(symbol, this_row, i + block_width) == module_fill);
&& module_colour_is_set(symbol, r, i + block_width) == module_fill);
if (module_fill) {
/* a colour block */
rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height);
rectangle->colour = module_colour_is_set(symbol, this_row, i);
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
rect = vector_plot_create_rect(symbol, i + xoffset, yposn, block_width, row_height);
if (!rect) return ZINT_ERROR_MEMORY;
rect->colour = module_colour_is_set(symbol, r, i);
vector_plot_add_rect(symbol, rect, &last_rectangle);
rect_count++;
}
i += block_width;
@@ -585,43 +592,45 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
} while (i < symbol->width);
} else {
do {
int module_fill = module_is_set(symbol, this_row, i);
float addon_row_height;
int module_fill = module_is_set(symbol, r, i);
int block_width = 0;
do {
block_width++;
} while (i + block_width < symbol->width
&& module_is_set(symbol, this_row, i + block_width) == module_fill);
&& module_is_set(symbol, r, i + block_width) == module_fill);
if (upceanflag && (addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) {
addon_text_posn = row_posn + text_height - text_height * digit_ascent_factor;
if (addon_text_posn < 0.0f) {
addon_text_posn = 0.0f;
addon_text_yposn = yposn + text_height - text_height * digit_ascent_factor;
if (addon_text_yposn < 0.0f) {
addon_text_yposn = 0.0f;
}
addon_bar_height = row_height - (addon_text_posn - row_posn) + text_gap;
if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E don't descend */
addon_bar_height += 5.0f;
addon_row_height = row_height - (addon_text_yposn - yposn) + text_gap;
if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E add-ons don't descend */
addon_row_height += guard_height;
}
if (addon_bar_height < 0.5f) {
addon_bar_height = 0.5f;
if (addon_row_height < 0.5f) {
addon_row_height = 0.5f;
}
addon_latch = 1;
}
if (module_fill) {
/* a bar */
if (addon_latch == 0) {
rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height);
rect = vector_plot_create_rect(symbol, i + xoffset, yposn, block_width, row_height);
} else {
rectangle = vector_plot_create_rect(i + xoffset, addon_text_posn - text_gap, block_width,
addon_bar_height);
rect = vector_plot_create_rect(symbol, i + xoffset, addon_text_yposn - text_gap,
block_width, addon_row_height);
}
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
if (!rect) return ZINT_ERROR_MEMORY;
vector_plot_add_rect(symbol, rect, &last_rectangle);
rect_count++;
}
i += block_width;
} while (i < symbol->width);
}
row_posn += row_height;
yposn += row_height;
}
}
@@ -636,7 +645,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
case 14:
case 15:
case 16:
rect->height += 5.0f;
rect->height += guard_height;
break;
}
i++;
@@ -651,7 +660,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
case 11:
case 20:
case 21:
rect->height += 5.0f;
rect->height += guard_height;
break;
}
i++;
@@ -670,7 +679,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
case 27:
case 28:
case 29:
rect->height += 5.0f;
rect->height += guard_height;
break;
}
i++;
@@ -685,7 +694,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
case 15:
case 28:
case 29:
rect->height += 5.0f;
rect->height += guard_height;
break;
}
i++;
@@ -696,8 +705,16 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
/* Add the text */
if (!hide_text) {
int textdone = 0;
float text_xposn;
float text_yposn;
xoffset += comp_offset;
xoffset += comp_xoffset;
text_yposn = yoffset + symbol->height + text_height + text_gap; /* Calculated to bottom of text */
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) {
text_yposn += symbol->border_width;
}
if (upceanflag) {
float textwidth;
@@ -705,115 +722,115 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
output_upcean_split_text(upceanflag, symbol->text, textpart1, textpart2, textpart3, textpart4);
if (upceanflag == 6) { /* UPC-E */
textpos = -5.0f + xoffset;
text_xposn = -5.0f + xoffset;
textwidth = 6.2f;
vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, upcae_outside_text_height,
textwidth, 2 /*right align*/, &last_string);
textpos = 24.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, upcae_outside_text_height,
textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 24.0f + xoffset;
textwidth = 6.0f * 8.5f;
vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
textpos = 51.0f + 3.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, text_height,
textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 51.0f + 3.0f + xoffset;
textwidth = 6.2f;
vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, upcae_outside_text_height,
textwidth, 1 /*left align*/, &last_string);
if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn, upcae_outside_text_height,
textwidth, 1 /*left align*/, &last_string)) return ZINT_ERROR_MEMORY;
textdone = 1;
switch (ustrlen(addon)) {
case 2:
textpos = 61.0f + xoffset + addon_gap;
text_xposn = 61.0f + xoffset + addon_gap;
textwidth = 2.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
case 5:
textpos = 75.0f + xoffset + addon_gap;
text_xposn = 75.0f + xoffset + addon_gap;
textwidth = 5.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
}
} else if (upceanflag == 8) { /* EAN-8 */
textpos = 17.0f + xoffset;
text_xposn = 17.0f + xoffset;
textwidth = 4.0f * 8.5f;
vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
textpos = 50.0f + xoffset;
vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 50.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
textdone = 1;
switch (ustrlen(addon)) {
case 2:
textpos = 77.0f + xoffset + addon_gap;
text_xposn = 77.0f + xoffset + addon_gap;
textwidth = 2.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
case 5:
textpos = 91.0f + xoffset + addon_gap;
text_xposn = 91.0f + xoffset + addon_gap;
textwidth = 5.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
}
} else if (upceanflag == 12) { /* UPC-A */
textpos = -5.0f + xoffset;
text_xposn = -5.0f + xoffset;
textwidth = 6.2f;
vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, upcae_outside_text_height,
textwidth, 2 /*right align*/, &last_string);
textpos = 27.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, upcae_outside_text_height,
textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 27.0f + xoffset;
textwidth = 5.0f * 8.5f;
vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
textpos = 67.0f + xoffset;
vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
textpos = 95.0f + 5.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, text_height,
textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 67.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn, text_height,
textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 95.0f + 5.0f + xoffset;
textwidth = 6.2f;
vector_plot_add_string(symbol, textpart4, textpos, default_text_posn, upcae_outside_text_height,
textwidth, 1 /*left align*/, &last_string);
if (!vector_plot_add_string(symbol, textpart4, text_xposn, text_yposn, upcae_outside_text_height,
textwidth, 1 /*left align*/, &last_string)) return ZINT_ERROR_MEMORY;
textdone = 1;
switch (ustrlen(addon)) {
case 2:
textpos = 105.0f + xoffset + addon_gap;
text_xposn = 105.0f + xoffset + addon_gap;
textwidth = 2.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
case 5:
textpos = 119.0f + xoffset + addon_gap;
text_xposn = 119.0f + xoffset + addon_gap;
textwidth = 5.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
}
} else if (upceanflag == 13) { /* EAN-13 */
textpos = -5.0f + xoffset;
text_xposn = -5.0f + xoffset;
textwidth = 8.5f;
vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, text_height, textwidth,
2 /*right align*/, &last_string);
textpos = 24.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn,
text_height, textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 24.0f + xoffset;
textwidth = 6.0f * 8.5f;
vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
textpos = 71.0f + xoffset;
vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 71.0f + xoffset;
if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
textdone = 1;
switch (ustrlen(addon)) {
case 2:
textpos = 105.0f + xoffset + addon_gap;
text_xposn = 105.0f + xoffset + addon_gap;
textwidth = 2.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
case 5:
textpos = 119.0f + xoffset + addon_gap;
text_xposn = 119.0f + xoffset + addon_gap;
textwidth = 5.0f * 8.5f;
vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0,
&last_string);
if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn,
text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY;
break;
}
}
@@ -822,70 +839,76 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
if (!textdone) {
/* Put normal human readable text at the bottom (and centered) */
// calculate start xoffset to center text
vector_plot_add_string(symbol, symbol->text, main_width / 2.0f + xoffset, default_text_posn, text_height,
symbol->width, 0, &last_string);
text_xposn = main_width / 2.0f + xoffset;
if (!vector_plot_add_string(symbol, symbol->text, text_xposn, text_yposn,
text_height, symbol->width, 0, &last_string)) return ZINT_ERROR_MEMORY;
}
xoffset -= comp_offset; // Restore xoffset
xoffset -= comp_xoffset; // Restore xoffset
}
// Binding and boxes
if (symbol->output_options & BARCODE_BIND) {
if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
float sep_height = 1.0f;
if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
sep_height = symbol->option_3;
}
/* row binding */
if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
for (r = 1; r < symbol->rows; r++) {
row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height;
rectangle = vector_plot_create_rect(xoffset, (r * row_height) + yoffset - sep_height / 2,
symbol->width, sep_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
}
} else {
for (r = 1; r < symbol->rows; r++) {
/* Avoid 11-module start and 13-module stop chars */
row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height;
rectangle = vector_plot_create_rect(xoffset + 11, (r * row_height) + yoffset - sep_height / 2,
symbol->width - 24, sep_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
}
}
// Separator binding for stacked barcodes
if ((symbol->output_options & BARCODE_BIND) && (symbol->rows > 1) && is_stackable(symbol->symbology)) {
float sep_xoffset = xoffset;
float sep_width = symbol->width;
float sep_height = 1.0f, sep_yoffset;
if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
sep_height = symbol->option_3;
}
sep_yoffset = yoffset - sep_height / 2;
if (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF) {
/* Avoid 11-module start and 13-module stop chars */
sep_xoffset += 11;
sep_width -= 11 + 13;
}
for (r = 1; r < symbol->rows; r++) {
float row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height;
rect = vector_plot_create_rect(symbol, sep_xoffset, (r * row_height) + sep_yoffset,
sep_width, sep_height);
if (!rect) return ZINT_ERROR_MEMORY;
vector_plot_add_rect(symbol, rect, &last_rectangle);
}
}
// Bind/box
if (symbol->border_width > 0) {
if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND)) {
float ybind_bottom = vector->height - symbol->border_width - textoffset - symbol->whitespace_height;
const float ybind_top = yoffset - symbol->border_width;
// Following equivalent to yoffset + symbol->height + dot_overspill except for BARCODE_MAXICODE
const float ybind_bot = vector->height - textoffset - boffset;
// Top
rectangle = vector_plot_create_rect(0.0f, symbol->whitespace_height, vector->width, symbol->border_width);
rect = vector_plot_create_rect(symbol, 0.0f, ybind_top, vector->width, symbol->border_width);
if (!rect) return ZINT_ERROR_MEMORY;
if (!(symbol->output_options & BARCODE_BOX)
&& (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) {
/* CodaBlockF bind - does not extend over horizontal whitespace */
rectangle->x = xoffset;
rectangle->width -= (2.0f * xoffset);
rect->x = xoffset;
rect->width -= xoffset + roffset;
}
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
vector_plot_add_rect(symbol, rect, &last_rectangle);
// Bottom
rectangle = vector_plot_create_rect(0.0f, ybind_bottom, vector->width, symbol->border_width);
rect = vector_plot_create_rect(symbol, 0.0f, ybind_bot, vector->width, symbol->border_width);
if (!rect) return ZINT_ERROR_MEMORY;
if (!(symbol->output_options & BARCODE_BOX)
&& (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) {
/* CodaBlockF bind - does not extend over horizontal whitespace */
rectangle->x = xoffset;
rectangle->width -= (2.0f * xoffset);
rect->x = xoffset;
rect->width -= xoffset + roffset;
}
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
vector_plot_add_rect(symbol, rect, &last_rectangle);
}
if (symbol->output_options & BARCODE_BOX) {
float xbox_right = vector->width - symbol->border_width;
float box_height = vector->height - textoffset - (symbol->whitespace_height + symbol->border_width) * 2;
// Following equivalent to symbol->height except for BARCODE_MAXICODE
float box_height = vector->height - textoffset - dot_overspill - yoffset - boffset;
// Left
rectangle = vector_plot_create_rect(0.0f, yoffset, symbol->border_width, box_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
rect = vector_plot_create_rect(symbol, 0.0f, yoffset, symbol->border_width, box_height);
if (!rect) return ZINT_ERROR_MEMORY;
vector_plot_add_rect(symbol, rect, &last_rectangle);
// Right
rectangle = vector_plot_create_rect(xbox_right, yoffset, symbol->border_width, box_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle);
rect = vector_plot_create_rect(symbol, xbox_right, yoffset, symbol->border_width, box_height);
if (!rect) return ZINT_ERROR_MEMORY;
vector_plot_add_rect(symbol, rect, &last_rectangle);
}
}