Allow image rotation for SVG and EPS files

This commit is contained in:
Robin Stuart 2020-08-05 21:23:11 +01:00
parent 980e039743
commit 79aaa5304d
6 changed files with 215 additions and 39 deletions

View File

@ -434,18 +434,33 @@ INTERNAL int emf_plot(struct zint_symbol *symbol) {
hexagon[this_hexagon].count = 6; hexagon[this_hexagon].count = 6;
radius = hex->diameter / 2.0; radius = hex->diameter / 2.0;
ay = hex->y + (1.0 * radius); if ((hex->rotation == 0) || (hex->rotation == 180)) {
by = hex->y + (0.5 * radius); ay = hex->y + (1.0 * radius);
cy = hex->y - (0.5 * radius); by = hex->y + (0.5 * radius);
dy = hex->y - (1.0 * radius); cy = hex->y - (0.5 * radius);
ey = hex->y - (0.5 * radius); dy = hex->y - (1.0 * radius);
fy = hex->y + (0.5 * radius); ey = hex->y - (0.5 * radius);
ax = hex->x; fy = hex->y + (0.5 * radius);
bx = hex->x + (0.86 * radius); ax = hex->x;
cx = hex->x + (0.86 * radius); bx = hex->x + (0.86 * radius);
dx = hex->x; cx = hex->x + (0.86 * radius);
ex = hex->x - (0.86 * radius); dx = hex->x;
fx = hex->x - (0.86 * radius); ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
} else {
ay = hex->y;
by = hex->y + (0.86 * radius);
cy = hex->y + (0.86 * radius);
dy = hex->y;
ey = hex->y - (0.86 * radius);
fy = hex->y - (0.86 * radius);
ax = hex->x - (1.0 * radius);
bx = hex->x - (0.5 * radius);
cx = hex->x + (0.5 * radius);
dx = hex->x + (1.0 * radius);
ex = hex->x + (0.5 * radius);
fx = hex->x - (0.5 * radius);
}
hexagon[this_hexagon].a_points_a.x = ax; hexagon[this_hexagon].a_points_a.x = ax;
hexagon[this_hexagon].a_points_a.y = ay; hexagon[this_hexagon].a_points_a.y = ay;

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2018 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -269,18 +269,33 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
hex = symbol->vector->hexagons; hex = symbol->vector->hexagons;
while (hex) { while (hex) {
radius = hex->diameter / 2.0; radius = hex->diameter / 2.0;
ay = (symbol->vector->height - hex->y) + (1.0 * radius); if ((hex->rotation == 0) || (hex->rotation == 180)) {
by = (symbol->vector->height - hex->y) + (0.5 * radius); ay = (symbol->vector->height - hex->y) + (1.0 * radius);
cy = (symbol->vector->height - hex->y) - (0.5 * radius); by = (symbol->vector->height - hex->y) + (0.5 * radius);
dy = (symbol->vector->height - hex->y) - (1.0 * radius); cy = (symbol->vector->height - hex->y) - (0.5 * radius);
ey = (symbol->vector->height - hex->y) - (0.5 * radius); dy = (symbol->vector->height - hex->y) - (1.0 * radius);
fy = (symbol->vector->height - hex->y) + (0.5 * radius); ey = (symbol->vector->height - hex->y) - (0.5 * radius);
ax = hex->x; fy = (symbol->vector->height - hex->y) + (0.5 * radius);
bx = hex->x + (0.86 * radius); ax = hex->x;
cx = hex->x + (0.86 * radius); bx = hex->x + (0.86 * radius);
dx = hex->x; cx = hex->x + (0.86 * radius);
ex = hex->x - (0.86 * radius); dx = hex->x;
fx = hex->x - (0.86 * radius); ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
} else {
ay = (symbol->vector->height - hex->y);
by = (symbol->vector->height - hex->y) + (0.86 * radius);
cy = (symbol->vector->height - hex->y) + (0.86 * radius);
dy = (symbol->vector->height - hex->y);
ey = (symbol->vector->height - hex->y) - (0.86 * radius);
fy = (symbol->vector->height - hex->y) - (0.86 * radius);
ax = hex->x - (1.0 * radius);
bx = hex->x - (0.5 * radius);
cx = hex->x + (0.5 * radius);
dx = hex->x + (1.0 * radius);
ex = hex->x + (0.5 * radius);
fx = hex->x - (0.5 * radius);
}
fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy); fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
hex = hex->next; hex = hex->next;
} }
@ -312,15 +327,23 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
// Text // Text
string = symbol->vector->strings; string = symbol->vector->strings;
while (string) { while (string) {
fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "%.2f scalefont setfont\n", string->fsize); fprintf(feps, "%.2f scalefont setfont\n", string->fsize);
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", string->x, (symbol->vector->height - string->y)); fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", string->x, (symbol->vector->height - string->y));
fprintf(feps, " (%s) stringwidth\n", string->text); fprintf(feps, " (%s) stringwidth\n", string->text);
if (string->rotation != 0) {
fprintf(feps, "gsave\n");
fprintf(feps, "%d rotate\n", 360 - string->rotation);
}
fprintf(feps, "pop\n"); fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", string->text); fprintf(feps, " (%s) show\n", string->text);
if (string->rotation != 0) {
fprintf(feps, "grestore\n");
}
fprintf(feps, "setmatrix\n"); fprintf(feps, "setmatrix\n");
string = string->next; string = string->next;
} }

