summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cairo/cdcaironative_x11.c2
-rw-r--r--src/drv/cdcgm.c14
-rw-r--r--src/drv/cddebug.c118
-rw-r--r--src/drv/cddgn.c13
-rw-r--r--src/drv/cddxf.c24
-rw-r--r--src/drv/cdirgb.c8
-rw-r--r--src/drv/cdmf.c93
-rw-r--r--src/drv/cdpdf.c3
-rw-r--r--src/drv/cdpicture.c201
-rw-r--r--src/gdiplus/cdwclpp.cpp6
-rw-r--r--src/gdiplus/cdwdbufp.cpp3
-rw-r--r--src/gdiplus/cdwemfp.cpp3
-rw-r--r--src/gdiplus/cdwimgp.cpp3
-rw-r--r--src/gdiplus/cdwinp.cpp66
-rw-r--r--src/gdiplus/cdwnativep.cpp3
-rw-r--r--src/gdiplus/cdwprnp.cpp1
-rw-r--r--src/gdk/cdgdk.c94
-rw-r--r--src/gdk/cdgdkclp.c2
-rw-r--r--src/gdk/cdgdkdbuf.c3
-rw-r--r--src/gdk/cdgdkimg.c2
-rw-r--r--src/gdk/cdgdknative.c2
-rw-r--r--src/lua5/cdlua5.c13
-rw-r--r--src/lua5/cdlua5_canvas.c7
-rw-r--r--src/sim/sim_other.c2
-rw-r--r--src/sim/sim_primitives.c123
-rw-r--r--src/x11/cdx11.c3
-rw-r--r--src/x11/cdxclp.c2
-rw-r--r--src/x11/cdxdbuf.c3
-rw-r--r--src/x11/cdximg.c2
-rw-r--r--src/x11/cdxnative.c2
-rw-r--r--src/xrender/cdxrender.c16
31 files changed, 738 insertions, 99 deletions
diff --git a/src/cairo/cdcaironative_x11.c b/src/cairo/cdcaironative_x11.c
index 027de4e..1030745 100644
--- a/src/cairo/cdcaironative_x11.c
+++ b/src/cairo/cdcaironative_x11.c
@@ -83,7 +83,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeWindowContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_FPRIMTIVES),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/drv/cdcgm.c b/src/drv/cdcgm.c
index ab47c1e..94b1619 100644
--- a/src/drv/cdcgm.c
+++ b/src/drv/cdcgm.c
@@ -566,6 +566,12 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
case CD_FILL:
cgm_polygon( ctxcanvas->cgm, n, fpoly);
break;
+ case CD_BEZIER:
+ cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
+ break;
}
free(fpoly);
@@ -595,6 +601,12 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
case CD_FILL:
cgm_polygon( ctxcanvas->cgm, n, fpoly);
break;
+ case CD_BEZIER:
+ cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
+ break;
}
}
@@ -1122,7 +1134,7 @@ static cdContext cdCGMContext =
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
CD_CAP_FONTDIM | CD_CAP_TEXTSIZE |
CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB |
- CD_CAP_TEXTORIENTATION),
+ CD_CAP_TEXTORIENTATION | CD_CAP_PATH | CD_CAP_BEZIER),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/drv/cddebug.c b/src/drv/cddebug.c
index 0c5fd0d..bd91209 100644
--- a/src/drv/cddebug.c
+++ b/src/drv/cddebug.c
@@ -27,6 +27,7 @@
#define CDDBG_BEGIN "Begin"
#define CDDBG_VERTEX "Vertex"
#define CDDBG_END "End"
+#define CDDBG_PATHSET "PathSet"
#define CDDBG_MARK "Mark"
#define CDDBG_BACKOPACITY "BackOpacity"
#define CDDBG_WRITEMODE "WriteMode"
@@ -236,7 +237,8 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
"CD_CLOSED_LINES",
"CD_CLIP",
"CD_BEZIER",
- "CD_REGION"
+ "CD_REGION",
+ "CD_PATH"
};
if (mode == CD_FILL && ctxcanvas->canvas->fill_mode != ctxcanvas->last_fill_mode)
@@ -254,8 +256,61 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
else
fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_BEGIN, enum2str[mode]);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ const char* path2str[] = {
+ "CD_PATH_NEW",
+ "CD_PATH_MOVETO",
+ "CD_PATH_LINETO",
+ "CD_PATH_ARC",
+ "CD_PATH_CURVETO",
+ "CD_PATH_CLOSE",
+ "CD_PATH_FILL",
+ "CD_PATH_STROKE",
+ "CD_PATH_FILLSTROKE",
+ "CD_PATH_CLIP"
+ };
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_PATHSET, path2str[ctxcanvas->canvas->path[p]]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%s()\n", CDDBG_END);
}
@@ -284,8 +339,61 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_BEGIN, enum2str[mode]);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_FVERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ const char* path2str[] = {
+ "CD_PATH_NEW",
+ "CD_PATH_MOVETO",
+ "CD_PATH_LINETO",
+ "CD_PATH_ARC",
+ "CD_PATH_CURVETO",
+ "CD_PATH_CLOSE",
+ "CD_PATH_FILL",
+ "CD_PATH_STROKE",
+ "CD_PATH_FILLSTROKE",
+ "CD_PATH_CLIP"
+ };
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_PATHSET, path2str[ctxcanvas->canvas->path[p]]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_FVERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%s()\n", CDDBG_END);
}
diff --git a/src/drv/cddgn.c b/src/drv/cddgn.c
index d7dd5f9..dd049fd 100644
--- a/src/drv/cddgn.c
+++ b/src/drv/cddgn.c
@@ -1066,6 +1066,17 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
short is_fill=0;
+ if (mode == CD_BEZIER)
+ {
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if(mode == CD_FILL && ctxcanvas->fill_type == NOFILL)
mode = CD_CLOSED_LINES;
@@ -1667,7 +1678,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDGNContext =
{
- CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY |
+ CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PATH | CD_CAP_BEZIER |
CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB |
CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY | CD_CAP_RECT |
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
diff --git a/src/drv/cddxf.c b/src/drv/cddxf.c
index 9f67ef4..f8c9a28 100644
--- a/src/drv/cddxf.c
+++ b/src/drv/cddxf.c
@@ -441,6 +441,17 @@ static void cdflush (cdCtxCanvas *ctxcanvas)
/*==========================================================================*/
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
+ if (mode == CD_BEZIER)
+ {
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if (mode == CD_CLOSED_LINES || mode == CD_FILL)
{
poly[n].x = poly[0].x;
@@ -501,6 +512,17 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
+ if (mode == CD_BEZIER)
+ {
+ cdfSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdfSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if (mode == CD_CLOSED_LINES || mode == CD_FILL)
{
poly[n].x = poly[0].x;
@@ -1331,7 +1353,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDXFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PALETTE |
- CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY |
+ CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY | CD_CAP_PATH | CD_CAP_BEZIER |
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
CD_CAP_IMAGERGB | CD_CAP_IMAGEMAP | CD_CAP_IMAGESRV |
CD_CAP_BACKGROUND | CD_CAP_BACKOPACITY | CD_CAP_WRITEMODE |
diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c
index f0eb98e..3caeb3c 100644
--- a/src/drv/cdirgb.c
+++ b/src/drv/cdirgb.c
@@ -1956,8 +1956,8 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageRGBContext =
{
CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvas,
cdinittable,
@@ -2074,8 +2074,8 @@ static void cdinittableDB(cdCanvas* canvas)
static cdContext cdDBufferRGBContext =
{
CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvasDB,
cdinittableDB,
diff --git a/src/drv/cdmf.c b/src/drv/cdmf.c
index 727fcac..ddb109c 100644
--- a/src/drv/cdmf.c
+++ b/src/drv/cdmf.c
@@ -96,7 +96,8 @@ enum
CDMF_FCHORD, /* 72 */
CDMF_FCLIPAREA, /* 73 */
CDMF_FONT, /* 74 */
- CDMF_RESETMATRIX /* 75 */
+ CDMF_RESETMATRIX, /* 75 */
+ CDMF_PATHSET /* 76 */
};
struct _cdCtxCanvas
@@ -242,8 +243,49 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%d %d\n", CDMF_PATHSET, ctxcanvas->canvas->path[p]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%d\n", CDMF_END);
}
@@ -260,8 +302,49 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%d %d\n", CDMF_PATHSET, ctxcanvas->canvas->path[p]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%d\n", CDMF_END);
}
diff --git a/src/drv/cdpdf.c b/src/drv/cdpdf.c
index eb9371f..4614568 100644
--- a/src/drv/cdpdf.c
+++ b/src/drv/cdpdf.c
@@ -1684,8 +1684,7 @@ static cdContext cdPDFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PALETTE |
CD_CAP_REGION | CD_CAP_IMAGESRV | CD_CAP_TEXTSIZE |
- CD_CAP_BACKGROUND | CD_CAP_BACKOPACITY | CD_CAP_WRITEMODE |
- CD_CAP_GETIMAGERGB),
+ CD_CAP_WRITEMODE | CD_CAP_GETIMAGERGB),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/drv/cdpicture.c b/src/drv/cdpicture.c
index a5533b2..c77f042 100644
--- a/src/drv/cdpicture.c
+++ b/src/drv/cdpicture.c
@@ -27,6 +27,7 @@ typedef enum _tPrim
CDPIC_CHORD,
CDPIC_TEXT,
CDPIC_POLY,
+ CDPIC_PATH,
CDPIC_FLINE,
CDPIC_FRECT,
CDPIC_FBOX,
@@ -35,6 +36,7 @@ typedef enum _tPrim
CDPIC_FCHORD,
CDPIC_FTEXT,
CDPIC_FPOLY,
+ CDPIC_FPATH,
CDPIC_PIXEL,
CDPIC_IMAGEMAP,
CDPIC_IMAGERGB,
@@ -109,6 +111,24 @@ typedef struct _tfPoly
cdfPoint* points;
} tfPoly; /* Begin, Vertex and End */
+typedef struct _tPath
+{
+ int fill;
+ int n;
+ cdPoint* points;
+ int path_n;
+ int *path;
+} tPath; /* Begin, PathSet, Vertex and End */
+
+typedef struct _tfPath
+{
+ int fill;
+ int n;
+ cdfPoint* points;
+ int path_n;
+ int *path;
+} tfPath; /* Begin, PathSet, Vertex and End */
+
typedef struct _tText
{
int x, y;
@@ -156,6 +176,8 @@ typedef struct _tPrimNode
tfASC arcsectorchordf;
tPoly poly;
tfPoly polyf;
+ tPath path;
+ tfPath pathf;
tText text;
tfText textf;
tPixel pixel;
@@ -608,16 +630,72 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
}
+static void cdpath(cdCtxCanvas *ctxcanvas, cdPoint* poly, int n)
+{
+ int i, p, fill = -1;
+ tPrimNode *prim;
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ return;
+ else if (ctxcanvas->canvas->path[p] == CD_PATH_FILL ||
+ ctxcanvas->canvas->path[p] == CD_PATH_FILLSTROKE) /* no support for both in cdPicture */
+ {
+ fill = 1;
+ break;
+ }
+ else if (ctxcanvas->canvas->path[p] == CD_PATH_STROKE)
+ {
+ fill = -1;
+ break;
+ }
+ }
+
+ if (fill == -1)
+ return;
+
+ prim = primCreate(CDPIC_PATH);
+ prim->param.path.fill = fill;
+
+ if (fill)
+ primAddAttrib_Fill(prim, ctxcanvas->canvas);
+ else
+ primAddAttrib_Line(prim, ctxcanvas->canvas);
+
+ prim->param_buffer = malloc(n * sizeof(cdPoint) + ctxcanvas->canvas->path_n * sizeof(int));
+
+ prim->param.path.n = n;
+ prim->param.path.points = (cdPoint*)prim->param_buffer;
+ memcpy(prim->param.path.points, poly, n * sizeof(cdPoint));
+ prim->param.path.path = (int*)((unsigned char*)prim->param_buffer + n * sizeof(cdPoint));
+ memcpy(prim->param.path.path, ctxcanvas->canvas->path, ctxcanvas->canvas->path_n * sizeof(int));
+ prim->param.path.path_n = ctxcanvas->canvas->path_n;
+
+ picAddPrim(ctxcanvas, prim);
+
+ for (i = 0; i < n; i++)
+ {
+ picUpdateBBox(ctxcanvas, poly[i].x, poly[i].y, 0);
+ }
+}
+
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
int i;
tPrimNode *prim;
if (mode == CD_CLIP || mode == CD_REGION) return;
+ if (mode == CD_PATH)
+ {
+ cdpath(ctxcanvas, poly, n);
+ return;
+ }
prim = primCreate(CDPIC_POLY);
if (mode == CD_FILL)
primAddAttrib_Fill(prim, ctxcanvas->canvas);
else
primAddAttrib_Line(prim, ctxcanvas->canvas);
+ prim->param.poly.mode = mode;
prim->param.poly.n = n;
prim->param.poly.points = malloc(n * sizeof(cdPoint));
memcpy(prim->param.poly.points, poly, n * sizeof(cdPoint));
@@ -633,6 +711,56 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
}
}
+static void cdfpath(cdCtxCanvas *ctxcanvas, cdfPoint* poly, int n)
+{
+ int i, p, fill = -1;
+ tPrimNode *prim;
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ return;
+ else if (ctxcanvas->canvas->path[p] == CD_PATH_FILL ||
+ ctxcanvas->canvas->path[p] == CD_PATH_FILLSTROKE) /* no support for both in cdPicture */
+ {
+ fill = 1;
+ break;
+ }
+ else if (ctxcanvas->canvas->path[p] == CD_PATH_STROKE)
+ {
+ fill = -1;
+ break;
+ }
+ }
+
+ if (fill == -1)
+ return;
+
+ prim = primCreate(CDPIC_FPATH);
+ prim->param.pathf.fill = fill;
+
+ if (fill)
+ primAddAttrib_Fill(prim, ctxcanvas->canvas);
+ else
+ primAddAttrib_Line(prim, ctxcanvas->canvas);
+
+ prim->param_buffer = malloc(n * sizeof(cdfPoint) + ctxcanvas->canvas->path_n * sizeof(int));
+
+ prim->param.pathf.n = n;
+ prim->param.pathf.points = (cdfPoint*)prim->param_buffer;
+ memcpy(prim->param.pathf.points, poly, n * sizeof(cdfPoint));
+ prim->param.pathf.path = (int*)((unsigned char*)prim->param_buffer + n * sizeof(cdfPoint));
+ memcpy(prim->param.pathf.path, ctxcanvas->canvas->path, ctxcanvas->canvas->path_n * sizeof(int));
+ prim->param.pathf.path_n = ctxcanvas->canvas->path_n;
+
+ picAddPrim(ctxcanvas, prim);
+
+ for (i = 0; i < n; i++)
+ {
+ picUpdateBBox(ctxcanvas, _cdRound(poly[i].x), _cdRound(poly[i].y), 0);
+ }
+}
+
static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
int i;
@@ -643,9 +771,10 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
primAddAttrib_Fill(prim, ctxcanvas->canvas);
else
primAddAttrib_Line(prim, ctxcanvas->canvas);
+ prim->param.polyf.mode = mode;
prim->param.polyf.n = n;
- prim->param.polyf.points = malloc(n * sizeof(cdPoint));
- memcpy(prim->param.polyf.points, poly, n * sizeof(cdPoint));
+ prim->param.polyf.points = malloc(n * sizeof(cdfPoint));
+ memcpy(prim->param.polyf.points, poly, n * sizeof(cdfPoint));
prim->param_buffer = prim->param.polyf.points;
picAddPrim(ctxcanvas, prim);
@@ -843,7 +972,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void
tPrimNode *prim;
cdCanvas* pic_canvas = (cdCanvas*)data;
cdCtxCanvas* ctxcanvas = pic_canvas->ctxcanvas;
- int p, i, scale = 0,
+ int p, i, n, scale = 0,
pic_xmin = ctxcanvas->xmin,
pic_ymin = ctxcanvas->ymin;
double factorX = 1, factorY = 1;
@@ -949,6 +1078,72 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void
cdfCanvasVertex(canvas, sfScaleX(prim->param.polyf.points[p].x), sfScaleY(prim->param.polyf.points[p].y));
cdCanvasEnd(canvas);
break;
+ case CDPIC_PATH:
+ if (prim->param.path.fill)
+ primUpdateAttrib_Fill(prim, canvas);
+ else
+ primUpdateAttrib_Line(prim, canvas);
+ cdCanvasBegin(canvas, CD_PATH);
+ n = 0;
+ for (p=0; p<prim->param.path.path_n; p++)
+ {
+ cdCanvasPathSet(canvas, prim->param.path.path[p]);
+
+ switch(prim->param.path.path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (n+1 > n) break;
+ cdCanvasVertex(canvas, sScaleX(prim->param.path.points[n].x), sScaleY(prim->param.path.points[n].y));
+ n++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (n+3 > n) break;
+ cdCanvasVertex(canvas, sScaleX(prim->param.path.points[n].x), sScaleY(prim->param.path.points[n].y));
+ cdCanvasVertex(canvas, sScaleX(prim->param.path.points[n+1].x), sScaleY(prim->param.path.points[n+1].y));
+ cdCanvasVertex(canvas, sScaleX(prim->param.path.points[n+2].x), sScaleY(prim->param.path.points[n+2].y));
+ n += 3;
+ }
+ break;
+ }
+ }
+ cdCanvasEnd(canvas);
+ break;
+ case CDPIC_FPATH:
+ if (prim->param.path.fill)
+ primUpdateAttrib_Fill(prim, canvas);
+ else
+ primUpdateAttrib_Line(prim, canvas);
+ cdCanvasBegin(canvas, CD_PATH);
+ n = 0;
+ for (p=0; p<prim->param.pathf.path_n; p++)
+ {
+ cdCanvasPathSet(canvas, prim->param.pathf.path[p]);
+
+ switch(prim->param.pathf.path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (n+1 > n) break;
+ cdfCanvasVertex(canvas, sfScaleX(prim->param.pathf.points[n].x), sfScaleY(prim->param.pathf.points[n].y));
+ n++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (n+3 > n) break;
+ cdfCanvasVertex(canvas, sfScaleX(prim->param.pathf.points[n].x), sfScaleY(prim->param.pathf.points[n].y));
+ cdfCanvasVertex(canvas, sfScaleX(prim->param.pathf.points[n+1].x), sfScaleY(prim->param.pathf.points[n+1].y));
+ cdfCanvasVertex(canvas, sfScaleX(prim->param.pathf.points[n+2].x), sfScaleY(prim->param.pathf.points[n+2].y));
+ n += 3;
+ }
+ break;
+ }
+ }
+ cdCanvasEnd(canvas);
+ break;
case CDPIC_IMAGERGB:
cdCanvasPutImageRectRGB(canvas, prim->param.imagergba.iw, prim->param.imagergba.ih, prim->param.imagergba.r, prim->param.imagergba.g, prim->param.imagergba.b, sScaleX(prim->param.imagergba.x), sScaleY(prim->param.imagergba.y), sScaleW(prim->param.imagergba.w), sScaleH(prim->param.imagergba.h), 0, 0, 0, 0);
break;
diff --git a/src/gdiplus/cdwclpp.cpp b/src/gdiplus/cdwclpp.cpp
index 719713f..0e3c5ea 100644
--- a/src/gdiplus/cdwclpp.cpp
+++ b/src/gdiplus/cdwclpp.cpp
@@ -187,10 +187,8 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS |
- CD_CAP_PLAY |
- CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS | CD_CAP_PLAY |
+ CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdiplus/cdwdbufp.cpp b/src/gdiplus/cdwdbufp.cpp
index 87957fb..68bc7b8 100644
--- a/src/gdiplus/cdwdbufp.cpp
+++ b/src/gdiplus/cdwdbufp.cpp
@@ -147,8 +147,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdiplus/cdwemfp.cpp b/src/gdiplus/cdwemfp.cpp
index 38b4200..23ae02d 100644
--- a/src/gdiplus/cdwemfp.cpp
+++ b/src/gdiplus/cdwemfp.cpp
@@ -58,7 +58,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void* data)
Rect frameRect(0, 0, (int)(100 * w / canvas->xres), (int)(100 * h / canvas->yres));
metafile = new Metafile(cdwpString2Unicode(filename, strlen(filename)),
- ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL);
+ ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL);
ReleaseDC(NULL, ScreenDC);
}
@@ -86,7 +86,6 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdEMFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_FLUSH | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES |
CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV),
1,
cdcreatecanvas,
diff --git a/src/gdiplus/cdwimgp.cpp b/src/gdiplus/cdwimgp.cpp
index 697ff40..5dd8b96 100644
--- a/src/gdiplus/cdwimgp.cpp
+++ b/src/gdiplus/cdwimgp.cpp
@@ -48,8 +48,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdiplus/cdwinp.cpp b/src/gdiplus/cdwinp.cpp
index a8d3f9c..5fbe2db 100644
--- a/src/gdiplus/cdwinp.cpp
+++ b/src/gdiplus/cdwinp.cpp
@@ -807,7 +807,7 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
case CD_PATH:
{
- int p, i, current_x = 0, current_y = 0;
+ int p, i, current_x = 0, current_y = 0, current_set = 0;
GraphicsPath* graphics_path;
PointF lastPoint;
@@ -822,18 +822,22 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
case CD_PATH_NEW:
graphics_path->Reset();
graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
break;
case CD_PATH_MOVETO:
if (i+1 > n) break;
current_x = poly[i].x;
current_y = poly[i].y;
+ current_set = 1;
i++;
break;
case CD_PATH_LINETO:
if (i+1 > n) break;
- graphics_path->AddLine(current_x, current_y, poly[i].x, poly[i].y);
+ if (current_set)
+ graphics_path->AddLine(current_x, current_y, poly[i].x, poly[i].y);
current_x = poly[i].x;
current_y = poly[i].y;
+ current_set = 1;
i++;
break;
case CD_PATH_ARC:
@@ -850,6 +854,24 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
a1 = poly[i+2].x/1000.0,
a2 = poly[i+2].y/1000.0;
+ if (current_set)
+ {
+ int StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ {
+ StartX = xc + cdRound(w * cos(CD_DEG2RAD * a1) / 2.0);
+ StartY = yc - cdRound(h * sin(CD_DEG2RAD * a1) / 2.0);
+ }
+ else
+ {
+ StartX = xc + cdRound(w * cos(CD_DEG2RAD * a2) / 2.0);
+ StartY = yc + cdRound(h * sin(CD_DEG2RAD * a2) / 2.0);
+ }
+
+ graphics_path->AddLine(current_x, current_y, StartX, StartY);
+ }
+
Rect rect(xc - w/2, yc - h/2, w, h);
if (a1 == 0 && a2 == 360)
graphics_path->AddEllipse(rect);
@@ -862,16 +884,23 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
graphics_path->GetLastPoint(&lastPoint);
current_x = (int)lastPoint.X;
current_y = (int)lastPoint.Y;
+ current_set = 1;
i += 3;
}
break;
case CD_PATH_CURVETO:
if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
graphics_path->AddBezier(current_x, current_y, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
graphics_path->GetLastPoint(&lastPoint);
current_x = (int)lastPoint.X;
current_y = (int)lastPoint.Y;
+ current_set = 1;
i += 3;
break;
case CD_PATH_CLOSE:
@@ -1011,7 +1040,7 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
{
case CD_PATH:
{
- int p, i;
+ int p, i, current_set = 0;
double current_x = 0, current_y = 0;
GraphicsPath* graphics_path;
PointF lastPoint;
@@ -1027,18 +1056,22 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
case CD_PATH_NEW:
graphics_path->Reset();
graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
break;
case CD_PATH_MOVETO:
if (i+1 > n) break;
current_x = poly[i].x;
current_y = poly[i].y;
+ current_set = 1;
i++;
break;
case CD_PATH_LINETO:
if (i+1 > n) break;
- graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y);
+ if (current_set)
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y);
current_x = poly[i].x;
current_y = poly[i].y;
+ current_set = 1;
i++;
break;
case CD_PATH_ARC:
@@ -1055,6 +1088,24 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
a1 = poly[i+2].x,
a2 = poly[i+2].y;
+ if (current_set)
+ {
+ double StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ {
+ StartX = xc + w * cos(CD_DEG2RAD * a1) / 2.0;
+ StartY = yc - h * sin(CD_DEG2RAD * a1) / 2.0;
+ }
+ else
+ {
+ StartX = xc + w * cos(CD_DEG2RAD * a2) / 2.0;
+ StartY = yc + h * sin(CD_DEG2RAD * a2) / 2.0;
+ }
+
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)StartX, (REAL)StartY);
+ }
+
RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
if (a1 == 0 && a2 == 360)
graphics_path->AddEllipse(rect);
@@ -1067,16 +1118,23 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
graphics_path->GetLastPoint(&lastPoint);
current_x = lastPoint.X;
current_y = lastPoint.Y;
+ current_set = 1;
i += 3;
}
break;
case CD_PATH_CURVETO:
if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
graphics_path->AddBezier((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y, (REAL)poly[i+1].x, (REAL)poly[i+1].y, (REAL)poly[i+2].x, (REAL)poly[i+2].y);
graphics_path->GetLastPoint(&lastPoint);
current_x = lastPoint.X;
current_y = lastPoint.Y;
+ current_set = 1;
i += 3;
break;
case CD_PATH_CLOSE:
diff --git a/src/gdiplus/cdwnativep.cpp b/src/gdiplus/cdwnativep.cpp
index fffd044..80209af 100644
--- a/src/gdiplus/cdwnativep.cpp
+++ b/src/gdiplus/cdwnativep.cpp
@@ -121,8 +121,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdiplus/cdwprnp.cpp b/src/gdiplus/cdwprnp.cpp
index 3d2b9f7..2eed9d9 100644
--- a/src/gdiplus/cdwprnp.cpp
+++ b/src/gdiplus/cdwprnp.cpp
@@ -140,7 +140,6 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdPrinterContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES |
CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV),
1,
cdcreatecanvas,
diff --git a/src/gdk/cdgdk.c b/src/gdk/cdgdk.c
index 1eccaa8..e16a73a 100644
--- a/src/gdk/cdgdk.c
+++ b/src/gdk/cdgdk.c
@@ -886,51 +886,55 @@ static void cdgettextsize(cdCtxCanvas *ctxcanvas, const char *s, int len, int *w
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
- int i;
-
- if (mode != CD_BEZIER)
- {
- for (i = 0; i < n; i++)
- {
- if (ctxcanvas->canvas->use_matrix)
- cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
- }
- }
-
- switch( mode )
- {
- case CD_FILL:
- if (ctxcanvas->canvas->new_region)
- {
- GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
- sCombineRegion(ctxcanvas, rgn);
- }
- else
- gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
- break;
-
- case CD_CLOSED_LINES:
- cdgdkCheckSolidStyle(ctxcanvas, 1);
- gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
- cdgdkCheckSolidStyle(ctxcanvas, 0);
- break;
-
- case CD_OPEN_LINES:
- cdgdkCheckSolidStyle(ctxcanvas, 1);
- gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
- cdgdkCheckSolidStyle(ctxcanvas, 0);
- break;
-
- case CD_CLIP:
- ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
- if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
- cdclip(ctxcanvas, CD_CLIPPOLYGON);
- break;
-
- case CD_BEZIER:
- cdSimPolyBezier(ctxcanvas->canvas, poly, n);
- break;
- }
+ int i;
+
+ if (mode != CD_BEZIER)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (ctxcanvas->canvas->use_matrix)
+ cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
+ }
+ }
+
+ switch( mode )
+ {
+ case CD_FILL:
+ if (ctxcanvas->canvas->new_region)
+ {
+ GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
+ sCombineRegion(ctxcanvas, rgn);
+ }
+ else
+ gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
+ break;
+
+ case CD_CLOSED_LINES:
+ cdgdkCheckSolidStyle(ctxcanvas, 1);
+ gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
+ cdgdkCheckSolidStyle(ctxcanvas, 0);
+ break;
+
+ case CD_OPEN_LINES:
+ cdgdkCheckSolidStyle(ctxcanvas, 1);
+ gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
+ cdgdkCheckSolidStyle(ctxcanvas, 0);
+ break;
+
+ case CD_CLIP:
+ ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ break;
+
+ case CD_BEZIER:
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ break;
+
+ case CD_PATH:
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
+ }
}
/******************************************************/
diff --git a/src/gdk/cdgdkclp.c b/src/gdk/cdgdkclp.c
index 22e7690..3eabc54 100644
--- a/src/gdk/cdgdkclp.c
+++ b/src/gdk/cdgdkclp.c
@@ -115,7 +115,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE),
+ CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE ), /* same as CD_MF */
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdk/cdgdkdbuf.c b/src/gdk/cdgdkdbuf.c
index aa8d587..b399cbe 100644
--- a/src/gdk/cdgdkdbuf.c
+++ b/src/gdk/cdgdkdbuf.c
@@ -147,8 +147,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_PATH | CD_CAP_BEZIER | CD_CAP_FPRIMTIVES ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdk/cdgdkimg.c b/src/gdk/cdgdkimg.c
index 0c5e5dd..4b4475b 100644
--- a/src/gdk/cdgdkimg.c
+++ b/src/gdk/cdgdkimg.c
@@ -30,7 +30,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/gdk/cdgdknative.c b/src/gdk/cdgdknative.c
index 9f0c5ed..8865d7e 100644
--- a/src/gdk/cdgdknative.c
+++ b/src/gdk/cdgdknative.c
@@ -95,7 +95,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeWindowContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/lua5/cdlua5.c b/src/lua5/cdlua5.c
index 954389c..bb40ecb 100644
--- a/src/lua5/cdlua5.c
+++ b/src/lua5/cdlua5.c
@@ -1428,8 +1428,21 @@ static const struct cdlua5_constant cdlibconstant[] = {
{"CLIP" , CD_CLIP},
{"BEZIER" , CD_BEZIER},
{"REGION" , CD_REGION},
+ {"PATH" , CD_PATH},
{"POLYCUSTOM" , CD_POLYCUSTOM},
+ /* path actions */
+ {"PATH_NEW", CD_PATH_NEW},
+ {"PATH_MOVETO", CD_PATH_MOVETO},
+ {"PATH_LINETO", CD_PATH_LINETO},
+ {"PATH_ARC", CD_PATH_ARC},
+ {"PATH_CURVETO", CD_PATH_CURVETO},
+ {"PATH_CLOSE", CD_PATH_CLOSE},
+ {"PATH_FILL", CD_PATH_FILL},
+ {"PATH_STROKE", CD_PATH_STROKE},
+ {"PATH_FILLSTROKE", CD_PATH_FILLSTROKE},
+ {"PATH_CLIP", CD_PATH_CLIP},
+
/* fill mode */
{"EVENODD", CD_EVENODD},
{"WINDING", CD_WINDING},
diff --git a/src/lua5/cdlua5_canvas.c b/src/lua5/cdlua5_canvas.c
index f3b929d..37d36b3 100644
--- a/src/lua5/cdlua5_canvas.c
+++ b/src/lua5/cdlua5_canvas.c
@@ -2205,6 +2205,12 @@ static int cdlua5_vertex(lua_State *L)
return 0;
}
+static int cdlua5_pathset(lua_State *L)
+{
+ cdCanvasPathSet(cdlua_checkcanvas(L, 1), luaL_checkint(L, 2));
+ return 0;
+}
+
static int wdlua5_vertex(lua_State *L)
{
wdCanvasVertex(cdlua_checkcanvas(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3));
@@ -2429,6 +2435,7 @@ static const struct luaL_reg cdlib_canvas_meta[] = {
/* Polygon */
{"Begin" , cdlua5_begin},
+ {"PathSet" , cdlua5_pathset},
{"Vertex" , cdlua5_vertex},
{"wVertex" , wdlua5_vertex},
{"fVertex" , cdlua5_fvertex},
diff --git a/src/sim/sim_other.c b/src/sim/sim_other.c
index 0954406..9079501 100644
--- a/src/sim/sim_other.c
+++ b/src/sim/sim_other.c
@@ -261,7 +261,7 @@ void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n)
last_yi_b = -65535;
/* Use special floating point anti-alias line draw when
- line_width==1, and NOT using cdlineSIM. */
+ line_width==1, and using cdlineSIM. */
if (canvas->line_width > 1 || canvas->cxLine != cdlineSIM)
use_poly = 1;
diff --git a/src/sim/sim_primitives.c b/src/sim/sim_primitives.c
index 78f7be0..a0a2e77 100644
--- a/src/sim/sim_primitives.c
+++ b/src/sim/sim_primitives.c
@@ -471,6 +471,124 @@ void cdchordSIM(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, d
cdSimElipse(ctxcanvas, xc, yc, width, height, angle1, angle2, 0);
}
+void cdfSimPolyPath(cdCtxCanvas* ctxcanvas, cdfPoint* poly, int n)
+{
+}
+
+void cdSimPolyPath(cdCtxCanvas* ctxcanvas, cdPoint* poly, int n)
+{
+// int p, i, current_x = 0, current_y = 0, current_set = 0;
+//
+// i = 0;
+// for (p=0; p<ctxcanvas->canvas->path_n; p++)
+// {
+// switch(ctxcanvas->canvas->path[p])
+// {
+// case CD_PATH_NEW:
+// current_set = 0;
+// break;
+// case CD_PATH_MOVETO:
+// if (i+1 > n) break;
+// current_x = poly[i].x;
+// current_y = poly[i].y;
+// current_set = 1;
+// i++;
+// break;
+// case CD_PATH_LINETO:
+// if (i+1 > n) break;
+// if (current_set)
+// graphics_path->AddLine(current_x, current_y, poly[i].x, poly[i].y);
+// current_x = poly[i].x;
+// current_y = poly[i].y;
+// current_set = 1;
+// i++;
+// break;
+// case CD_PATH_ARC:
+// {
+// int xc, yc, w, h;
+// double a1, a2;
+//
+// if (i+3 > n) break;
+//
+// xc = poly[i].x,
+// yc = poly[i].y,
+// w = poly[i+1].x,
+// h = poly[i+1].y,
+// a1 = poly[i+2].x/1000.0,
+// a2 = poly[i+2].y/1000.0;
+//
+// if (current_set)
+// {
+// int StartX, StartY;
+//
+// if (ctxcanvas->canvas->invert_yaxis)
+// {
+// StartX = xc + cdRound(w * cos(CD_DEG2RAD * a1) / 2.0);
+// StartY = yc - cdRound(h * sin(CD_DEG2RAD * a1) / 2.0);
+// }
+// else
+// {
+// StartX = xc + cdRound(w * cos(CD_DEG2RAD * a2) / 2.0);
+// StartY = yc + cdRound(h * sin(CD_DEG2RAD * a2) / 2.0);
+// }
+//
+// graphics_path->AddLine(current_x, current_y, StartX, StartY);
+// }
+//
+// Rect rect(xc - w/2, yc - h/2, w, h);
+// if (a1 == 0 && a2 == 360)
+// graphics_path->AddEllipse(rect);
+// else
+// {
+// cdwpFixAngles(ctxcanvas, &a1, &a2);
+// graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
+// }
+//
+// graphics_path->GetLastPoint(&lastPoint);
+// current_x = (int)lastPoint.X;
+// current_y = (int)lastPoint.Y;
+// current_set = 1;
+//
+// i += 3;
+// }
+// break;
+// case CD_PATH_CURVETO:
+// if (i+3 > n) break;
+// if (!current_set)
+// {
+// current_x = poly[i].x;
+// current_y = poly[i].y;
+// }
+// graphics_path->AddBezier(current_x, current_y, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+// graphics_path->GetLastPoint(&lastPoint);
+// current_x = (int)lastPoint.X;
+// current_y = (int)lastPoint.Y;
+// current_set = 1;
+// i += 3;
+// break;
+// case CD_PATH_CLOSE:
+// graphics_path->CloseFigure();
+// break;
+// case CD_PATH_FILL:
+// ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+// break;
+// case CD_PATH_STROKE:
+// ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+// break;
+// case CD_PATH_FILLSTROKE:
+// ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+// ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+// break;
+// case CD_PATH_CLIP:
+// ctxcanvas->graphics->SetClip(graphics_path, CombineModeIntersect);
+// break;
+// }
+// }
+//
+// delete graphics_path;
+// break;
+}
+
void cdpolySIM(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
@@ -497,6 +615,11 @@ void cdpolySIM(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
cdSimPolyBezier(canvas, poly, n);
simLineStyleNoReset = 0;
break;
+ case CD_PATH:
+ simLineStyleNoReset = 1;
+ cdSimPolyPath(canvas, poly, n);
+ simLineStyleNoReset = 0;
+ break;
case CD_FILL:
{
/* must set line attributes here, because fill simulation use cxLine */
diff --git a/src/x11/cdx11.c b/src/x11/cdx11.c
index 35342db..e74ad67 100644
--- a/src/x11/cdx11.c
+++ b/src/x11/cdx11.c
@@ -1394,6 +1394,9 @@ void cdxPoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
case CD_BEZIER:
cdSimPolyBezier(ctxcanvas->canvas, poly, n);
break;
+ case CD_PATH:
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
}
if (pnt) free(pnt);
diff --git a/src/x11/cdxclp.c b/src/x11/cdxclp.c
index d775fde..a2d1b6b 100644
--- a/src/x11/cdxclp.c
+++ b/src/x11/cdxclp.c
@@ -120,7 +120,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE),
+ CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE ), /* same as CD_MF */
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/x11/cdxdbuf.c b/src/x11/cdxdbuf.c
index 835687c..0f4955e 100644
--- a/src/x11/cdxdbuf.c
+++ b/src/x11/cdxdbuf.c
@@ -146,8 +146,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/x11/cdximg.c b/src/x11/cdximg.c
index 8131f78..c823705 100644
--- a/src/x11/cdximg.c
+++ b/src/x11/cdximg.c
@@ -30,7 +30,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/src/x11/cdxnative.c b/src/x11/cdxnative.c
index c708d20..a69314c 100644
--- a/src/x11/cdxnative.c
+++ b/src/x11/cdxnative.c
@@ -143,7 +143,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeWindowContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER),
1,
cdcreatecanvas,
cdinittable,
diff --git a/src/xrender/cdxrender.c b/src/xrender/cdxrender.c
index 4dc69e2..c1f67bf 100644
--- a/src/xrender/cdxrender.c
+++ b/src/xrender/cdxrender.c
@@ -259,6 +259,9 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
case CD_BEZIER:
cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
+ break;
case CD_FILL:
{
if (ctxcanvas->canvas->new_region)
@@ -327,11 +330,12 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
/* continue */
case CD_OPEN_LINES:
for (i = 0; i<n-1; i++)
- cdfline(ctxcanvas, (int)poly[i].x, (int)poly[i].y, (int)poly[i+1].x, (int)poly[i+1].y);
+ cdfline(ctxcanvas, (double)poly[i].x, (double)poly[i].y, (double)poly[i+1].x, (double)poly[i+1].y);
break;
+ case CD_PATH:
case CD_BEZIER:
{
- cdfPoint* fpoly = malloc(sizeof(cdfPoint)*n);
+ cdfPoint* fpoly = malloc(sizeof(cdfPoint)*n); /* because we support cdfpoly */
for (i = 0; i<n; i++)
{
@@ -339,7 +343,10 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
fpoly[i].y = (double)poly[i].y;
}
- cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
+ if (mode == CD_BEZIER)
+ cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
+ else
+ cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
free(fpoly);
}
@@ -1062,6 +1069,7 @@ cdContext* cdContextDBufferPlus(void)
int old_plus = cdUseContextPlus(0); /* disable context plus */
cdDBufferContext = *cdContextDBuffer(); /* copy original context */
cdDBufferContext.plus = 1; /* mark as plus */
+ cdDBufferContext.caps |= CD_CAP_FPRIMTIVES;
/* save original methods */
cdcreatecanvasDBUFFER = cdDBufferContext.cxCreateCanvas;
@@ -1101,6 +1109,7 @@ cdContext* cdContextNativeWindowPlus(void)
cdNativeWindowContext.cxCreateCanvas = xrCreateCanvasNATIVE;
cdNativeWindowContext.cxInitTable = xrInitTableNATIVE;
cdNativeWindowContext.plus = 1;
+ cdNativeWindowContext.caps |= CD_CAP_FPRIMTIVES;
cdUseContextPlus(old_plus);
}
return &cdNativeWindowContext;
@@ -1131,6 +1140,7 @@ cdContext* cdContextImagePlus(void)
cdImageContext.cxCreateCanvas = xrCreateCanvasIMAGE;
cdImageContext.cxInitTable = xrInitTableIMAGE;
cdImageContext.plus = 1;
+ cdImageContext.caps |= CD_CAP_FPRIMTIVES;
cdUseContextPlus(old_plus);
}
return &cdImageContext;