diff --git a/backend/emf.c b/backend/emf.c index dece436c..5d4c5bc5 100644 --- a/backend/emf.c +++ b/backend/emf.c @@ -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; diff --git a/backend/ps.c b/backend/ps.c index 3b78704b..390c306c 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009-2018 Robin Stuart + Copyright (C) 2009-2020 Robin Stuart 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; } diff --git a/backend/svg.c b/backend/svg.c index 27355725..498f7222 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -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, " 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); diff --git a/backend/vector.c b/backend/vector.c index 69267d88..3f0d7e79 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -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: diff --git a/backend/zint.h b/backend/zint.h index 0d427ccb..b299a91c 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -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 */ }; diff --git a/docs/manual.txt b/docs/manual.txt index 68d150f7..d366563c 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -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