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;
radius = hex->diameter / 2.0;
ay = hex->y + (1.0 * radius);
by = hex->y + (0.5 * radius);
cy = hex->y - (0.5 * radius);
dy = hex->y - (1.0 * radius);
ey = hex->y - (0.5 * radius);
fy = hex->y + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
if ((hex->rotation == 0) || (hex->rotation == 180)) {
ay = hex->y + (1.0 * radius);
by = hex->y + (0.5 * radius);
cy = hex->y - (0.5 * radius);
dy = hex->y - (1.0 * radius);
ey = hex->y - (0.5 * radius);
fy = hex->y + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
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.y = ay;

View File

@ -2,7 +2,7 @@
/*
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
modification, are permitted provided that the following conditions
@ -269,18 +269,33 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
hex = symbol->vector->hexagons;
while (hex) {
radius = hex->diameter / 2.0;
ay = (symbol->vector->height - hex->y) + (1.0 * radius);
by = (symbol->vector->height - hex->y) + (0.5 * radius);
cy = (symbol->vector->height - hex->y) - (0.5 * radius);
dy = (symbol->vector->height - hex->y) - (1.0 * radius);
ey = (symbol->vector->height - hex->y) - (0.5 * radius);
fy = (symbol->vector->height - hex->y) + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
if ((hex->rotation == 0) || (hex->rotation == 180)) {
ay = (symbol->vector->height - hex->y) + (1.0 * radius);
by = (symbol->vector->height - hex->y) + (0.5 * radius);
cy = (symbol->vector->height - hex->y) - (0.5 * radius);
dy = (symbol->vector->height - hex->y) - (1.0 * radius);
ey = (symbol->vector->height - hex->y) - (0.5 * radius);
fy = (symbol->vector->height - hex->y) + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
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);
hex = hex->next;
}
@ -312,15 +327,23 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
// Text
string = symbol->vector->strings;
while (string) {
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
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, " (%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, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", string->text);
if (string->rotation != 0) {
fprintf(feps, "grestore\n");
}
fprintf(feps, "setmatrix\n");
string = string->next;
}

View File

@ -224,18 +224,33 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
hex = symbol->vector->hexagons;
while (hex) {
radius = hex->diameter / 2.0;
ay = hex->y + (1.0 * radius);
by = hex->y + (0.5 * radius);
cy = hex->y - (0.5 * radius);
dy = hex->y - (1.0 * radius);
ey = hex->y - (0.5 * radius);
fy = hex->y + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
ex = hex->x - (0.86 * radius);
fx = hex->x - (0.86 * radius);
if ((hex->rotation == 0) || (hex->rotation == 180)) {
ay = hex->y + (1.0 * radius);
by = hex->y + (0.5 * radius);
cy = hex->y - (0.5 * radius);
dy = hex->y - (1.0 * radius);
ey = hex->y - (0.5 * radius);
fy = hex->y + (0.5 * radius);
ax = hex->x;
bx = hex->x + (0.86 * radius);
cx = hex->x + (0.86 * radius);
dx = hex->x;
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);
if (fg_alpha != 0xff) {
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) {
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");
make_html_friendly(string->text, 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->y = y;
hexagon->diameter = (diameter * 5.0) / 4.0; // Ugly kludge for legacy support
hexagon->rotation = 0;
return hexagon;
}
@ -132,6 +133,7 @@ static int vector_plot_add_string(struct zint_symbol *symbol,
string->width = width;
string->fsize = fsize;
string->length = ustrlen(text);
string->rotation = 0;
string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1));
ustrcpy(string->text, text);
@ -241,6 +243,116 @@ static void vector_scale(struct zint_symbol *symbol, int file_type) {
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) {
// Looks for vertically aligned rectangles and merges them together
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) */
// 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);
printf("%s\n", symbol->text);
}
xoffset -= comp_offset; // Restore xoffset
@ -685,6 +798,11 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
vector_reduce_rectangles(symbol);
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) {
case OUT_EPS_FILE:

View File

@ -47,6 +47,7 @@ extern "C" {
float x, y, fsize;
float width; /* Suggested string width, may be 0 if none recommended */
int length;
int rotation;
unsigned char *text;
struct zint_vector_string *next; /* Pointer to next character */
};
@ -59,6 +60,7 @@ extern "C" {
struct zint_vector_hexagon {
float x, y, diameter;
int rotation;
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
-----------------------
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
with raster image (PNG, BMP, GIF and PCX) output.
followed by the angle of rotation as shown below. This option does not (yet)
apply to EMF file output.
--rotate=0 (default)
--rotate=90