#include "common.h"
#include "output.h"
#include "zfiletypes.h"
INTERNAL int zint_ps_plot(struct zint_symbol *symbol);
INTERNAL int zint_svg_plot(struct zint_symbol *symbol);
INTERNAL int zint_emf_plot(struct zint_symbol *symbol, int rotate_angle);
static int vector_add_rect(struct zint_symbol *symbol, const float x, const float y, const float width,
const float height, struct zint_vector_rect **last_rect) {
struct zint_vector_rect *rect;
if (!(rect = (struct zint_vector_rect *) malloc(sizeof(struct zint_vector_rect)))) {
z_errtxt(0, symbol, 691, "Insufficient memory for vector rectangle");
return 0;
}
#ifdef ZINT_SANITIZEM
memset(rect, 0, sizeof(struct zint_vector_rect));
#endif
rect->next = NULL;
rect->x = x;
rect->y = y;
rect->width = width;
rect->height = height;
rect->colour = -1;
if (*last_rect)
(*last_rect)->next = rect;
else
symbol->vector->rectangles = rect;
*last_rect = rect;
return 1;
}
static int vector_add_hexagon(struct zint_symbol *symbol, const float x, const float y,
const float diameter, struct zint_vector_hexagon **last_hexagon) {
struct zint_vector_hexagon *hexagon;
if (!(hexagon = (struct zint_vector_hexagon *) malloc(sizeof(struct zint_vector_hexagon)))) {
return z_errtxt(0, symbol, 692, "Insufficient memory for vector hexagon");
}
#ifdef ZINT_SANITIZEM
memset(hexagon, 0, sizeof(struct zint_vector_hexagon));
#endif
hexagon->next = NULL;
hexagon->x = x;
hexagon->y = y;
hexagon->diameter = diameter;
hexagon->rotation = 0;
if (*last_hexagon)
(*last_hexagon)->next = hexagon;
else
symbol->vector->hexagons = hexagon;
*last_hexagon = hexagon;
return 1;
}
static int vector_add_circle(struct zint_symbol *symbol, const float x, const float y, const float diameter,
const float width, const int colour, struct zint_vector_circle **last_circle) {
struct zint_vector_circle *circle;
if (!(circle = (struct zint_vector_circle *) malloc(sizeof(struct zint_vector_circle)))) {
return z_errtxt(0, symbol, 693, "Insufficient memory for vector circle");
}
#ifdef ZINT_SANITIZEM
memset(circle, 0, sizeof(struct zint_vector_circle));
#endif
circle->next = NULL;
circle->x = x;
circle->y = y;
circle->diameter = diameter;
circle->width = width;
circle->colour = colour;
if (*last_circle)
(*last_circle)->next = circle;
else
symbol->vector->circles = circle;
*last_circle = circle;
return 1;
}
static int vector_add_string(struct zint_symbol *symbol, const unsigned char *text, const int length,
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;
if (!(string = (struct zint_vector_string *) malloc(sizeof(struct zint_vector_string)))) {
return z_errtxt(0, symbol, 694, "Insufficient memory for vector string");
}
#ifdef ZINT_SANITIZEM
memset(string, 0, sizeof(struct zint_vector_string));
#endif
string->next = NULL;
string->x = x;
string->y = y;
string->width = width;
string->fsize = fsize;
string->length = length == -1 ? (int) z_ustrlen(text) : length;
string->rotation = 0;
string->halign = halign;
if (!(string->text = (unsigned char *) malloc(string->length + 1))) {
free(string);
return z_errtxt(0, symbol, 695, "Insufficient memory for vector string text");
}
#ifdef ZINT_SANITIZEM
memset(string->text, 0, string->length + 1);
#endif
memcpy(string->text, text, string->length);
string->text[string->length] = '\0';
if (*last_string)
(*last_string)->next = string;
else
symbol->vector->strings = string;
*last_string = string;
return 1;
}
INTERNAL void zint_vector_free(struct zint_symbol *symbol) {
if (symbol->vector != NULL) {
struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
struct zint_vector_circle *circle;
struct zint_vector_string *string;
rect = symbol->vector->rectangles;
while (rect) {
struct zint_vector_rect *r = rect;
rect = rect->next;
free(r);
}
hex = symbol->vector->hexagons;
while (hex) {
struct zint_vector_hexagon *h = hex;
hex = hex->next;
free(h);
}
circle = symbol->vector->circles;
while (circle) {
struct zint_vector_circle *c = circle;
circle = circle->next;
free(c);
}
string = symbol->vector->strings;
while (string) {
struct zint_vector_string *s = string;
string = string->next;
free(s->text);
free(s);
}
free(symbol->vector);
symbol->vector = NULL;
}
}
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;
struct zint_vector_string *string;
float scale = symbol->scale * 2.0f;
if (scale < 0.2f) {
scale = 0.2f;
}
if (file_type == OUT_EMF_FILE && symbol->symbology == BARCODE_MAXICODE) {
scale *= 20;
}
symbol->vector->width = z_stripf(symbol->vector->width * scale);
symbol->vector->height = z_stripf(symbol->vector->height * scale);
rect = symbol->vector->rectangles;
while (rect) {
rect->x = z_stripf(rect->x * scale);
rect->y = z_stripf(rect->y * scale);
rect->height = z_stripf(rect->height * scale);
rect->width = z_stripf(rect->width * scale);
rect = rect->next;
}
hex = symbol->vector->hexagons;
while (hex) {
hex->x = z_stripf(hex->x * scale);
hex->y = z_stripf(hex->y * scale);
hex->diameter = z_stripf(hex->diameter * scale);
hex = hex->next;
}
circle = symbol->vector->circles;
while (circle) {
circle->x = z_stripf(circle->x * scale);
circle->y = z_stripf(circle->y * scale);
circle->diameter = z_stripf(circle->diameter * scale);
circle->width = z_stripf(circle->width * scale);
circle = circle->next;
}
string = symbol->vector->strings;
while (string) {
string->x = z_stripf(string->x * scale);
string->y = z_stripf(string->y * scale);
string->width = z_stripf(string->width * scale);
string->fsize = z_stripf(string->fsize * scale);
string = string->next;
}
}
static void vector_rotate(struct zint_symbol *symbol, const int rotate_angle) {
struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
struct zint_vector_circle *circle;
struct zint_vector_string *string;
float temp;
if (rotate_angle == 0) {
return;
}
rect = symbol->vector->rectangles;
while (rect) {
if (rotate_angle == 90) {
temp = rect->x;
rect->x = z_stripf(symbol->vector->height - (rect->y + rect->height));
rect->y = temp;
temp = rect->width;
rect->width = rect->height;
rect->height = temp;
} else if (rotate_angle == 180) {
rect->x = z_stripf(symbol->vector->width - (rect->x + rect->width));
rect->y = z_stripf(symbol->vector->height - (rect->y + rect->height));
} else if (rotate_angle == 270) {
temp = rect->x;
rect->x = rect->y;
rect->y = z_stripf(symbol->vector->width - (temp + rect->width));
temp = rect->width;
rect->width = rect->height;
rect->height = temp;
}
rect = rect->next;
}
hex = symbol->vector->hexagons;
while (hex) {
if (rotate_angle == 90) {
temp = hex->x;
hex->x = z_stripf(symbol->vector->height - hex->y);
hex->y = temp;
hex->rotation = 90;
} else if (rotate_angle == 180) {
hex->x = z_stripf(symbol->vector->width - hex->x);
hex->y = z_stripf(symbol->vector->height - hex->y);
hex->rotation = 180;
} else if (rotate_angle == 270) {
temp = hex->x;
hex->x = hex->y;
hex->y = z_stripf(symbol->vector->width - temp);
hex->rotation = 270;
}
hex = hex->next;
}
circle = symbol->vector->circles;
while (circle) {
if (rotate_angle == 90) {
temp = circle->x;
circle->x = z_stripf(symbol->vector->height - circle->y);
circle->y = temp;
} else if (rotate_angle == 180) {
circle->x = z_stripf(symbol->vector->width - circle->x);
circle->y = z_stripf(symbol->vector->height - circle->y);
} else if (rotate_angle == 270) {
temp = circle->x;
circle->x = circle->y;
circle->y = z_stripf(symbol->vector->width - temp);
}
circle = circle->next;
}
string = symbol->vector->strings;
while (string) {
if (rotate_angle == 90) {
temp = string->x;
string->x = z_stripf(symbol->vector->height - string->y);
string->y = temp;
string->rotation = 90;
} else if (rotate_angle == 180) {
string->x = z_stripf(symbol->vector->width - string->x);
string->y = z_stripf(symbol->vector->height - string->y);
string->rotation = 180;
} else if (rotate_angle == 270) {
temp = string->x;
string->x = string->y;
string->y = z_stripf(symbol->vector->width - temp);
string->rotation = 270;
}
string = string->next;
}
if (rotate_angle == 90 || rotate_angle == 270) {
temp = symbol->vector->height;
symbol->vector->height = symbol->vector->width;
symbol->vector->width = temp;
}
}
static void vector_reduce_rectangles(struct zint_symbol *symbol) {
struct zint_vector_rect *rect, *target, *prev;
rect = symbol->vector->rectangles;
while (rect) {
prev = rect;
target = prev->next;
while (target) {
if (rect->x == target->x && rect->width == target->width && z_stripf(rect->y + rect->height) == target->y
&& rect->colour == target->colour) {
rect->height += target->height;
prev->next = target->next;
free(target);
} else {
prev = target;
}
target = prev->next;
}
rect = rect->next;
}
}
INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type) {
int error_number, warn_number = 0;
int main_width;
int comp_xoffset = 0;
int comp_roffset = 0;
unsigned char addon[6];
int addon_len = 0;
int addon_gap = 0;
float addon_text_yposn = 0.0f;
float xoffset, yoffset, roffset, boffset, qz_right;
float textoffset;
int upceanflag = 0;
int addon_latch = 0;
int hide_text;
int i, r;
int block_width = 0;
int font_height;
float text_gap;
float guard_descent;
const int upcean_guard_whitespace = !(symbol->output_options & BARCODE_NO_QUIET_ZONES)
&& (symbol->output_options & EANUPC_GUARD_WHITESPACE);
const int is_codablockf = symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF;
const int no_extend = is_codablockf || symbol->symbology == BARCODE_DPD;
float large_bar_height;
int xoffset_comp;
const float descent = 1.32779717f;
const float descent_small = 0.948426545f;
float addon_row_yposn = 0.0f;
float addon_row_height = 0.0f;
int upcae_outside_font_height = 0;
const float gws_left_fudge = 0.5f;
const float gws_right_fudge = 0.5f;
const float digit_ascender_factor = 0.22f;
float digit_ascender = 0.0f;
const float antialias_fudge_factor = 0.02f;
float antialias_fudge = 0.0f;
int rect_count = 0, last_row_start = 0;
float dot_overspill = 0.0f;
float dot_offset = 0.0f;
float yposn;
struct zint_vector *vector;
struct zint_vector_rect *rect, *last_rect = NULL;
struct zint_vector_hexagon *last_hexagon = NULL;
struct zint_vector_string *last_string = NULL;
struct zint_vector_circle *last_circle = NULL;
struct zint_vector_rect **first_row_rects
= (struct zint_vector_rect **) z_alloca(sizeof(struct zint_vector_rect *) * (symbol->rows + 1));
memset(first_row_rects, 0, sizeof(struct zint_vector_rect *) * (symbol->rows + 1));
zint_vector_free(symbol);
error_number = zint_out_check_colour_options(symbol);
if (error_number != 0) {
return error_number;
}
if (symbol->rows <= 0) {
return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 697, "No rows");
}
if (!(vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector)))) {
return z_errtxt(ZINT_ERROR_MEMORY, symbol, 696, "Insufficient memory for vector header");
}
#ifdef ZINT_SANITIZEM
memset(vector, 0, sizeof(struct zint_vector));
#endif
vector->rectangles = NULL;
vector->hexagons = NULL;
vector->circles = NULL;
vector->strings = NULL;
large_bar_height = zint_out_large_bar_height(symbol, 0 , NULL ,
NULL );
main_width = symbol->width;
if (z_is_composite(symbol->symbology)) {
while (!z_module_is_set(symbol, symbol->rows - 1, comp_xoffset)) {
comp_xoffset++;
}
}
if (z_is_upcean(symbol->symbology)) {
upceanflag = zint_out_process_upcean(symbol, comp_xoffset, &main_width, addon, &addon_len, &addon_gap);
} else if (z_is_composite(symbol->symbology)) {
int x;
for (x = symbol->width - 1; x && !z_module_is_set(symbol, symbol->rows - 1, x); comp_roffset++, x--);
main_width -= comp_xoffset + comp_roffset;
}
hide_text = !symbol->show_hrt || symbol->text_length == 0;
zint_out_set_whitespace_offsets(symbol, hide_text, comp_xoffset, &xoffset, &yoffset, &roffset, &boffset,
&qz_right, 0 , NULL, NULL, NULL, NULL, NULL);
xoffset_comp = xoffset + comp_xoffset;
if (symbol->symbology != BARCODE_MAXICODE && (symbol->output_options & BARCODE_DOTTY_MODE)) {
if (symbol->dot_size < 1.0f) {
dot_overspill = 0.0f;
dot_offset = 0.5f;
} else {
dot_overspill = symbol->dot_size - 1.0f + 0.1f;
dot_offset = symbol->dot_size / 2.0f + 0.05f;
}
}
vector->width = symbol->width + dot_overspill + (xoffset + roffset);
if (upceanflag) {
font_height = symbol->output_options & SMALL_TEXT ? 7 : 10;
digit_ascender = font_height * digit_ascender_factor;
antialias_fudge = font_height * antialias_fudge_factor;
upcae_outside_font_height = symbol->output_options & SMALL_TEXT ? 6 : 7;
text_gap = symbol->text_gap - digit_ascender;
guard_descent = upceanflag >= 6 ? symbol->guard_descent : 0.0f;
} else {
font_height = symbol->output_options & SMALL_TEXT ? 5 : 7;
antialias_fudge = font_height * antialias_fudge_factor;
text_gap = symbol->text_gap;
guard_descent = 0.0f;
}
if (hide_text) {
textoffset = guard_descent;
} else {
textoffset = font_height + z_stripf(text_gap + antialias_fudge);
if (upceanflag) {
if (textoffset < guard_descent) {
textoffset = guard_descent;
}
}
}
vector->height = symbol->height + textoffset + dot_overspill + (yoffset + boffset);
if (symbol->symbology == BARCODE_MAXICODE) {
float bull_x, bull_y, bull_d_incr, bull_width;
const float two_div_sqrt3 = 1.1547f;
const float sqrt3_div_two = 0.866f;
const float hex_diameter = 1.0f;
const float hex_radius = hex_diameter / 2.0f;
const float hex_ydiameter = two_div_sqrt3 * hex_diameter;
const float hex_yradius = hex_ydiameter / 2.0f;
const float yposn_offset = sqrt3_div_two * hex_diameter;
vector->width = 30 * hex_diameter + (xoffset + roffset);
vector->height = 32 * yposn_offset + hex_ydiameter + (yoffset + boffset);
bull_x = 14.5f * hex_diameter + xoffset;
bull_y = vector->height / 2.0f;
bull_d_incr = (hex_diameter * 9 - hex_ydiameter) / 5.0f;
bull_width = bull_d_incr / 2.0f;
if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, 0,
&last_circle)) return ZINT_ERROR_MEMORY;
if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, 0,
&last_circle)) return ZINT_ERROR_MEMORY;
if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr - bull_width, bull_width, 0,
&last_circle)) return ZINT_ERROR_MEMORY;
for (r = 0; r < symbol->rows; r++) {
const int odd_row = r & 1;
const float hex_yposn = r * yposn_offset + hex_yradius + yoffset;
const float xposn_offset = (odd_row ? hex_diameter : hex_radius) + xoffset;
for (i = 0; i < symbol->width - odd_row; i++) {
if (z_module_is_set(symbol, r, i)) {
const float hex_xposn = i * hex_diameter + xposn_offset;
if (!vector_add_hexagon(symbol, hex_xposn, hex_yposn, hex_diameter, &last_hexagon))
return ZINT_ERROR_MEMORY;
}
}
}
} else if (symbol->output_options & BARCODE_DOTTY_MODE) {
for (r = 0; r < symbol->rows; r++) {
for (i = 0; i < symbol->width; i++) {
if (z_module_is_set(symbol, r, i)) {
if (!vector_add_circle(symbol, i + dot_offset + xoffset, r + dot_offset + yoffset,
symbol->dot_size, 0, 0, &last_circle)) return ZINT_ERROR_MEMORY;
}
}
}
} else if (symbol->symbology == BARCODE_ULTRA) {
yposn = yoffset;
for (r = 0; r < symbol->rows; r++) {
const float row_height = symbol->row_height[r];
for (i = 0; i < symbol->width; i += block_width) {
const int fill = z_module_colour_is_set(symbol, r, i);
for (block_width = 1; (i + block_width < symbol->width)
&& z_module_colour_is_set(symbol, r, i + block_width) == fill; block_width++);
if (fill) {
if (!vector_add_rect(symbol, i + xoffset, yposn, block_width, row_height, &last_rect))
return ZINT_ERROR_MEMORY;
last_rect->colour = z_module_colour_is_set(symbol, r, i);
}
}
yposn += row_height;
}
} else if (upceanflag >= 6) {
yposn = yoffset;
for (r = 0; r < symbol->rows; r++) {
const float row_height = symbol->row_height[r] ? symbol->row_height[r] : large_bar_height;
last_row_start = rect_count;
for (i = 0; i < symbol->width; i += block_width) {
const int fill = z_module_is_set(symbol, r, i);
for (block_width = 1; (i + block_width < symbol->width)
&& z_module_is_set(symbol, r, i + block_width) == fill; block_width++);
if (r == symbol->rows - 1 && i > main_width && addon_latch == 0) {
addon_text_yposn = yposn + font_height - digit_ascender;
if (addon_text_yposn < 0.0f) {
addon_text_yposn = 0.0f;
}
addon_row_yposn = yposn + font_height + text_gap + antialias_fudge;
addon_row_height = row_height - (addon_row_yposn - yposn);
addon_row_height += guard_descent;
if (addon_row_height < 0.5f) {
addon_row_height = 0.5f;
}
addon_latch = 1;
}
if (fill) {
if (addon_latch) {
if (!vector_add_rect(symbol, i + xoffset, addon_row_yposn, block_width, addon_row_height,
&last_rect)) return ZINT_ERROR_MEMORY;
} else {
if (!vector_add_rect(symbol, i + xoffset, yposn, block_width, row_height, &last_rect))
return ZINT_ERROR_MEMORY;
}
rect_count++;
}
}
yposn += row_height;
}
} else {
yposn = yoffset;
if (upceanflag && !hide_text) {
yposn += font_height + text_gap + antialias_fudge;
}
for (r = 0; r < symbol->rows; r++) {
const float row_height = symbol->row_height[r] ? symbol->row_height[r] : large_bar_height;
for (i = 0; i < symbol->width; i += block_width) {
const int fill = z_module_is_set(symbol, r, i);
for (block_width = 1; (i + block_width < symbol->width)
&& z_module_is_set(symbol, r, i + block_width) == fill; block_width++);
if (fill) {
if (!vector_add_rect(symbol, i + xoffset, yposn, block_width, row_height, &last_rect))
return ZINT_ERROR_MEMORY;
if (i == 0) {
first_row_rects[r] = last_rect;
}
}
}
yposn += row_height;
}
}
if (guard_descent && upceanflag >= 6) {
if (upceanflag == 6) {
i = 0;
for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
switch (i - last_row_start) {
case 0:
case 1:
case 14:
case 15:
case 16:
rect->height += guard_descent;
break;
}
i++;
}
} else if (upceanflag == 8) {
i = 0;
for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
switch (i - last_row_start) {
case 0:
case 1:
case 10:
case 11:
case 20:
case 21:
rect->height += guard_descent;
break;
}
i++;
}
} else if (upceanflag == 12) {
i = 0;
for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
switch (i - last_row_start) {
case 0:
case 1:
case 2:
case 3:
case 14:
case 15:
case 26:
case 27:
case 28:
case 29:
rect->height += guard_descent;
break;
}
i++;
}
} else {
i = 0;
for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
switch (i - last_row_start) {
case 0:
case 1:
case 14:
case 15:
case 28:
case 29:
rect->height += guard_descent;
break;
}
i++;
}
}
}
if (!hide_text) {
float textwidth;
if (upceanflag >= 6) {
float text_yposn = yoffset + symbol->height + font_height + text_gap - antialias_fudge;
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))
&& !(symbol->output_options & BARCODE_BIND_TOP)) {
text_yposn += symbol->border_width;
}
if (upceanflag == 6) {
float text_xposn = -(5.0f - 0.35f) + xoffset_comp;
textwidth = 6.2f;
if (!vector_add_string(symbol, symbol->text, 1, text_xposn, text_yposn, upcae_outside_font_height,
textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (24.0f + 0.5f) + xoffset_comp;
textwidth = 6.0f * 8.5f;
if (!vector_add_string(symbol, symbol->text + 1, 6, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (51.0f - 0.35f) + 2.0f + xoffset_comp;
textwidth = 6.2f;
if (!vector_add_string(symbol, symbol->text + 7, 1, text_xposn, text_yposn, upcae_outside_font_height,
textwidth, 1 , &last_string)) return ZINT_ERROR_MEMORY;
if (addon_len) {
text_xposn = (addon_len == 2 ? 61.0f : 75.0f) + xoffset_comp + addon_gap;
textwidth = addon_len * 8.5f;
if (!vector_add_string(symbol, addon, addon_len, text_xposn, addon_text_yposn, font_height,
textwidth, 0 , &last_string)) return ZINT_ERROR_MEMORY;
if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
}
} else if (upceanflag == 8) {
float text_xposn;
if (upcean_guard_whitespace) {
text_xposn = -7.0f - gws_left_fudge + xoffset_comp;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) "<", 1, text_xposn, text_yposn,
font_height, textwidth, 1 , &last_string)) return ZINT_ERROR_MEMORY;
}
text_xposn = (17.0f + 0.5f) + xoffset_comp;
textwidth = 4.0f * 8.5f;
if (!vector_add_string(symbol, symbol->text, 4, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (50.0f - 0.5f) + xoffset_comp;
if (!vector_add_string(symbol, symbol->text + 4, 4, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
if (addon_len) {
text_xposn = (addon_len == 2 ? 77.0f : 91.0f) + xoffset_comp + addon_gap;
textwidth = addon_len * 8.5f;
if (!vector_add_string(symbol, addon, addon_len, text_xposn, addon_text_yposn, font_height,
textwidth, 0 , &last_string)) return ZINT_ERROR_MEMORY;
if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
} else if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
} else if (upceanflag == 12) {
float text_xposn = -(5.0f - 0.35f) + xoffset_comp;
textwidth = 6.2f;
if (!vector_add_string(symbol, symbol->text, 1, text_xposn, text_yposn, upcae_outside_font_height,
textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 28.0f + xoffset_comp;
textwidth = 5.0f * 8.5f;
if (!vector_add_string(symbol, symbol->text + 1, 5, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = 67.0f + xoffset_comp;
if (!vector_add_string(symbol, symbol->text + 6, 5, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (95.0f - 0.35f) + 4.0f + xoffset_comp;
textwidth = 6.2f;
if (!vector_add_string(symbol, symbol->text + 11, 1, text_xposn, text_yposn,
upcae_outside_font_height, textwidth, 1 , &last_string)) {
return ZINT_ERROR_MEMORY;
}
if (addon_len) {
text_xposn = (addon_len == 2 ? 105.0f : 119.0f) + xoffset_comp + addon_gap;
textwidth = addon_len * 8.5f;
if (!vector_add_string(symbol, addon, addon_len, text_xposn, addon_text_yposn, font_height,
textwidth, 0 , &last_string)) return ZINT_ERROR_MEMORY;
if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
}
} else {
float text_xposn = -(5.0f - 0.1f) + xoffset_comp;
textwidth = 8.5f;
if (!vector_add_string(symbol, symbol->text, 1, text_xposn, text_yposn, font_height, textwidth,
2 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (24.0f + 0.5f) + xoffset_comp;
textwidth = 6.0f * 8.5f;
if (!vector_add_string(symbol, symbol->text + 1, 6, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
text_xposn = (71.0f - 0.5f) + xoffset_comp;
if (!vector_add_string(symbol, symbol->text + 7, 6, text_xposn, text_yposn, font_height, textwidth,
0 , &last_string)) return ZINT_ERROR_MEMORY;
if (addon_len) {
text_xposn = (addon_len == 2 ? 105.0f : 119.0f) + xoffset_comp + addon_gap;
textwidth = addon_len * 8.5f;
if (!vector_add_string(symbol, addon, addon_len, text_xposn, addon_text_yposn, font_height,
textwidth, 0 , &last_string)) return ZINT_ERROR_MEMORY;
if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, addon_text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
} else if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
}
} else if (upceanflag) {
float text_xposn = main_width / 2.0f + xoffset;
float text_yposn = yoffset + font_height - digit_ascender;
if (symbol->border_width > 0
&& (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
text_yposn -= symbol->border_width;
}
if (text_yposn < 0.0f) {
text_yposn = 0.0f;
}
addon_len = symbol->text_length;
textwidth = addon_len * 8.5f;
if (!vector_add_string(symbol, symbol->text, addon_len, text_xposn, text_yposn, font_height,
textwidth, 0 , &last_string)) return ZINT_ERROR_MEMORY;
if (upcean_guard_whitespace) {
text_xposn = symbol->width + gws_right_fudge + qz_right + xoffset;
textwidth = 8.5f;
if (!vector_add_string(symbol, (const unsigned char *) ">", 1, text_xposn, text_yposn,
font_height, textwidth, 2 , &last_string)) return ZINT_ERROR_MEMORY;
}
} else {
float text_xposn = main_width / 2.0f + xoffset_comp;
float text_yposn = yoffset + symbol->height + font_height + text_gap;
text_yposn -= symbol->output_options & SMALL_TEXT ? descent_small : descent;
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))
&& !(symbol->output_options & BARCODE_BIND_TOP)) {
text_yposn += symbol->border_width;
}
if (!vector_add_string(symbol, symbol->text, -1, text_xposn, text_yposn, font_height, symbol->width, 0,
&last_string)) return ZINT_ERROR_MEMORY;
}
}
if ((symbol->output_options & BARCODE_BIND) && symbol->rows > 1 && z_is_bindable(symbol->symbology)) {
float sep_xoffset = xoffset;
float sep_width = symbol->width;
float sep_height = 1.0f, sep_yoffset, sep_half_height;
if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
sep_height = symbol->option_3;
}
sep_half_height = sep_height / 2.0f;
sep_yoffset = yoffset - sep_half_height;
if (is_codablockf) {
sep_xoffset += 11;
sep_width -= 11 + 13;
}
for (r = 0; r < symbol->rows; r++) {
for (rect = first_row_rects[r], i = 0; rect && rect != first_row_rects[r + 1]; rect = rect->next, i++) {
if (is_codablockf) {
if (i < 3) {
continue;
}
if ((i / 3) * 11 + 13 >= symbol->width) {
break;
}
}
if (r != 0) {
rect->y += sep_height - sep_half_height;
rect->height -= r + 1 == symbol->rows ? sep_half_height : sep_height;
} else {
rect->height -= sep_half_height;
}
if (rect->height < 0) {
rect->height = 0.0f;
}
}
}
for (r = 1; r < symbol->rows; r++) {
const float row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height;
if (!vector_add_rect(symbol, sep_xoffset, (r * row_height) + sep_yoffset, sep_width, sep_height,
&last_rect)) return ZINT_ERROR_MEMORY;
}
}
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND | BARCODE_BIND_TOP))) {
const int horz_outside = z_is_fixed_ratio(symbol->symbology);
float ybind_top = yoffset - symbol->border_width;
float ybind_bot = vector->height - textoffset - boffset;
if (horz_outside) {
ybind_top = 0;
ybind_bot = vector->height - symbol->border_width;
} else if (upceanflag == 2 || upceanflag == 5) {
ybind_top += textoffset;
ybind_bot += textoffset;
}
if (!vector_add_rect(symbol, 0.0f, ybind_top, vector->width, symbol->border_width, &last_rect))
return ZINT_ERROR_MEMORY;
if (!(symbol->output_options & BARCODE_BOX) && no_extend) {
last_rect->x = xoffset;
last_rect->width -= xoffset + roffset;
}
if (!(symbol->output_options & BARCODE_BIND_TOP)) {
if (!vector_add_rect(symbol, 0.0f, ybind_bot, vector->width, symbol->border_width, &last_rect))
return ZINT_ERROR_MEMORY;
if (!(symbol->output_options & BARCODE_BOX) && no_extend) {
last_rect->x = xoffset;
last_rect->width -= xoffset + roffset;
}
}
if (symbol->output_options & BARCODE_BOX) {
const float xbox_right = vector->width - symbol->border_width;
float box_top = yoffset;
float box_height = vector->height - textoffset - dot_overspill - yoffset - boffset;
if (horz_outside) {
box_top = symbol->border_width;
box_height = vector->height - symbol->border_width * 2;
} else if (upceanflag == 2 || upceanflag == 5) {
box_top += textoffset;
}
if (!vector_add_rect(symbol, 0.0f, box_top, symbol->border_width, box_height, &last_rect))
return ZINT_ERROR_MEMORY;
if (!vector_add_rect(symbol, xbox_right, box_top, symbol->border_width, box_height, &last_rect))
return ZINT_ERROR_MEMORY;
}
}
vector_reduce_rectangles(symbol);
vector_scale(symbol, file_type);
if (file_type != OUT_EMF_FILE) {
vector_rotate(symbol, rotate_angle);
}
switch (file_type) {
case OUT_EPS_FILE:
error_number = zint_ps_plot(symbol);
break;
case OUT_SVG_FILE:
error_number = zint_svg_plot(symbol);
break;
case OUT_EMF_FILE:
error_number = zint_emf_plot(symbol, rotate_angle);
break;
}
return error_number ? error_number : warn_number;
}