diff options
Diffstat (limited to 'src/svg')
-rw-r--r-- | src/svg/cdsvg.c | 525 |
1 files changed, 296 insertions, 229 deletions
diff --git a/src/svg/cdsvg.c b/src/svg/cdsvg.c index 184031c..c657825 100644 --- a/src/svg/cdsvg.c +++ b/src/svg/cdsvg.c @@ -19,6 +19,7 @@ #include "lodepng.h" #include "base64.h" + struct _cdCtxCanvas { cdCanvas* canvas; @@ -26,30 +27,26 @@ struct _cdCtxCanvas char bgColor[20]; char fgColor[20]; - char linecap[10]; - char linejoin[10]; - char linestyle[20]; - char poly[256]; - char pattern[30]; - - char font_weight[15]; - char font_style[15]; - char font_decoration[15]; + char* linecap; + char* linejoin; + char linestyle[50]; + char pattern[50]; + + char* font_weight; + char* font_style; + char* font_decoration; char font_family[256]; char font_size[10]; - int backopacity; - int writemode; - int linewidth; + double opacity; int hatchboxsize; - double xmatrix[6]; /* Transformation matrix that includes axis inversion */ - /* private */ int last_fill_mode; - int last_clip_path; - int clip_off_control; + int last_clip_poly; + int last_clip_rect; + int clip_control; int clip_polygon; int transform_control; @@ -57,18 +54,17 @@ struct _cdCtxCanvas FILE* file; }; +static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix); + static void cdkillcanvas(cdCtxCanvas* ctxcanvas) { - while(ctxcanvas->clip_off_control > 0) - { - fprintf(ctxcanvas->file, "</g>\n"); - --ctxcanvas->clip_off_control; - } + if (ctxcanvas->clip_control) + fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */ - if(ctxcanvas->transform_control) - fprintf(ctxcanvas->file, "</g>\n"); + if (ctxcanvas->transform_control) + fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */ - fprintf(ctxcanvas->file, "</g>\n"); + fprintf(ctxcanvas->file, "</g>\n"); /* close global container */ fprintf(ctxcanvas->file, "</svg>\n"); free(ctxcanvas->filename); @@ -78,63 +74,37 @@ static void cdkillcanvas(cdCtxCanvas* ctxcanvas) free(ctxcanvas); } -static void setclip_area(cdCtxCanvas *ctxcanvas) +static int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode) { - cdRect* clip_rect = &ctxcanvas->canvas->clip_rect; - - fprintf(ctxcanvas->file, "<clipPath id=\"clippath%d\">\n", ++ctxcanvas->last_clip_path); - - if (ctxcanvas->canvas->use_matrix) + if (ctxcanvas->clip_control) { - cdPoint poly[4]; - poly[0].x = clip_rect->xmin; poly[0].y = clip_rect->ymin; - poly[1].x = clip_rect->xmin; poly[1].y = clip_rect->ymax; - poly[2].x = clip_rect->xmax; poly[2].y = clip_rect->ymax; - poly[3].x = clip_rect->xmax; poly[3].y = clip_rect->ymin; - - sprintf(ctxcanvas->poly, "%g,%g", (double)poly[0].x, (double)poly[0].y); - sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[1].x, (double)poly[1].y); - sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[2].x, (double)poly[2].y); - sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[3].x, (double)poly[3].y); - - fprintf(ctxcanvas->file, "<polygon points=\"%s\" />\n", ctxcanvas->poly); - } - else - { - double x, y, w, h; - x = (double)clip_rect->xmin; - y = (double)clip_rect->ymin; - w = (double)(clip_rect->xmax - clip_rect->xmin + 1); - h = (double)(clip_rect->ymax - clip_rect->ymin + 1); - - fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" />\n", x, y, w, h); - } + int old_transform_control = ctxcanvas->transform_control; + if (ctxcanvas->transform_control) + { + fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */ + ctxcanvas->transform_control = 0; + } - fprintf(ctxcanvas->file, "</clipPath>\n"); + fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */ + ctxcanvas->clip_control = 0; - fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippath%d)\">\n", ctxcanvas->last_clip_path); - ++ctxcanvas->clip_off_control; -} + if (old_transform_control) + cdtransform(ctxcanvas, ctxcanvas->canvas->matrix); /* reopen transform container */ + } -int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode) -{ switch (clip_mode) { - case CD_CLIPOFF: - if(ctxcanvas->clip_off_control > 0) - { - fprintf(ctxcanvas->file, "</g>\n"); - --ctxcanvas->clip_off_control; - } - break; case CD_CLIPAREA: - setclip_area(ctxcanvas); + /* open clipping container */ + fprintf(ctxcanvas->file, "<g clip-path=\"url(#cliprect%d)\">\n", ctxcanvas->last_clip_rect); + ctxcanvas->clip_control = 1; break; case CD_CLIPPOLYGON: if (ctxcanvas->clip_polygon) { - fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippath%d)\">\n", ctxcanvas->last_clip_path); - ++ctxcanvas->clip_off_control; + /* open clipping container */ + fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippoly%d)\">\n", ctxcanvas->last_clip_poly); + ctxcanvas->clip_control = 1; } break; } @@ -143,14 +113,26 @@ int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode) static void cdfcliparea(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) { + double x, y, w, h; + + ctxcanvas->canvas->clip_rect.xmin = (int)xmin; + ctxcanvas->canvas->clip_rect.ymin = (int)ymin; + ctxcanvas->canvas->clip_rect.xmax = (int)xmax; + ctxcanvas->canvas->clip_rect.ymax = (int)ymax; + + x = xmin; + y = ymin; + w = xmax - xmin + 1; + h = ymax - ymin + 1; + + fprintf(ctxcanvas->file, "<clipPath id=\"cliprect%d\">\n", ++ctxcanvas->last_clip_rect); + + fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" />\n", x, y, w, h); + + fprintf(ctxcanvas->file, "</clipPath>\n"); + if (ctxcanvas->canvas->clip_mode == CD_CLIPAREA) - { - ctxcanvas->canvas->clip_rect.xmin = (int)xmin; - ctxcanvas->canvas->clip_rect.ymin = (int)ymin; - ctxcanvas->canvas->clip_rect.xmax = (int)xmax; - ctxcanvas->canvas->clip_rect.ymax = (int)ymax; cdclip(ctxcanvas, CD_CLIPAREA); - } } static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) @@ -160,39 +142,51 @@ static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix) { - if (matrix) + if (ctxcanvas->transform_control) { - /* Matrix identity */ - ctxcanvas->xmatrix[0] = 1; - ctxcanvas->xmatrix[1] = 0; - ctxcanvas->xmatrix[2] = 0; - ctxcanvas->xmatrix[3] = -1; - ctxcanvas->xmatrix[4] = 0; - ctxcanvas->xmatrix[5] = (ctxcanvas->canvas->h-1); - - if(ctxcanvas->transform_control) + int old_clip_control = ctxcanvas->clip_control; + if (ctxcanvas->clip_control) { - fprintf(ctxcanvas->file, "</g>\n"); - --ctxcanvas->transform_control; + fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */ + ctxcanvas->clip_control = 0; } - cdMatrixMultiply(matrix, ctxcanvas->xmatrix); + fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */ + ctxcanvas->transform_control = 0; - ++ctxcanvas->transform_control; - fprintf(ctxcanvas->file, "<g transform=\"matrix(%g %g %g %g %g %g)\">\n", ctxcanvas->xmatrix[0], ctxcanvas->xmatrix[1], ctxcanvas->xmatrix[2], ctxcanvas->xmatrix[3], ctxcanvas->xmatrix[4], ctxcanvas->xmatrix[5]); + if (old_clip_control) + cdclip(ctxcanvas, ctxcanvas->canvas->clip_mode); /* reopen clipping container */ + } + + if (matrix) + { + double xmatrix[6]; + + /* Matrix identity + invert axis */ + xmatrix[0] = 1; + xmatrix[1] = 0; + xmatrix[2] = 0; + xmatrix[3] = -1; + xmatrix[4] = 0; + xmatrix[5] = (ctxcanvas->canvas->h-1); + + /* compose transform */ + cdMatrixMultiply(matrix, xmatrix); + + /* open transform container */ + fprintf(ctxcanvas->file, "<g transform=\"matrix(%g %g %g %g %g %g)\">\n", xmatrix[0], xmatrix[1], xmatrix[2], xmatrix[3], xmatrix[4], xmatrix[5]); + ctxcanvas->transform_control = 1; ctxcanvas->canvas->invert_yaxis = 0; } else - { ctxcanvas->canvas->invert_yaxis = 1; - } } static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2) { - fprintf(ctxcanvas->file, "<line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - x1, y1, x2, y2, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n", + x1, y1, x2, y2, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); } static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2) @@ -202,8 +196,8 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2) static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) { - fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - xmin, ymin, xmax-xmin, ymax-ymin, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n", + xmin, ymin, xmax-xmin, ymax-ymin, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); } static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) @@ -213,9 +207,8 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) { - fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - xmin, ymin, xmax-xmin, ymax-ymin, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, - (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; stroke:none; opacity:%g\" />\n", + xmin, ymin, xmax-xmin, ymax-ymin, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity); } static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) @@ -230,9 +223,8 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl if((a1 == 0.0) && (a2 == 360.0)) /* an ellipse/circle */ { - fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - xc, yc, w/2, h/2, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); - + fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n", + xc, yc, w/2, h/2, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); return; } @@ -251,8 +243,8 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl if((a2-a1) > 180.0) largeArc = 1; - fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n", + arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); } static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) @@ -267,10 +259,8 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do if((a1 == 0.0) && (a2 == 360.0)) /* an ellipse/circle */ { - fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - xc, yc, w/2, h/2, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, - (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); - + fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:%s; stroke:none; opacity:%g\" />\n", + xc, yc, w/2, h/2, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity); return; } @@ -289,9 +279,8 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do if((a2-a1) > 180.0) largeArc = 1; - fprintf(ctxcanvas->file, "<path d=\"M%g,%g L%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - xc, yc, arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, - (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<path d=\"M%g,%g L%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:none; opacity:%g\" />\n", + xc, yc, arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity); } static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) @@ -319,9 +308,8 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou if((a2-a1) > 180.0) largeArc = 1; - fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, - (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:none; opacity:%g\" />\n", + arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity); } static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) @@ -331,8 +319,8 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text, int len) { - char anchor[10]; - char alignment[20]; + char* anchor; + char* alignment; int i; switch (ctxcanvas->canvas->text_alignment) @@ -340,22 +328,23 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text case CD_NORTH: case CD_NORTH_EAST: case CD_NORTH_WEST: - sprintf(alignment, "%s", "text-before-edge"); + alignment = "text-before-edge"; break; case CD_SOUTH: case CD_SOUTH_EAST: case CD_SOUTH_WEST: - sprintf(alignment, "%s", "text-after-edge"); + alignment = "text-after-edge"; break; case CD_CENTER: case CD_EAST: case CD_WEST: - sprintf(alignment, "%s", "middle"); + alignment = "middle"; break; case CD_BASE_CENTER: case CD_BASE_LEFT: case CD_BASE_RIGHT: - sprintf(alignment, "%s", "baseline"); + default: + alignment = "baseline"; break; } @@ -365,19 +354,20 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text case CD_NORTH_WEST: case CD_SOUTH_WEST: case CD_BASE_LEFT: - sprintf(anchor, "%s", "start"); + anchor = "start"; break; case CD_CENTER: case CD_NORTH: case CD_SOUTH: case CD_BASE_CENTER: - sprintf(anchor, "%s", "middle"); + anchor = "middle"; break; case CD_EAST: case CD_NORTH_EAST: case CD_SOUTH_EAST: case CD_BASE_RIGHT: - sprintf(anchor, "%s", "end"); + default: + anchor = "end"; break; } @@ -392,10 +382,10 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text if (ctxcanvas->canvas->use_matrix) /* Transformation active */ fprintf(ctxcanvas->file, "<text transform=\"matrix(%g %g %g %g %g %g)\" font-family=\"%s\" font-size=\"%s\" font-style=\"%s\" font-weight=\"%s\" text-decoration=\"%s\" text-anchor=\"%s\" dominant-baseline=\"%s\" fill=\"%s\">\n", - text_cos, text_sin, text_sin, -text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor); + text_cos, text_sin, text_sin, -text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor); else fprintf(ctxcanvas->file, "<text transform=\"matrix(%g %g %g %g %g %g)\" font-family=\"%s\" font-size=\"%s\" font-style=\"%s\" font-weight=\"%s\" text-decoration=\"%s\" text-anchor=\"%s\" dominant-baseline=\"%s\" fill=\"%s\">\n", - text_cos, -text_sin, text_sin, text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor); + text_cos, -text_sin, text_sin, text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor); for(i = 0; i < len; i++) fprintf(ctxcanvas->file, "&#x%02X;", (unsigned char)text[i]); @@ -419,46 +409,56 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text, int l cdftext(ctxcanvas, (double)x, (double)y, text, len); } -static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n) +static void write_points(cdCtxCanvas *ctxcanvas, cdfPoint* poly, int n, int close) { - int i, m = 0; - char rule[8]; - - if(mode == CD_BEZIER) - m = 1; + int i; + for(i = 0; i<n; i++) + fprintf(ctxcanvas->file, "%g,%g ", poly[i].x, poly[i].y); + if (close) + fprintf(ctxcanvas->file, "%g,%g ", poly[0].x, poly[0].y); +} - sprintf(ctxcanvas->poly, "%g,%g", poly[m].x, poly[m].y); - for(i = m+1; i<n; i++) - sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, poly[i].x, poly[i].y); +static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n) +{ + char* rule; switch (mode) { - case CD_CLOSED_LINES : - fprintf(ctxcanvas->file, "<polygon style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n", - ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly); + case CD_CLOSED_LINES: + fprintf(ctxcanvas->file, "<polygon style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"", + ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); + write_points(ctxcanvas, poly, n, 1); + fprintf(ctxcanvas->file, "\" />\n"); break; - case CD_OPEN_LINES : - fprintf(ctxcanvas->file, "<polyline style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n", - ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly); + case CD_OPEN_LINES: + fprintf(ctxcanvas->file, "<polyline style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"", + ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); + write_points(ctxcanvas, poly, n, 0); + fprintf(ctxcanvas->file, "\" />\n"); break; - case CD_BEZIER : - fprintf(ctxcanvas->file, "<path d=\"M%g,%g C%s\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - poly[0].x, poly[0].y, ctxcanvas->poly, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + case CD_BEZIER: + fprintf(ctxcanvas->file, "<path d=\"M%g,%g C", poly[0].x, poly[0].y); + write_points(ctxcanvas, poly+1, n-1, 0); + fprintf(ctxcanvas->file, "\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n", + ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity); break; - case CD_FILL : + case CD_FILL: if(ctxcanvas->canvas->fill_mode==CD_EVENODD) - sprintf(rule, "%s", "evenodd"); + rule = "evenodd"; else - sprintf(rule, "%s", "nonzero"); + rule = "nonzero"; - fprintf(ctxcanvas->file, "<polygon style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n", - (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, rule, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", - ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly); + fprintf(ctxcanvas->file, "<polygon style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" points=\"", + (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity); + write_points(ctxcanvas, poly, n, 0); + fprintf(ctxcanvas->file, "\" />\n"); break; case CD_CLIP: - fprintf(ctxcanvas->file, "<clipPath id=\"clippath%d\">\n", ++ctxcanvas->last_clip_path); + fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly); - fprintf(ctxcanvas->file, "<polygon points=\"%s\" />\n", ctxcanvas->poly); + fprintf(ctxcanvas->file, "<polygon points=\""); + write_points(ctxcanvas, poly, n, 0); + fprintf(ctxcanvas->file, "\" />\n"); fprintf(ctxcanvas->file, "</clipPath>\n"); @@ -490,32 +490,27 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n) free(newPoly); } -static int cdbackopacity(cdCtxCanvas *ctxcanvas, int opacity) -{ - ctxcanvas->backopacity = opacity; - return opacity; -} - static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style) { switch (style) { - case CD_CONTINUOUS : /* empty dash */ + case CD_CONTINUOUS: /* empty dash */ + default: sprintf(ctxcanvas->linestyle, "%s", "0"); break; - case CD_DASHED : + case CD_DASHED: sprintf(ctxcanvas->linestyle, "%s", "6,2"); break; - case CD_DOTTED : + case CD_DOTTED: sprintf(ctxcanvas->linestyle, "%s", "2,2"); break; - case CD_DASH_DOT : + case CD_DASH_DOT: sprintf(ctxcanvas->linestyle, "%s", "6,2,2,2"); break; - case CD_DASH_DOT_DOT : + case CD_DASH_DOT_DOT: sprintf(ctxcanvas->linestyle, "%s", "6,2,2,2,2,2"); break; - case CD_CUSTOM : + case CD_CUSTOM: { int i; sprintf(ctxcanvas->linestyle, "%d", ctxcanvas->canvas->line_dashes[0]); @@ -529,34 +524,25 @@ static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style) return style; } -static int cdlinewidth(cdCtxCanvas *ctxcanvas, int width) -{ - ctxcanvas->linewidth = width; - - return width; -} - static int cdlinecap(cdCtxCanvas *ctxcanvas, int cap) { if(cap == CD_CAPROUND) - sprintf(ctxcanvas->linecap, "%s", "round"); + ctxcanvas->linecap = "round"; else if(cap == CD_CAPSQUARE) - sprintf(ctxcanvas->linecap, "%s", "square"); + ctxcanvas->linecap = "square"; else /* CD_CAPFLAT */ - sprintf(ctxcanvas->linecap, "%s", "butt"); - + ctxcanvas->linecap = "butt"; return cap; } static int cdlinejoin(cdCtxCanvas *ctxcanvas, int join) { if(join == CD_ROUND) - sprintf(ctxcanvas->linejoin, "%s", "round"); + ctxcanvas->linejoin = "round"; else if(join == CD_BEVEL) - sprintf(ctxcanvas->linejoin, "%s", "bevel"); + ctxcanvas->linejoin = "bevel"; else /* CD_MITER */ - sprintf(ctxcanvas->linejoin, "%s", "miter"); - + ctxcanvas->linejoin = "miter"; return join; } @@ -565,39 +551,44 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style) int hsize = ctxcanvas->hatchboxsize - 1; int hhalf = hsize / 2; - ctxcanvas->canvas->interior_style = CD_HATCH; sprintf(ctxcanvas->pattern, "url(#pattern%d)", ++ctxcanvas->last_fill_mode); fprintf(ctxcanvas->file, "<pattern id=\"pattern%d\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"%d\" height=\"%d\">\n", ctxcanvas->last_fill_mode, hsize, hsize); + if (ctxcanvas->canvas->back_opacity==CD_OPAQUE) + { + fprintf(ctxcanvas->file, "<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" style=\"fill:%s; stroke:none; opacity:%g\" />\n", + hsize, hsize, ctxcanvas->bgColor, ctxcanvas->opacity); + } + switch(style) { case CD_HORIZONTAL: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - 0, hhalf, hsize, hhalf, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + 0, hhalf, hsize, hhalf, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; case CD_VERTICAL: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - hhalf, 0, hhalf, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + hhalf, 0, hhalf, hsize, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; case CD_BDIAGONAL: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - 0, hsize, hsize, 0, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + 0, hsize, hsize, 0, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; case CD_FDIAGONAL: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - 0, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + 0, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; case CD_CROSS: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - hsize, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - 0, hhalf, hsize, hhalf, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + hsize, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + 0, hhalf, hsize, hhalf, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; case CD_DIAGCROSS: - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - 0, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); - fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n", - hsize, 0, 0, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + 0, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); + fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n", + hsize, 0, 0, hsize, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->opacity); break; } @@ -624,8 +615,8 @@ static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int ( sprintf(color, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b); - fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; opacity:%d\" />\n", - (double)i, (double)j, 1.0, 1.0, color, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; opacity:%g\" />\n", + (double)i, (double)j, 1.0, 1.0, color, ctxcanvas->opacity); } } @@ -642,7 +633,6 @@ static int long2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, uns static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *pattern) { - ctxcanvas->canvas->interior_style = CD_PATTERN; make_pattern(ctxcanvas, n, m, (void*)pattern, long2rgb); } @@ -667,40 +657,48 @@ static int uchar2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, un static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple) { - ctxcanvas->canvas->interior_style = CD_STIPPLE; make_pattern(ctxcanvas, n, m, (void*)stipple, uchar2rgb); } static int cdfont(cdCtxCanvas *ctxcanvas, const char* type_face, int style, int size) { /* Define type_face and size */ - if(type_face != NULL) + if (type_face != NULL) sprintf(ctxcanvas->font_family, "%s", type_face); - if(size > 0) + if (size > 0) sprintf(ctxcanvas->font_size, "%dpt", size); else sprintf(ctxcanvas->font_size, "%dpx", (-1)*size); - if(style != -1) + if (style != -1) { - /* Default: CD_PLAIN */ - sprintf(ctxcanvas->font_weight, "%s", "normal"); - sprintf(ctxcanvas->font_style, "%s", "normal"); - sprintf(ctxcanvas->font_decoration, "%s", "none"); - /* Define styles and decorations */ if (style & CD_BOLD) - sprintf(ctxcanvas->font_weight, "%s", "bold"); + ctxcanvas->font_weight = "bold"; + else + ctxcanvas->font_weight = "normal"; if (style & CD_ITALIC) - sprintf(ctxcanvas->font_style, "%s", "italic"); + ctxcanvas->font_style = "italic"; + else + ctxcanvas->font_style = "normal"; - if (style & CD_STRIKEOUT) - sprintf(ctxcanvas->font_decoration, "%s", "line-through"); + if (style & CD_STRIKEOUT || style & CD_UNDERLINE) + { + if (style & CD_STRIKEOUT && style & CD_UNDERLINE) + ctxcanvas->font_decoration = "line-through underline"; + else + { + if (style & CD_STRIKEOUT) + ctxcanvas->font_decoration = "line-through"; - if (style & CD_UNDERLINE) - sprintf(ctxcanvas->font_decoration, "%s", "underline"); + if (style & CD_UNDERLINE) + ctxcanvas->font_decoration = "underline"; + } + } + else + ctxcanvas->font_decoration = "none"; } return 1; @@ -711,7 +709,6 @@ static long cdbackground(cdCtxCanvas *ctxcanvas, long int color) unsigned char r, g, b; cdDecodeColor(color, &r, &g, &b); sprintf(ctxcanvas->bgColor, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b); - return color; } @@ -720,7 +717,6 @@ static long cdforeground(cdCtxCanvas *ctxcanvas, long int color) unsigned char r, g, b; cdDecodeColor(color, &r, &g, &b); sprintf(ctxcanvas->fgColor, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b); - return color; } @@ -762,10 +758,10 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi if (ctxcanvas->canvas->use_matrix) /* Transformation active */ fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, -1, x, y+h, w, h, rgb_target); + 1, 0, 0, -1, x, y+h, w, h, rgb_target); else fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, 1, x, y-h, w, h, rgb_target); + 1, 0, 0, 1, x, y-h, w, h, rgb_target); free(rgb_data); free(rgb_buffer); @@ -811,10 +807,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns if (ctxcanvas->canvas->use_matrix) /* Transformation active */ fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, -1, x, y+h, w, h, rgb_target); + 1, 0, 0, -1, x, y+h, w, h, rgb_target); else fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, 1, x, y-h, w, h, rgb_target); + 1, 0, 0, 1, x, y-h, w, h, rgb_target); free(rgb_data); free(rgb_buffer); @@ -862,10 +858,10 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi if (ctxcanvas->canvas->use_matrix) /* Transformation active */ fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, -1, x, y+h, w, h, rgb_target); + 1, 0, 0, -1, x, y+h, w, h, rgb_target); else fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n", - 1, 0, 0, 1, x, y-h, w, h, rgb_target); + 1, 0, 0, 1, x, y-h, w, h, rgb_target); free(rgb_data); free(rgb_buffer); @@ -878,8 +874,8 @@ static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color) unsigned char r, g, b; cdDecodeColor(color, &r, &g, &b); - fprintf(ctxcanvas->file, "<circle cx=\"%d\" cy=\"%d\" r=\"0.1\" style=\"fill:rgb(%d,%d,%d); stroke:rgb(%d,%d,%d); stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n", - x, y, r, g, b, r, g, b, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity); + fprintf(ctxcanvas->file, "<circle cx=\"%d\" cy=\"%d\" r=\"0.1\" style=\"fill:rgb(%d,%d,%d); stroke:none; opacity:%g\" />\n", + x, y, r, g, b, ctxcanvas->opacity); } static void cddeactivate (cdCtxCanvas* ctxcanvas) @@ -892,6 +888,74 @@ static void cdflush (cdCtxCanvas* ctxcanvas) fflush(ctxcanvas->file); } +static void set_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + int hatchboxsize; + + if (data == NULL) + { + ctxcanvas->hatchboxsize = 8; + return; + } + + sscanf(data, "%d", &hatchboxsize); + ctxcanvas->hatchboxsize = hatchboxsize; +} + +static char* get_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas) +{ + static char size[10]; + sprintf(size, "%d", ctxcanvas->hatchboxsize); + return size; +} + +static cdAttribute hatchboxsize_attrib = +{ + "HATCHBOXSIZE", + set_hatchboxsize_attrib, + get_hatchboxsize_attrib +}; + +static void set_opacity_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + { + int opacity = 255; + sscanf(data, "%d", &opacity); + if (opacity < 0) ctxcanvas->opacity = 0.0; + else if (opacity > 255) ctxcanvas->opacity = 1.0; + else ctxcanvas->opacity = (double)opacity/255.0; + } + else + ctxcanvas->opacity = 1.0; +} + +static char* get_opacity_attrib(cdCtxCanvas *ctxcanvas) +{ + static char data[50]; + sprintf(data, "%d", ctxcanvas->opacity); + return data; +} + +static cdAttribute opacity_attrib = +{ + "OPACITY", + set_opacity_attrib, + get_opacity_attrib +}; + +static void set_cmd_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + fprintf(ctxcanvas->file, data); +} + +static cdAttribute cmd_attrib = +{ + "CMD", + set_cmd_attrib, + NULL +}; + static void cdcreatecanvas(cdCanvas *canvas, void *data) { char filename[10240] = ""; @@ -937,17 +1001,22 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data) canvas->ctxcanvas = ctxcanvas; ctxcanvas->last_fill_mode = -1; - ctxcanvas->last_clip_path = -1; + ctxcanvas->last_clip_poly = -1; + ctxcanvas->last_clip_rect = -1; - ctxcanvas->clip_off_control = 0; + ctxcanvas->clip_control = 0; ctxcanvas->transform_control = 0; ctxcanvas->clip_polygon = 0; ctxcanvas->hatchboxsize = 8; + ctxcanvas->opacity = 1.0; + + cdRegisterAttribute(canvas, &cmd_attrib); + cdRegisterAttribute(canvas, &hatchboxsize_attrib); fprintf(ctxcanvas->file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(ctxcanvas->file, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%dpt\" height=\"%dpt\" viewBox=\"0 0 %d %d\" version=\"1.1\">\n", canvas->w, canvas->h, canvas->w, canvas->h); - fprintf(ctxcanvas->file, "<g>\n"); + fprintf(ctxcanvas->file, "<g>\n"); /* open global container */ } static void cdinittable(cdCanvas* canvas) @@ -979,9 +1048,7 @@ static void cdinittable(cdCanvas* canvas) canvas->cxFText = cdftext; canvas->cxFClipArea = cdfcliparea; - canvas->cxBackOpacity = cdbackopacity; canvas->cxLineStyle = cdlinestyle; - canvas->cxLineWidth = cdlinewidth; canvas->cxLineCap = cdlinecap; canvas->cxLineJoin = cdlinejoin; @@ -996,7 +1063,7 @@ static void cdinittable(cdCanvas* canvas) canvas->cxFlush = cdflush; canvas->cxDeactivate = cddeactivate; - canvas->cxKillCanvas = (void (*)(cdCtxCanvas*))cdkillcanvas; + canvas->cxKillCanvas = cdkillcanvas; } static cdContext cdSVGContext = |