summaryrefslogtreecommitdiff
path: root/cd/src/svg/cdsvg.c
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/svg/cdsvg.c')
-rw-r--r--cd/src/svg/cdsvg.c920
1 files changed, 623 insertions, 297 deletions
diff --git a/cd/src/svg/cdsvg.c b/cd/src/svg/cdsvg.c
index 184031c..0510919 100644
--- a/cd/src/svg/cdsvg.c
+++ b/cd/src/svg/cdsvg.c
@@ -19,37 +19,33 @@
#include "lodepng.h"
#include "base64.h"
+
struct _cdCtxCanvas
{
cdCanvas* canvas;
- char* filename;
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,100 +53,85 @@ 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);
fclose(ctxcanvas->file);
memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
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)
- {
- 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
+ if (ctxcanvas->clip_control)
{
- 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)\" clip-rule:%s >\n", ctxcanvas->last_clip_poly, (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero");
+ ctxcanvas->clip_control = 1;
}
break;
}
+
return 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 +141,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;
+
+ if (old_clip_control)
+ cdclip(ctxcanvas, ctxcanvas->canvas->clip_mode); /* reopen clipping container */
+ }
- ++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 (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 +195,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 +206,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)
@@ -223,36 +215,51 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
}
+static void sCalcArc(cdCanvas* canvas, double xc, double yc, double w, double h, double a1, double a2, double *arcStartX, double *arcStartY, double *arcEndX, double *arcEndY, int *largeArc, int swap)
+{
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, arcStartX, arcStartY, arcEndX, arcEndY);
+
+ if (canvas->invert_yaxis)
+ {
+ /* fix axis orientation */
+ *arcStartY = 2*yc - *arcStartY;
+ *arcEndY = 2*yc - *arcEndY;
+ }
+ else
+ {
+ /* it is clock-wise when axis NOT inverted */
+ if (swap)
+ {
+ _cdSwapDouble(*arcStartX, *arcEndX);
+ _cdSwapDouble(*arcStartY, *arcEndY);
+ }
+ }
+
+ if (fabs(a2-a1) > 180.0)
+ *largeArc = 1;
+ else
+ *largeArc = 0;
+}
+
static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
+ int largeArc;
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;
}
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
-
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
-
- if((a2-a1) > 180.0)
- largeArc = 1;
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &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)
@@ -263,35 +270,19 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
+ int largeArc;
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;
}
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
-
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
-
- if((a2-a1) > 180.0)
- largeArc = 1;
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &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)
@@ -302,26 +293,12 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
-
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
+ int largeArc;
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 1);
- 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 +308,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 +317,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 +343,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 +371,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 +398,178 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text, int l
cdftext(ctxcanvas, (double)x, (double)y, text, len);
}
+static void sWritePointsF(cdCtxCanvas *ctxcanvas, cdfPoint* poly, int n, int close)
+{
+ 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);
+}
+
+static void sWritePoints(cdCtxCanvas *ctxcanvas, cdPoint* poly, int n, int close)
+{
+ int i;
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d,%d ", poly[i].x, poly[i].y);
+ if (close)
+ fprintf(ctxcanvas->file, "%d,%d ", poly[0].x, poly[0].y);
+}
+
static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
- int i, m = 0;
- char rule[8];
+ char* rule;
- if(mode == CD_BEZIER)
- m = 1;
+ if (mode == CD_PATH)
+ {
+ int i, p, clip_path = 0, end_path, current_set;
- 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);
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ {
+ clip_path = 1;
+ break;
+ }
+ }
+
+ if (clip_path)
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
+
+ /* starts a new path */
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ if (!end_path)
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "M %g %g ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "L %g %g ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+ double arcStartX, arcStartY, arcEndX, arcEndY;
+ int largeArc, sweep = 0;
+
+ if (i+3 > n) return;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 0);
+
+ if (ctxcanvas->canvas->invert_yaxis && (a2-a1)<0) /* can be clockwise */
+ sweep = 1;
+
+ if (current_set)
+ fprintf(ctxcanvas->file, "L %g %g A %g %g 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+ else
+ fprintf(ctxcanvas->file, "M %g %g A %g %g 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+
+ current_set = 1;
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "C %g %g %g %g %g %g ", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "Z ");
+ break;
+ case CD_PATH_FILL:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_STROKE:
+ 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);
+ end_path = 1;
+ break;
+ case CD_PATH_FILLSTROKE:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_CLIP:
+ fprintf(ctxcanvas->file, "\" />\n");
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+ ctxcanvas->clip_polygon = 1;
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ end_path = 1;
+ break;
+ }
+ }
+ return;
+ }
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);
+ sWritePointsF(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);
+ sWritePointsF(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);
+ sWritePointsF(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);
+ sWritePointsF(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=\"");
+ sWritePointsF(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
fprintf(ctxcanvas->file, "</clipPath>\n");
@@ -474,48 +585,193 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
- int i;
- cdfPoint* newPoly = NULL;
-
- newPoly = (cdfPoint*)malloc(sizeof(cdfPoint)*(n+1));
+ char* rule;
- for(i = 0; i < n; i++)
+ if (mode == CD_PATH)
{
- newPoly[i].x = (double)poly[i].x;
- newPoly[i].y = (double)poly[i].y;
+ int i, p, clip_path = 0, end_path, current_set;
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ {
+ clip_path = 1;
+ break;
+ }
+ }
+
+ if (clip_path)
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
+
+ /* starts a new path */
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ if (!end_path)
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "M %d %d ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "L %d %d ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+ double arcStartX, arcStartY, arcEndX, arcEndY;
+ int largeArc, sweep = 0;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 0);
+
+ if (ctxcanvas->canvas->invert_yaxis && (a2-a1)<0) /* can be clockwise */
+ sweep = 1;
+
+ if (current_set)
+ fprintf(ctxcanvas->file, "L %g %g A %d %d 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+ else
+ fprintf(ctxcanvas->file, "M %g %g A %d %d 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+
+ current_set = 1;
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "C %d %d %d %d %d %d ", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "Z ");
+ break;
+ case CD_PATH_FILL:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_STROKE:
+ 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);
+ end_path = 1;
+ break;
+ case CD_PATH_FILLSTROKE:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_CLIP:
+ fprintf(ctxcanvas->file, "\" />\n");
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+ ctxcanvas->clip_polygon = 1;
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ end_path = 1;
+ break;
+ }
+ }
+ return;
}
- cdfpoly(ctxcanvas, mode, (cdfPoint*)newPoly, n);
+ 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:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePoints(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:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+ break;
+ case CD_BEZIER:
+ fprintf(ctxcanvas->file, "<path d=\"M%d,%d C", poly[0].x, poly[0].y);
+ sWritePoints(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:
+ if(ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ rule = "evenodd";
+ else
+ rule = "nonzero";
- free(newPoly);
-}
+ 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);
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+ break;
+ case CD_CLIP:
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
-static int cdbackopacity(cdCtxCanvas *ctxcanvas, int opacity)
-{
- ctxcanvas->backopacity = opacity;
- return opacity;
+ fprintf(ctxcanvas->file, "<polygon points=\"");
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+
+ ctxcanvas->clip_polygon = 1;
+
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+
+ break;
+
+ }
}
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 +785,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 +812,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->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->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->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->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->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->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->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->opacity);
break;
}
@@ -608,7 +860,7 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (*data2rgb)(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b))
{
- int i, j;
+ int i, j, ret;
unsigned char r, g, b;
char color[20];
@@ -619,13 +871,18 @@ static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (
{
for (i = 0; i < n; i++)
{
- int ret = data2rgb(ctxcanvas, n, i, j, data, &r, &g, &b);
+ /* internal transform, affects also pattern orientation */
+ if (ctxcanvas->canvas->invert_yaxis)
+ ret = data2rgb(ctxcanvas, n, i, m-1 - j, data, &r, &g, &b);
+ else
+ ret = data2rgb(ctxcanvas, n, i, j, data, &r, &g, &b);
+
if (ret == -1) continue;
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,65 +899,69 @@ 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);
}
static int uchar2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b)
{
- int ret = 1;
unsigned char* uchar_data = (unsigned char*)data;
if (uchar_data[j*n+i])
- {
cdDecodeColor(ctxcanvas->canvas->foreground, r, g, b);
- ret = 1;
- }
else
{
- cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
if (ctxcanvas->canvas->back_opacity==CD_TRANSPARENT)
- ret = -1;
+ return -1;
+ else
+ cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
}
- return ret;
+ return 1;
}
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 +972,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 +980,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 +1021,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 +1070,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 +1121,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 +1137,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.5\" style=\"fill:rgb(%d,%d,%d); stroke:none; opacity:%g\" />\n",
+ x, y, r, g, b, ctxcanvas->opacity);
}
static void cddeactivate (cdCtxCanvas* ctxcanvas)
@@ -892,13 +1151,80 @@ 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", cdRound(ctxcanvas->opacity*255.0));
+ 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, "%s", data);
+}
+
+static cdAttribute cmd_attrib =
+{
+ "CMD",
+ set_cmd_attrib,
+ NULL
+};
+
static void cdcreatecanvas(cdCanvas *canvas, void *data)
{
char filename[10240] = "";
char* strdata = (char*)data;
double w_mm = INT_MAX*3.78, h_mm = INT_MAX*3.78, res = 3.78;
cdCtxCanvas* ctxcanvas;
- int size;
strdata += cdGetFileName(strdata, filename);
if (filename[0] == 0)
@@ -916,10 +1242,6 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data)
return;
}
- size = strlen(filename);
- ctxcanvas->filename = malloc(size+1);
- memcpy(ctxcanvas->filename, filename, size+1);
-
/* store the base canvas */
ctxcanvas->canvas = canvas;
@@ -937,17 +1259,23 @@ 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);
+ cdRegisterAttribute(canvas, &opacity_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, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%gpt\" height=\"%gpt\" viewBox=\"0 0 %d %d\" version=\"1.1\">\n", CD_MM2PT*canvas->w_mm, CD_MM2PT*canvas->h_mm, canvas->w, canvas->h);
+ fprintf(ctxcanvas->file, "<g>\n"); /* open global container */
}
static void cdinittable(cdCanvas* canvas)
@@ -979,9 +1307,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 +1322,7 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFlush = cdflush;
canvas->cxDeactivate = cddeactivate;
- canvas->cxKillCanvas = (void (*)(cdCtxCanvas*))cdkillcanvas;
+ canvas->cxKillCanvas = cdkillcanvas;
}
static cdContext cdSVGContext =