diff options
47 files changed, 777 insertions, 129 deletions
diff --git a/html/en/drv/cairo.html b/html/en/drv/cairo.html index c0ad80f..2e04833 100644 --- a/html/en/drv/cairo.html +++ b/html/en/drv/cairo.html @@ -66,9 +66,6 @@ for complex clipping regions.</p> </ul> <h4>Primitives</h4> <ul> - <li><a href="../func/lines.html#cdBegin"> - <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt>CD_PATH</tt></strong> - is supported.</li> <li>Floating point primitives are supported.</li> </ul> <h4>Attributes </h4> diff --git a/html/en/drv/cgm.html b/html/en/drv/cgm.html index 470561a..5c915cf 100644 --- a/html/en/drv/cgm.html +++ b/html/en/drv/cgm.html @@ -85,7 +85,9 @@ <h4>Primitives</h4> <ul> <li><a href="../func/lines.html#cdBegin"><font face="Courier"><strong>Begin</strong></font></a>: - if parameter <strong><tt>CD_CLIP</tt></strong> or <strong><tt>CD_BEZIER</tt></strong> are specified, does nothing.</li> + if parameter <strong><tt>CD_CLIP</tt></strong> is specified, does nothing.<strong><tt> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> <li><font face="Courier"><strong><a href="../func/marks.html#cdPixel">Pixel</a></strong></font>: does not exist in CGM, is simulated using a mark with size 1.</li> <li><strong><font face="Courier"><a href="../func/filled.html#cdChord">Chord</a></font></strong>: diff --git a/html/en/drv/dgn.html b/html/en/drv/dgn.html index be52f3c..b3f0ecc 100644 --- a/html/en/drv/dgn.html +++ b/html/en/drv/dgn.html @@ -68,7 +68,9 @@ <h4>Primitives</h4> <ul> <li><a href="../func/lines.html#cdBegin"><font face="Courier"><strong>Begin</strong></font></a>: - if parameter <strong><tt>CD_CLIP</tt></strong> or <strong><tt>CD_BEZIER</tt></strong> are specified, does nothing.</li> + if parameter <strong><tt>CD_CLIP</tt></strong> is specified, does nothing. <strong><tt> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> <li><strong><font face="Courier"><a href="../func/filled.html#cdChord">cdChord</a></font></strong>: does nothing.</li> </ul> diff --git a/html/en/drv/dxf.html b/html/en/drv/dxf.html index 31cf2e6..ebeb98a 100644 --- a/html/en/drv/dxf.html +++ b/html/en/drv/dxf.html @@ -68,8 +68,9 @@ <li><a href="../func/filled.html#cdSector"><font face="Courier"><strong>Sector</strong></font></a>: draws a "hollow" sector, that is, only its borders.</li> <li><a href="../func/lines.html#cdBegin"><font face="Courier"><strong>Begin</strong></font></a>: - if parameter <strong><tt>CD_CLIP</tt></strong> or <strong><tt>CD_BEZIER</tt></strong> - are specified, does nothing.</li> + if parameter <strong><tt>CD_CLIP</tt></strong> is specified, does nothing. <strong><tt> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> <li><strong><font face="Courier"><a href="../func/filled.html#cdChord">Chord</a></font></strong>: does nothing.</li> <li>Floating point primitives are supported.</li> diff --git a/html/en/drv/gdiplus.html b/html/en/drv/gdiplus.html index 41e72dd..2229207 100644 --- a/html/en/drv/gdiplus.html +++ b/html/en/drv/gdiplus.html @@ -78,8 +78,7 @@ <strong><tt>CD_FILLGRADIENT</tt></strong> defines the points of a filled polygon. It is filled with a gradient from colors in each vertex to a color in its center. The colors are defined by the "<strong><tt>GRADIENTCOLOR</tt></strong>" attribute, that must be set before each <strong><tt>cdVertex</tt></strong> call and before <strong><tt>cdEnd</tt></strong> - for the center color. This will not affect the current interior style.<br> - <strong><tt>CD_PATH</tt></strong> is supported. </li> + for the center color. This will not affect the current interior style.</li> </ul> <h4>Attributes </h4> <ul> diff --git a/html/en/drv/gdk.html b/html/en/drv/gdk.html index e4a531b..694a22c 100644 --- a/html/en/drv/gdk.html +++ b/html/en/drv/gdk.html @@ -6,6 +6,11 @@ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>GDK</title> <link rel="stylesheet" type="text/css" href="../../style.css"> +<style type="text/css"> +.style1 { + font-family: monospace; +} +</style> </head> <body> @@ -33,6 +38,13 @@ <font face="Courier"><strong>UpdateYAxis</strong></font></a>: the orientation of axis Y is the opposite to its orientation in the CD library.</li> </ul> +<h4>Primitives</h4> +<ul> + <li><a href="../func/lines.html#cdBegin"> + <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> +</ul> <h4>Attributes </h4> <ul> <li> diff --git a/html/en/drv/pdf.html b/html/en/drv/pdf.html index 2d9203d..ffbf860 100644 --- a/html/en/drv/pdf.html +++ b/html/en/drv/pdf.html @@ -167,9 +167,6 @@ ZapfDingbats</pre> does not exist in PDF, is simulated using a circle with radius=1.</li> <li>Floating point primitives are supported.</li> <li>Filled primitives do not include the line at the edges of the filled area.</li> - <li><a href="../func/lines.html#cdBegin"> - <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt>CD_PATH</tt></strong> - is supported.</li> </ul> <h4>Server Images</h4> <ul> diff --git a/html/en/drv/ps.html b/html/en/drv/ps.html index 9f4267a..4727f1d 100644 --- a/html/en/drv/ps.html +++ b/html/en/drv/ps.html @@ -180,9 +180,6 @@ does not exist in PS, is simulated using a circle with radius=1.</li> <li>Floating point primitives are supported.</li> <li>Filled primitives do not include the line at the edges of the filled area.</li> - <li><a href="../func/lines.html#cdBegin"> - <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt>CD_PATH</tt></strong> - is supported.</li> </ul> <h4>Server Images</h4> <ul> diff --git a/html/en/drv/sim.html b/html/en/drv/sim.html index 0e69d9d..93898c5 100644 --- a/html/en/drv/sim.html +++ b/html/en/drv/sim.html @@ -72,7 +72,7 @@ <li><font face="Courier"><b><a href="../func/lines.html#cdBegin">Begin</a></b></font>, <font face="Courier"><a href="../func/lines.html#cdVertex"><b>Vertex</b></a></font> and <font face="Courier"><a href="../func/lines.html#cdEnd"><b>End</b></a></font>: - simulate using the <strong>Line</strong> or <strong>Pixel</strong> functions, depending on the interior style.</li> + simulated using the <strong>Line</strong> or <strong>Pixel</strong> functions, depending on the interior style.</li> <li><font face="Courier"><a href="../func/text.html#cdText"><b>Text</b></a></font>: text simulation is made using TrueType font files in a transparent way for the user. Oriented text is not supported.</li> diff --git a/html/en/drv/svg.html b/html/en/drv/svg.html index af703a5..10a0952 100644 --- a/html/en/drv/svg.html +++ b/html/en/drv/svg.html @@ -76,9 +76,6 @@ <a href="http://www.tecgraf.puc-rio.br/cd/en/func/marks.html#cdPixel">Pixel</a></strong></font>: does not exist in SVG, is simulated using a circle with radius=0.1.</li> <li>Floating point primitives are supported.</li> - <li><a href="../func/lines.html#cdBegin"> - <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt>CD_PATH</tt></strong> - is supported.</li> </dir> <h4>Client Images</h4> <dir> diff --git a/html/en/drv/win32.html b/html/en/drv/win32.html index 86a3f4e..df0d902 100644 --- a/html/en/drv/win32.html +++ b/html/en/drv/win32.html @@ -37,9 +37,6 @@ using bitmaps.</li> <li><font face="Courier"><strong><a href="../func/lines.html#cdLine">Line</a></strong></font>: needs to draw an extra pixel in the final position.</li> - <li><a href="../func/lines.html#cdBegin"> - <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt>CD_PATH</tt></strong> - is supported.</li> </ul> <h4>Attributes </h4> <ul> diff --git a/html/en/drv/xrender.html b/html/en/drv/xrender.html index be85b8e..21d9a48 100644 --- a/html/en/drv/xrender.html +++ b/html/en/drv/xrender.html @@ -69,8 +69,8 @@ IRIX.</p> contain text regions.</li> <li><a href="../func/lines.html#cdBegin"> <font face="Courier"><strong>Begin</strong></font></a>: <strong><tt> - CD_BEZIER</tt></strong> is simulated with lines. - <strong><tt>CD_PATH</tt></strong> is supported.</li> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> <li><font face="Courier"><strong><a href="../func/lines.html#cdRect">Rect</a></strong></font>: simulated using the client's <strong>Line</strong>.</li> <li><font face="Courier"><a href="../func/lines.html#cdArc"><b>Arc</b></a></font>: @@ -80,7 +80,8 @@ IRIX.</p> <li><font face="Courier"><b><a href="../func/filled.html#cdChord">Chord</a></b></font>: simulated using the client's <strong>Poly</strong></li> <li><font face="Courier"><a href="../func/filled.html#cdBox"><b>Box</b></a></font>: - simulated using the client's <strong>Poly</strong>. </li> + simulated using the client's <strong>Poly</strong>.</li> + <li>Floating point primitives are supported.</li> </ul> <h4>Attributes </h4> <ul> diff --git a/html/en/drv/xwin.html b/html/en/drv/xwin.html index cd2d900..3049da9 100644 --- a/html/en/drv/xwin.html +++ b/html/en/drv/xwin.html @@ -47,7 +47,8 @@ <li><a href="../func/lines.html#cdBegin"> <font face="Courier"><strong>Begin</strong></font></a>: Filled polygons have an error of one pixel to the right and below. <strong><tt> - CD_BEZIER</tt></strong> is simulated with lines.</li> + CD_BEZIER</tt></strong> and <strong><tt>CD_PATH</tt></strong> + are simulated with lines.</li> <li><span class="style1"><a href="../func/marks.html#cdMark"> <strong>Box</strong></a></span>: in Linux with ATI board, is being drawn with one extra pixel to the right and below.</li> diff --git a/html/en/history.html b/html/en/history.html index 7325ce8..7740f27 100644 --- a/html/en/history.html +++ b/html/en/history.html @@ -25,7 +25,9 @@ <li><span style="color: #0000FF">New:</span> "CMD", "OPACITY" and "HATCHBOXSIZE" attributes in the SVG driver.</li> <li><span style="color: #0000FF">New:</span> CD_PATH <strong>cdCanvasBegin</strong> - mode in the SVG, PS, PDF, Cairo, Win32 and GDI+ drivers.</li> + mode to create a path composed of several primitives that can be line draw, + filled or used as clipping. New function <strong>cdCanvasPathSet</strong> to + configure the action between sequences of <strong>cdCanvasVertex</strong>.</li> <li><span class="style1">Changed</span><span class="hist_changed">:</span> CD_DXF now supports solid filled primitives for polygons and rectangles.</li> <li><span class="style1">Changed</span><span class="hist_changed">:</span> diff --git a/include/cd.h b/include/cd.h index 1dc90c0..fd8348b 100644 --- a/include/cd.h +++ b/include/cd.h @@ -19,9 +19,9 @@ extern "C" { #define CD_NAME "CD - Canvas Draw" #define CD_DESCRIPTION "A 2D Graphics Library" #define CD_COPYRIGHT "Copyright (C) 1994-2010 Tecgraf, PUC-Rio." -#define CD_VERSION "5.3" /* bug fixes are reported only by cdVersion functions */ -#define CD_VERSION_NUMBER 503000 -#define CD_VERSION_DATE "2010/01/26" /* does not include bug fix releases */ +#define CD_VERSION "5.4" /* bug fixes are reported only by cdVersion functions */ +#define CD_VERSION_NUMBER 504000 +#define CD_VERSION_DATE "2010/XX/XX" /* does not include bug fix releases */ typedef struct _cdContext cdContext; typedef struct _cdCanvas cdCanvas; @@ -425,6 +425,8 @@ enum { /* some font sizes */ #define CD_CAP_PALETTE 0x08000000 #define CD_CAP_LINECAP 0x10000000 #define CD_CAP_LINEJOIN 0x20000000 +#define CD_CAP_PATH 0x40000000 +#define CD_CAP_BEZIER 0x80000000 #define CD_CAP_ALL 0xFFFFFFFF /* cdPlay definitions */ diff --git a/include/cd_private.h b/include/cd_private.h index 742750e..d2fb66b 100644 --- a/include/cd_private.h +++ b/include/cd_private.h @@ -353,12 +353,14 @@ void cdgettextsizeSIM(cdCtxCanvas* ctxcanvas, const char *s, int len, int *width /* Simulation functions that are independent of the simulation base driver */ void cdSimMark(cdCanvas* canvas, int x, int y); void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n); +void cdSimPolyPath(cdCanvas* canvas, const cdPoint* points, int n); void cdSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax); /* Simulation functions that are independent of the simulation base driver, and does not checks for axis and matrix. All use the polygon method ->cxFPoly only. */ void cdfSimPolyBezier(cdCanvas* canvas, const cdfPoint* points, int n); +void cdfSimPolyPath(cdCanvas* canvas, const cdfPoint* points, int n); void cdfSimRect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax); void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax); void cdfSimElipse(cdCtxCanvas* ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2, int sector); 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; |