diff --git a/qrenc.c b/qrenc.c index 78f1c120..52529fab 100644 --- a/qrenc.c +++ b/qrenc.c @@ -189,7 +189,7 @@ static int color_set(unsigned char color[4], const char *value) { int len = strlen(value); int i, count; - unsigned int col[3]; + unsigned int col[4]; if(len == 6) { count = sscanf(value, "%02x%02x%02x%n", &col[0], &col[1], &col[2], &len); if(count < 3 || len != 6) { @@ -494,24 +494,17 @@ static int writeEPS(const QRcode *qrcode, const char *outfile) return 0; } -static void writeSVG_writeRect(FILE *fp, int x, int y, int width, const char* col, float opacity) +static void writeSVG_writeRect(FILE *fp, int x, int y, int width) { - if(fg_color[3] != 255) { - fprintf(fp, "\t\t\t\n", - x, y, width, col, opacity ); - } else { - fprintf(fp, "\t\t\t\n", - x, y, width, col ); - } + fprintf(fp, "\t\t\t\n", + x, y, width); } static int writeSVG(const QRcode *qrcode, const char *outfile) { FILE *fp; unsigned char *row, *p; - int x, y, x0, pen; + int x, y, x0, x1, pen, abs; int symwidth, realwidth; float scale; char fg[7], bg[7]; @@ -547,25 +540,69 @@ static int writeSVG(const QRcode *qrcode, const char *outfile) QRcode_APIVersionString() ); /* SVG code start */ - fprintf( fp, "\n", realwidth / scale, realwidth / scale, symwidth, symwidth - ); + ); + } else { + fprintf( fp, "\n", + symwidth, symwidth); + } + + /* SVG CSS for styling */ + fputs( "\t\n", fp ); /* Make named group */ fputs( "\t\n", fp ); /* Make solid background */ - if(bg_color[3] != 255) { - fprintf(fp, "\t\t\n", symwidth, symwidth, bg, bg_opacity); - } else { - fprintf(fp, "\t\t\n", symwidth, symwidth, bg); - } + fprintf(fp, "\t\t\n", + symwidth, symwidth); /* Create new viewbox for QR data */ fputs( "\t\t\n", fp); + /* If in RLE mode, start the path. We will draw it margin-less but translate it by the margin width. + * Note that the y translation has an additional .5 because the path is stroked, so + * it must be _centered_ in its coordinate. Horizontally this is not needed because + * of the butt cap used by default. */ + if (rle) + fprintf(fp, "\t\t\tdata; for(y=0; ywidth; y++) { @@ -575,31 +612,44 @@ static int writeSVG(const QRcode *qrcode, const char *outfile) /* no RLE */ for(x=0; xwidth; x++) { if(*(row+x)&0x1) { - writeSVG_writeRect(fp, margin + x, - margin + y, 1, - fg, fg_opacity); + writeSVG_writeRect(fp, margin + x, margin + y, 1); } } } else { /* simple RLE */ pen = 0; x0 = 0; + x1 = 0; for(x=0; xwidth; x++) { if( !pen ) { pen = *(row+x)&0x1; x0 = x; } else { if(!(*(row+x)&0x1)) { - writeSVG_writeRect(fp, x0 + margin, y + margin, x-x0, fg, fg_opacity); + /* motion is initially absolute */ + abs = (x1 == 0); + fprintf(fp, "%c%d,%dh%d", abs ? 'M' : 'm', + (x0 - x1), abs ? y : 0, x - x0); + x1 = x; pen = 0; } } } if( pen ) { - writeSVG_writeRect(fp, x0 + margin, y + margin, qrcode->width - x0, fg, fg_opacity); + abs = (x1 == 0); + fprintf(fp, "%c%d,%dh%d", abs ? 'M' : 'm', + (x0 - x1), abs ? y : 0, qrcode->width - x0); + } + if (y < qrcode->width - 1) { + fprintf( fp, "\n\t\t\t\t" ); } } } + + /* Close the path */ + if (rle) + fputs( "\"/>\n", fp ); + /* Close QR data viewbox */ fputs( "\t\t\n", fp );