View File

@ -224,18 +224,33 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
hex = symbol->vector->hexagons; hex = symbol->vector->hexagons;
while (hex) { while (hex) {
radius = hex->diameter / 2.0; radius = hex->diameter / 2.0;
ay = hex->y + (1.0 * radius); if ((hex->rotation == 0) || (hex->rotation == 180)) {
by = hex->y + (0.5 * radius); ay = hex->y + (1.0 * radius);
cy = hex->y - (0.5 * radius); by = hex->y + (0.5 * radius);
dy = hex->y - (1.0 * radius); cy = hex->y - (0.5 * radius);
ey = hex->y - (0.5 * radius); dy = hex->y - (1.0 * radius);
fy = hex->y + (0.5 * radius); ey = hex->y - (0.5 * radius);
ax = hex->x; fy = hex->y + (0.5 * radius);
bx = hex->x + (0.86 * radius); ax = hex->x;
cx = hex->x + (0.86 * radius); bx = hex->x + (0.86 * radius);
dx = hex->x; cx = hex->x + (0.86 * radius);
ex = hex->x - (0.86 * radius); dx = hex->x;
fx = hex->x - (0.86 * radius); ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
} else {
ay = hex->y;
by = hex->y + (0.86 * radius);
cy = hex->y + (0.86 * radius);
dy = hex->y;
ey = hex->y - (0.86 * radius);
fy = hex->y - (0.86 * radius);
ax = hex->x - (1.0 * radius);
bx = hex->x - (0.5 * radius);
cx = hex->x + (0.5 * radius);
dx = hex->x + (1.0 * radius);
ex = hex->x + (0.5 * radius);
fx = hex->x - (0.5 * radius);
}
fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\"", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy); fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\"", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
if (fg_alpha != 0xff) { if (fg_alpha != 0xff) {
fprintf(fsvg, " opacity=\"%.3f\"", (float) fg_alpha / 255.0); fprintf(fsvg, " opacity=\"%.3f\"", (float) fg_alpha / 255.0);
@ -270,6 +285,9 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
if (fg_alpha != 0xff) { if (fg_alpha != 0xff) {
fprintf(fsvg, " opacity=\"%.3f\"", (float) fg_alpha / 255.0); fprintf(fsvg, " opacity=\"%.3f\"", (float) fg_alpha / 255.0);
} }
if (string->rotation != 0) {
fprintf(fsvg, " transform=\"rotate(%d,%.2f,%.2f)\"", string->rotation, string->x, string->y);
}
fprintf(fsvg, " >\n"); fprintf(fsvg, " >\n");
make_html_friendly(string->text, html_string); make_html_friendly(string->text, html_string);
fprintf(fsvg, " %s\n", html_string); fprintf(fsvg, " %s\n", html_string);

View File

@ -80,6 +80,7 @@ static struct zint_vector_hexagon *vector_plot_create_hexagon(double x, double y
hexagon->x = x; hexagon->x = x;
hexagon->y = y; hexagon->y = y;
hexagon->diameter = (diameter * 5.0) / 4.0; // Ugly kludge for legacy support hexagon->diameter = (diameter * 5.0) / 4.0; // Ugly kludge for legacy support
hexagon->rotation = 0;
return hexagon; return hexagon;
} }
@ -132,6 +133,7 @@ static int vector_plot_add_string(struct zint_symbol *symbol,
string->width = width; string->width = width;
string->fsize = fsize; string->fsize = fsize;
string->length = ustrlen(text); string->length = ustrlen(text);
string->rotation = 0;
string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1)); string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1));
ustrcpy(string->text, text); ustrcpy(string->text, text);
@ -241,6 +243,116 @@ static void vector_scale(struct zint_symbol *symbol, int file_type) {
return; return;
} }
static void vector_rotate(struct zint_symbol *symbol, int rotate_angle) {
// Rotates the image
struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
struct zint_vector_circle *circle;
struct zint_vector_string *string;
int temp;
if (rotate_angle == 0) {
// No rotation needed
return;
}
rect = symbol->vector->rectangles;
while (rect) {
if (rotate_angle == 90) {
temp = rect->x;
rect->x = symbol->vector->height - (rect->y + rect->height);
rect->y = temp;
temp = rect->width;
rect->width = rect->height;
rect->height = temp;
}
if (rotate_angle == 180) {
rect->x = symbol->vector->width - (rect->x + rect->width);
rect->y = symbol->vector->height - (rect->y + rect->height);
}
if (rotate_angle == 270) {
temp = rect->x;
rect->x = rect->y;
rect->y = 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 = symbol->vector->height - hex->y;
hex->y = temp;
hex->rotation = 90;
}
if (rotate_angle == 180) {
hex->x = symbol->vector->width - hex->x;
hex->y = symbol->vector->height - hex->y;
hex->rotation = 180;
}
if (rotate_angle == 270) {
temp = hex->x;
hex->x = hex->y;
hex->y = 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 = symbol->vector->height - circle->y;
circle->y = temp;
}
if (rotate_angle == 180) {
circle->x = symbol->vector->width - circle->x;
circle->y = symbol->vector->height - circle->y;
}
if (rotate_angle == 270) {
temp = circle->x;
circle->x = circle->y;
circle->y = symbol->vector->width - temp;
}
circle = circle->next;
}
string = symbol->vector->strings;
while (string) {
if (rotate_angle == 90) {
temp = string->x;
string->x = symbol->vector->height - string->y;
string->y = temp;
string->rotation = 90;
}
if (rotate_angle == 180) {
string->x = symbol->vector->width - string->x;
string->y = symbol->vector->height - string->y;
string->rotation = 180;
}
if (rotate_angle == 270) {
temp = string->x;
string->x = string->y;
string->y = 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;
}
return;
}
static void vector_reduce_rectangles(struct zint_symbol *symbol) { static void vector_reduce_rectangles(struct zint_symbol *symbol) {
// Looks for vertically aligned rectangles and merges them together // Looks for vertically aligned rectangles and merges them together
struct zint_vector_rect *rect, *target, *prev; struct zint_vector_rect *rect, *target, *prev;
@ -628,6 +740,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
/* Put normal human readable text at the bottom (and centered) */ /* Put normal human readable text at the bottom (and centered) */
// calculate start xoffset to center text // calculate start xoffset to center text
vector_plot_add_string(symbol, symbol->text, main_width / 2.0 + xoffset, default_text_posn, text_height, symbol->width, &last_string); vector_plot_add_string(symbol, symbol->text, main_width / 2.0 + xoffset, default_text_posn, text_height, symbol->width, &last_string);
printf("%s\n", symbol->text);
} }
xoffset -= comp_offset; // Restore xoffset xoffset -= comp_offset; // Restore xoffset
@ -686,6 +799,11 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
vector_scale(symbol, file_type); vector_scale(symbol, file_type);
if (file_type != OUT_EMF_FILE) {
/* Should be possible for EMF but not sure how to rotate text */
vector_rotate(symbol, rotate_angle);
}
switch (file_type) { switch (file_type) {
case OUT_EPS_FILE: case OUT_EPS_FILE:
error_number = ps_plot(symbol); error_number = ps_plot(symbol);

View File

@ -47,6 +47,7 @@ extern "C" {
float x, y, fsize; float x, y, fsize;
float width; /* Suggested string width, may be 0 if none recommended */ float width; /* Suggested string width, may be 0 if none recommended */
int length; int length;
int rotation;
unsigned char *text; unsigned char *text;
struct zint_vector_string *next; /* Pointer to next character */ struct zint_vector_string *next; /* Pointer to next character */
}; };
@ -59,6 +60,7 @@ extern "C" {
struct zint_vector_hexagon { struct zint_vector_hexagon {
float x, y, diameter; float x, y, diameter;
int rotation;
struct zint_vector_hexagon *next; /* Pointer to next hexagon */ struct zint_vector_hexagon *next; /* Pointer to next hexagon */
}; };

View File

@ -425,8 +425,8 @@ PNG, GIF, SVG, EMF and EPS files.
4.8 Rotating the Symbol 4.8 Rotating the Symbol
----------------------- -----------------------
The symbol can be rotated through four orientations using the --rotate= option The symbol can be rotated through four orientations using the --rotate= option
followed by the angle of rotation as shown below. This option is only available followed by the angle of rotation as shown below. This option does not (yet)
with raster image (PNG, BMP, GIF and PCX) output. apply to EMF file output.
--rotate=0 (default) --rotate=0 (default)
--rotate=90 --rotate=90