diff --git a/backend/Makefile b/backend/Makefile index 4ce322d6..0826a519 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -19,8 +19,8 @@ includedir := $(prefix)/include libdir := $(prefix)/lib DESTDIR := -COMMON:= common.c png.c library.c ps.c large.c reedsol.c gs1.c -COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o +COMMON:= common.c png.c library.c ps.c large.c reedsol.c gs1.c svg.c +COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o ONEDIM:= code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o POSTAL:= postal.c auspost.c imail.c @@ -36,7 +36,7 @@ DEFINES:= LIBS+= -lqrencode endif -libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c aztec.c blockf.c micqr.c gs1.c +libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c aztec.c blockf.c micqr.c gs1.c svg.c $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(ONEDIM) $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(POSTAL) $(CC) -Wall -fPIC $(DEFINES) $(CFLAGS) $(ZINT_VERSION) -c $(TWODIM) diff --git a/backend/common.c b/backend/common.c index 7edaa571..35c6ac1d 100644 --- a/backend/common.c +++ b/backend/common.c @@ -149,3 +149,18 @@ int is_stackable(int symbology) { return 0; } +int roundup(float input) +{ + float remainder; + int integer_part; + + integer_part = (int)input; + remainder = input - integer_part; + + if(remainder > 0.1) { + integer_part++; + } + + return integer_part; +} + diff --git a/backend/common.h b/backend/common.h index 8a715c7d..6fb8c3b6 100644 --- a/backend/common.h +++ b/backend/common.h @@ -38,3 +38,4 @@ void lookup(char set_string[], char *table[], char data, char dest[]); int posn(char set_string[], char data); void expand(struct zint_symbol *symbol, char data[]); int is_stackable(int symbology); +int roundup(float input); diff --git a/backend/library.c b/backend/library.c index 7380639d..eda7733d 100644 --- a/backend/library.c +++ b/backend/library.c @@ -124,6 +124,7 @@ int png_handle(struct zint_symbol *symbol, int rotate_angle); #endif extern int ps_plot(struct zint_symbol *symbol); +extern int svg_plot(struct zint_symbol *symbol); void error_tag(char error_string[], int error_number) { @@ -515,9 +516,13 @@ int ZBarcode_Print(struct zint_symbol *symbol) if(!(strcmp(output, "EPS"))) { error_number = ps_plot(symbol); } else { - strcpy(symbol->errtxt, "Unknown output format [Z20]"); - error_tag(symbol->errtxt, ERROR_INVALID_OPTION); - return ERROR_INVALID_OPTION; + if(!(strcmp(output, "SVG"))) { + error_number = svg_plot(symbol); + } else { + strcpy(symbol->errtxt, "Unknown output format [Z20]"); + error_tag(symbol->errtxt, ERROR_INVALID_OPTION); + return ERROR_INVALID_OPTION; + } } #ifndef NO_PNG } diff --git a/backend/svg.c b/backend/svg.c new file mode 100644 index 00000000..d835984f --- /dev/null +++ b/backend/svg.c @@ -0,0 +1,711 @@ +/* svg.c - Scalable Vector Graphics */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include "common.h" + +#define SSET "0123456789ABCDEF" + +int svg_plot(struct zint_symbol *symbol) +{ + int i, block_width, latch, r, this_row; + float textpos, large_bar_height, preset_height, row_height, row_posn; + FILE *fsvg; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone, main_width; + char textpart[10], addon[6]; + int large_bar_count, comp_offset; + float addon_text_posn; + float scaler = symbol->scale; + + row_height=0; + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + + if((symbol->output_options & BARCODE_STDOUT) != 0) { + fsvg = stdout; + } else { + fsvg = fopen(symbol->outfile, "w"); + } + if(fsvg == NULL) { + strcpy(symbol->errtxt, "Could not open output file"); + return ERROR_FILE_ACCESS; + } + + /* sort out colour options */ + to_upper((unsigned char*)symbol->fgcolour); + to_upper((unsigned char*)symbol->bgcolour); + + if(strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + if(strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + red_ink = fgred / 256.0; + green_ink = fggrn / 256.0; + blue_ink = fgblu / 256.0; + red_paper = bgred / 256.0; + green_paper = bggrn / 256.0; + blue_paper = bgblu / 256.0; + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for(i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if(symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while(symbol->encoded_data[symbol->rows - 1][comp_offset] != '1') { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if (((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) { + switch(strlen(symbol->text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + for(i = 0; i < strlen(symbol->text); i++) { + if (latch == 1) { + addon[r] = symbol->text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + addon[r] = '\0'; + + if(strcmp(symbol->text, "")) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + /* Start writing the header */ + fprintf(fsvg, "\n"); + fprintf(fsvg, "\n"); + if(symbol->symbology != BARCODE_MAXICODE) { + fprintf(fsvg, "width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); + } else { + fprintf(fsvg, "\n"); + if(strlen(symbol->text) != 0) { + fprintf(fsvg, " %s\n", symbol->text); + } else { + fprintf(fsvg, " Zint Generated Symbol\n"); + } + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n \n"); + + if(symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode uses hexagons */ + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + + + textoffset = 0.0; + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(fsvg, " \n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + } + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler); + for(r = 0; r < symbol->rows; r++) { + for(i = 0; i < symbol->width; i++) { + if(symbol->encoded_data[r][i] == '1') { + /* Dump a hexagon */ + my = r * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + if(r % 2 == 1) { + mx = (2.46 * i) + 1.23 + 1.23; + } else { + mx = (2.46 * i) + 1.23; + } + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + fprintf(fsvg, " \n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); + } + } + } + } + + if(symbol->symbology != BARCODE_MAXICODE) { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + int addon_latch = 0; + + for(r = 0; r < symbol->rows; r++) { + this_row = r; + if(symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for(i = 0; i < r; i++) { + if(symbol->row_height[i] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[i]; + } + } + row_posn += yoffset; + + i = 0; + if(symbol->encoded_data[this_row][0] == '1') { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (symbol->encoded_data[this_row][i + block_width] == symbol->encoded_data[this_row][i]); + if((addon_latch == 0) && (r == 0) && (i > main_width)) { + addon_text_posn = row_posn + row_height - 8.0; + addon_latch = 1; + } + if(latch == 1) { + /* a bar */ + if(addon_latch == 0) { + fprintf(fsvg, " \n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler); + } else { + fprintf(fsvg, " \n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); + } + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + /* That's done the actual data area, everything else is human-friendly */ + + xoffset += comp_offset; + row_posn = (yoffset + large_bar_height) * scaler; + + if (((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch(strlen(symbol->text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i]; + } + /* textpart[4] = '\0'; + fprintf(fsvg, "TE\n"); + fprintf(fsvg, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 17; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.50 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i + 4]; + } + textpart[4] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 50; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 10; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + case 5: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 23; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + } */ + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + /*fprintf(fsvg, "TE\n"); + fprintf(fsvg, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = -7; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.50 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.50 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 7]; + } + textpart[6] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 71; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 10; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + case 5: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 23; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + } + break; */ + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (symbol->encoded_data[symbol->rows - 1][i + block_width] == symbol->encoded_data[symbol->rows - 1][i]); + if(latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (symbol->encoded_data[symbol->rows - 1][i + block_width] == symbol->encoded_data[symbol->rows - 1][i]); + if(latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + /*fprintf(fsvg, "TE\n"); + fprintf(fsvg, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[5] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 27; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 6]; + } + textpart[6] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 68; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textpart[0] = symbol->text[11]; + textpart[1] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 100; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 10; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + case 5: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 23; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + } */ + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + /* fprintf(fsvg, "TE\n"); + fprintf(fsvg, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textpart[0] = symbol->text[7]; + textpart[1] = '\0'; + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 55; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 0.5 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", textpart); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", textpart); + fprintf(fsvg, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 10; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + case 5: + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = symbol->width + xoffset - 23; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(fsvg, " (%s) stringwidth\n", addon); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", addon); + fprintf(fsvg, "setmatrix\n"); + break; + } */ + + } + + xoffset -= comp_offset; + + switch(symbol->symbology) { + case BARCODE_CODABLOCKF: + case BARCODE_HIBC_BLOCKF: + fprintf(fsvg, " \n", xoffset * scaler, 0.0, symbol->width * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", xoffset * scaler, (symbol->height + symbol->border_width) * scaler, symbol->width * scaler, symbol->border_width * scaler); + if(symbol->rows > 1) { + /* row binding */ + for(r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", (xoffset + 11) * scaler, ((r * row_height) + yoffset - 1) * scaler, (symbol->width - 24) * scaler, 2.0 * scaler); + } + } + break; + case BARCODE_MAXICODE: + /* Do nothing! (It's already been done) */ + break; + default: + if((symbol->output_options & BARCODE_BIND) != 0) { + if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + for(r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); + } + } + } + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(fsvg, " \n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + } + break; + } + + /* Put the human readable text at the bottom */ + /* if((textdone == 0) && (strlen(symbol->text) != 0)) { + fprintf(fsvg, "TE\n"); + fprintf(fsvg, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(fsvg, "matrix currentmatrix\n"); + fprintf(fsvg, "/Helvetica findfont\n"); + fprintf(fsvg, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = symbol->width / 2.0; + fprintf(fsvg, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, 1.67 * scaler); + fprintf(fsvg, " (%s) stringwidth\n", symbol->text); + fprintf(fsvg, "pop\n"); + fprintf(fsvg, "-2 div 0 rmoveto\n"); + fprintf(fsvg, " (%s) show\n", symbol->text); + fprintf(fsvg, "setmatrix\n"); + } */ + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n"); + + fclose(fsvg); + + return error_number; +} +