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:
413
backend/vector.c
413
backend/vector.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user