From 17be65cfea56a53dc3a9cb617895adf5300db099 Mon Sep 17 00:00:00 2001
From: scuri
Date: Tue, 1 Jun 2010 22:31:45 +0000
Subject: *** empty log message ***
---
html/en/func/filled.html | 24 +++---
html/en/func/lines.html | 22 +++---
html/en/func/polygon.html | 31 +++++---
include/cd_private.h | 23 +++---
src/cairo/cdcairo.c | 72 ++++++++++--------
src/cd.c | 4 +
src/cd.def | 6 ++
src/cd_primitives.c | 169 ++++++++++++++++++++++++++++++++---------
src/cd_util.c | 1 +
src/drv/cdirgb.c | 186 ++--------------------------------------------
src/drv/cdpdf.c | 28 +++----
src/drv/cdpicture.c | 12 +--
src/drv/cdps.c | 44 +++++------
src/gdiplus/cdwinp.cpp | 78 ++++++++-----------
src/gdk/cdgdk.c | 2 +-
src/sim/sim_primitives.c | 161 ++++++++++++++++++++++-----------------
src/svg/cdsvg.c | 57 +++++++++-----
src/win32/cdwin.c | 84 +++++++++++++--------
test/simple/simple.c | 20 +++--
19 files changed, 522 insertions(+), 502 deletions(-)
diff --git a/html/en/func/filled.html b/html/en/func/filled.html
index 2ae1083..97a2e84 100644
--- a/html/en/func/filled.html
+++ b/html/en/func/filled.html
@@ -63,25 +63,29 @@ canvas:fSector(xc, yc, w, h, angle1, angle2: number) [in Lua]
canvas:wSector(xc, yc, w, h, angle1, angle2: number) (WC) [in Lua]
Fills the arc of an ellipse aligned with the axis, according to the current
- interior style, in the shape of a pie. It is drawn counter-clockwise. The
+ interior style, in the shape of a pie.
+The
coordinate (xc,yc) defines the center of the ellipse.
Dimensions w and h define the elliptic axes X
and Y, respectively.
- Angles angle1 and angle2, in degrees,
- define the arc's beginning and end, but they are not the angle relative to the
+
Angles angle1 and angle2 are in degrees and oriented
+ counter-clockwise. They
+ define the arc start and end, but they are not the angle relative to the
center, except when w==h and the ellipse is reduced to a circle. The arc
- starts at the point (xc+(w/2)*cos(angle1),yc+(h/2)*sin(angle1))
- and ends at (xc+(w/2)*cos(angle2),yc+(h/2)*sin(angle2)). A
- complete ellipse can be drawn using 0 and 360 as the angles.
+ starts at the point (xc+(w/2)*cos(angle1), yc+(h/2)*sin(angle1))
+ and ends at (xc+(w/2)*cos(angle2), yc+(h/2)*sin(angle2)). A
+ complete ellipse can be drawn using 0 and 360 as the angles. If angle2
+ is less than angle1 it will be increased by 360 until it is greater
+ than angle1.
The angles are specified so if the size of the ellipse (w x h) is changed,
its shape is preserved. So the angles relative to the center are dependent
- from the ellipse size. The actual angle can be obtained using rangle =
- atan2((h/2)*sin(angle),(w/2)*cos(angle)).
- The angles are given in degrees. To specify the angle in radians, you can
+ from the ellipse size. The actual angle can be obtained using rangle =
+ atan2((h/2)*sin(angle), (w/2)*cos(angle)).
+ To specify the angle in radians, you can
use the definition CD_RAD2DEG
to multiply the value in radians before passing the angle to CD.
When the interior style CD_HOLLOW is defined,
- the function behaves like its equivalent cdArc,
+ the function behaves like its equivalent cdCanvasArc,
plus two lines connecting to the center.
Sector Parameters

diff --git a/html/en/func/lines.html b/html/en/func/lines.html
index b748391..6ba78d7 100644
--- a/html/en/func/lines.html
+++ b/html/en/func/lines.html
@@ -1,5 +1,5 @@
-
+
@@ -64,21 +64,25 @@ canvas:fArc(xc, yc, w, h, angle1, angle2: number) [in Lua]
canvas:wArc(xc, yc, w, h, angle1, angle2: number) (WC) [in Lua]
Draws the arc of an ellipse aligned with the axis, using the current
- foreground color and line width and style. It is drawn counter-clockwise. The
+ foreground color and line width and style.
+The
coordinate (xc,yc) defines the center of the ellipse.
Dimensions w and h define the elliptic axes X
and Y, respectively.
- Angles angle1 and angle2, in degrees define
- the arc's beginning and end, but they are not the angle relative to the
+
Angles angle1 and angle2 are in degrees and oriented
+ counter-clockwise. They define
+ the arc start and end, but they are not the angle relative to the
center, except when w==h and the ellipse is reduced to a circle. The arc
- starts at the point (xc+(w/2)*cos(angle1),yc+(h/2)*sin(angle1))
- and ends at (xc+(w/2)*cos(angle2),yc+(h/2)*sin(angle2)). A
- complete ellipse can be drawn using 0 and 360 as the angles.
+ starts at the point (xc+(w/2)*cos(angle1), yc+(h/2)*sin(angle1))
+ and ends at (xc+(w/2)*cos(angle2), yc+(h/2)*sin(angle2)). A
+ complete ellipse can be drawn using 0 and 360 as the angles. If angle2
+ is less than angle1 it will be increased by 360 until it is greater
+ than angle1.
The angles are specified so if the size of the ellipse (w x h) is changed,
its shape is preserved. So the angles relative to the center are dependent
from the ellipse size. The actual angle can be obtained using rangle =
- atan2((h/2)*sin(angle),(w/2)*cos(angle)).
- The angles are given in degrees. To specify the angle in radians, you can
+ atan2((h/2)*sin(angle), (w/2)*cos(angle)).
+ To specify the angle in radians, you can
use the definition CD_RAD2DEG
to multiply the value in radians before passing the angle to CD.
Arc Parameters
diff --git a/html/en/func/polygon.html b/html/en/func/polygon.html
index 3a0b9c0..c2acb9a 100644
--- a/html/en/func/polygon.html
+++ b/html/en/func/polygon.html
@@ -93,42 +93,43 @@ canvas:PathSet(action: number) [in Lua]
Configures the action between sequences of cdCanvasVertex.
action can be:
- - CD_PATH_NEW - creates a new empty path. Useful if more than one
+
- CD_PATH_NEW - creates a new empty path. Useful if more than one
path is configured. cdCanvasBegin(CD_PATH) already creates
a new path.
- - CD_PATH_MOVETO - moves the current position to the given coordinates.
+
- CD_PATH_MOVETO - moves the current position to the given coordinates.
Must be followed by 1 call to cdCanvasVertex,
cdfCanvasVertex, or wdCanvasVertex.
- - CD_PATH_LINETO - adds a line to the path from the current position to
+
- CD_PATH_LINETO - adds a line to the path from the current position to
the given coordinates. The current position is updated to the given
coordinates. If there is no current position, nothing is connected and only
the current position is updated. Must be followed by 1 call to
cdCanvasVertex, cdfCanvasVertex, or
wdCanvasVertex.
- - CD_PATH_ARC - adds an arc to the path. If there is a current position
+
- CD_PATH_ARC - adds an arc to the path. If there is a current position
adds also a line from the current position to the start of the arc. The end
of the arc becomes the current position. Must be followed by 3 calls to
cdCanvasVertex, cdfCanvasVertex, or
wdCanvasVertex. One for the center of the arc (xc,yc), one
for the bounding rectangle size (w,h), and one for the start and end angles
- (angle1,angle2). Angles are in degrees. When using integer coordinates
+ (angle1,angle2). Angles are in degrees and oriented counter-clockwise, but
+ angle2 can be smaller than angle1 to describe a clockwise arc. When using integer coordinates
angles must be multiplied by 1000.
- - CD_PATH_CURVETO - adds a bezier curve to the path. If there is no
+
- CD_PATH_CURVETO - adds a bezier curve to the path. If there is no
current position, the first point will be used twice. The end point becomes
the current position. Must be followed by 3 calls to cdCanvasVertex,
cdfCanvasVertex, or wdCanvasVertex. Must
be first control point (x1,y1) + second control point (x2,y2) + end point
(x3,y3).
- - CD_PATH_CLOSE - adds a line to the path that connects the last point
+
- CD_PATH_CLOSE - adds a line to the path that connects the last point
with the first point of the path, closing it.
- - CD_PATH_FILL - fills the path with the current fill attributes,
+
- CD_PATH_FILL - fills the path with the current fill attributes,
then the path is discarded.
- - CD_PATH_STROKE - strokes the path with the current line attributes, then the
+
- CD_PATH_STROKE - strokes the path with the current line attributes, then the
path is discarded.
- - CD_PATH_FILLSTROKE - fills the path with the current fill
+
- CD_PATH_FILLSTROKE - fills the path with the current fill
attributes, strokes the path with the current line attributes, then the path
is discarded.
- - CD_PATH_CLIP - use the path as a clipping area to be
+
- CD_PATH_CLIP - use the path as a clipping area to be
intersected with the current clipping area, then the path is discarded.
@@ -139,6 +140,14 @@ cdCanvasPathSet(canvas, CD_PATH_MOVETO);
cdCanvasVertex(canvas, x1, y1);
cdCanvasPathSet(canvas, CD_PATH_LINETO);
cdCanvasVertex(canvas, x2, y2);
+cdCanvasPathSet(canvas, CD_PATH_CURVETO);
+cdCanvasVertex(canvas, x3, y3); /* control point for start point */
+cdCanvasVertex(canvas, x4, y4); /* control point for end point */
+cdCanvasVertex(canvas, x5, y5); /* end point */
+cdCanvasPathSet(canvas, CD_PATH_ARC);
+cdCanvasVertex(canvas, x6, y6); /* center */
+cdCanvasVertex(canvas, x7, y7); /* width, height */
+cdCanvasVertex(canvas, x8, y8); /* start angle, end angle (degrees / 1000) */
cdCanvasPathSet(canvas, CD_PATH_STROKE);
cdCanvasEnd(canvas);
diff --git a/include/cd_private.h b/include/cd_private.h
index 28b92d8..1410126 100644
--- a/include/cd_private.h
+++ b/include/cd_private.h
@@ -222,7 +222,6 @@ struct _cdCanvas
/* simulation flags */
int sim_mode;
- int sim_poly;
/* WC */
double s, sx, tx, sy, ty; /* Transformacao Window -> Viewport (scale+translation)*/
@@ -269,7 +268,6 @@ enum{CD_CTX_NATIVEWINDOW, CD_CTX_IMAGE, CD_CTX_DBUFFER, CD_CTX_PRINTER, CD_CTX_E
/* utilities */
/*************/
int cdRound(double x);
-void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax);
int cdCheckBoxSize(int *xmin, int *xmax, int *ymin, int *ymax);
int cdfCheckBoxSize(double *xmin, double *xmax, double *ymin, double *ymax);
void cdNormalizeLimits(int w, int h, int *xmin, int *xmax, int *ymin, int *ymax);
@@ -280,6 +278,14 @@ char* cdStrDup(const char* str);
char* cdStrDupN(const char* str, int len);
void cdSetPaperSize(int size, double *w_pt, double *h_pt);
+void cdCanvasPoly(cdCanvas* canvas, int mode, cdPoint* points, int n);
+void cdCanvasGetArcBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax);
+int cdCanvasGetArcPathF(cdCanvas* canvas, const cdPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2);
+int cdfCanvasGetArcPath(cdCanvas* canvas, const cdfPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2);
+int cdCanvasGetArcPath(cdCanvas* canvas, const cdPoint* poly, int *xc, int *yc, int *w, int *h, double *a1, double *a2);
+void cdCanvasGetArcStartEnd(int xc, int yc, int w, int h, double a1, double a2, int *x1, int *y1, int *x2, int *y2);
+void cdfCanvasGetArcStartEnd(double xc, double yc, double w, double h, double a1, double a2, double *x1, double *y1, double *x2, double *y2);
+
#define _cdCheckCanvas(_canvas) (_canvas!=NULL && ((unsigned char*)_canvas)[0] == 'C' && ((unsigned char*)_canvas)[1] == 'D')
#define _cdInvertYAxis(_canvas, _y) (_canvas->h - (_y) - 1)
#define _cdSwapInt(_a,_b) {int _c=_a;_a=_b;_b=_c;}
@@ -351,11 +357,6 @@ void cdSimGetTextSizeFT(cdCtxCanvas* ctxcanvas, const char *s, int len, int *wid
/* sim_primitives.c */
-/* Simulation functions that depend on the simulation base driver. */
-void cdSimPolyFill(cdCanvas* canvas, cdPoint* poly, int n);
-void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n);
-void cdfSimPolyLine(cdCanvas* canvas, const cdfPoint* poly, int n);
-
/* Simulation functions that are >> independent << of the simulation base driver. */
void cdSimMark(cdCanvas* canvas, int x, int y);
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);
@@ -368,6 +369,8 @@ void cdSimBox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax);
void cdSimArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2);
void cdSimSector(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2);
void cdSimChord(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2);
+void cdSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* points, int n);
+
void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n);
void cdSimPolyPath(cdCanvas* canvas, const cdPoint* points, int n);
@@ -379,13 +382,11 @@ void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, do
void cdfSimArc(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2);
void cdfSimSector(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2);
void cdfSimChord(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2);
+void cdfSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n);
+
void cdfSimPolyBezier(cdCanvas* canvas, const cdfPoint* points, int n);
void cdfSimPolyPath(cdCanvas* canvas, const cdfPoint* points, int n);
-/* Utilities */
-void cdSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* points, int n);
-int cdSimCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height);
-
#ifdef __cplusplus
}
diff --git a/src/cairo/cdcairo.c b/src/cairo/cdcairo.c
index 55f8b51..9589d74 100644
--- a/src/cairo/cdcairo.c
+++ b/src/cairo/cdcairo.c
@@ -592,24 +592,28 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
cdfline(ctxcanvas, (double)x1, (double)y1, (double)x2, (double)y2);
}
-static void sFixAngles(cdCtxCanvas* ctxcanvas, double *a1, double *a2)
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2, int swap)
{
- if (ctxcanvas->canvas->invert_yaxis)
- {
- double t;
+ /* Cairo angles are clock-wise by default, in radians */
+
+ /* if NOT inverted means a transformation is set,
+ so the angle will follow the transformation that includes the axis invertion,
+ then it is already counter-clockwise */
- /* Cairo angles are clock-wise by default */
+ if (canvas->invert_yaxis)
+ {
+ /* change orientation */
*a1 *= -1;
*a2 *= -1;
/* swap, so the start angle is the smaller */
- t = *a1;
- *a1 = *a2;
- *a2 = t;
+ if (swap)
+ {
+ double t = *a1;
+ *a1 = *a2;
+ *a2 = t;
+ }
}
- /* if NOT inverted means a transformation is set,
- so the angle will follow the transformation that includes the axis invertion,
- then it is counter-clockwise */
/* convert to radians */
*a1 *= CD_DEG2RAD;
@@ -620,7 +624,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
{
sUpdateFill(ctxcanvas, 0);
- sFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
if (w == h)
{
@@ -651,7 +655,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
{
sUpdateFill(ctxcanvas, 1);
- sFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
if (w == h)
{
@@ -685,7 +689,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
{
sUpdateFill(ctxcanvas, 1);
- sFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
if (w == h)
{
@@ -883,18 +887,17 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
if (i+3 > n) return;
- 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 (!cdCanvasGetArcPathF(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
- sFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 0); /* do not swap because we handle negative arcs here */
if (w == h)
{
- cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
}
else /* Ellipse: change the scale to create from the circle */
{
@@ -904,7 +907,10 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
cairo_scale(ctxcanvas->cr, w/h, 1.0);
cairo_translate(ctxcanvas->cr, -xc, -yc);
- cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
cairo_restore(ctxcanvas->cr); /* restore from local */
}
@@ -1036,18 +1042,17 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
if (i+3 > n) return;
- xc = poly[i].x,
- yc = poly[i].y,
- w = poly[i+1].x,
- h = poly[i+1].y,
- a1 = poly[i+2].x,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
- sFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 0); /* do not swap because we handle negative arcs here */
if (w == h)
{
- cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
}
else /* Ellipse: change the scale to create from the circle */
{
@@ -1057,7 +1062,10 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
cairo_scale(ctxcanvas->cr, w/h, 1.0);
cairo_translate(ctxcanvas->cr, -xc, -yc);
- cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
cairo_restore(ctxcanvas->cr); /* restore from local */
}
diff --git a/src/cd.c b/src/cd.c
index 1c64def..13d2541 100644
--- a/src/cd.c
+++ b/src/cd.c
@@ -327,7 +327,11 @@ int cdCanvasSimulate(cdCanvas* canvas, int mode)
canvas->cxFont(canvas->ctxcanvas, canvas->font_type_face, canvas->font_style, canvas->font_size);
if (mode & CD_SIM_POLYLINE || mode & CD_SIM_POLYGON)
+ {
+ /* can NOT replace canvas->cxPoly because it will be used by the simulation,
+ handle polygon simulation in Begin/End */
canvas->cxFPoly = NULL;
+ }
return sim_mode;
}
diff --git a/src/cd.def b/src/cd.def
index eda5beb..da6938c 100644
--- a/src/cd.def
+++ b/src/cd.def
@@ -220,6 +220,12 @@ EXPORTS
cdGetFontSizePoints
cdStrEqualNoCase
cdSetPaperSize
+ cdCanvasGetArcPath
+ cdfCanvasGetArcPath
+ cdCanvasGetArcPathF
+ cdCanvasGetArcBox
+ cdCanvasGetArcStartEnd
+ cdfCanvasGetArcStartEnd
wdCanvasLineWidth
wdCanvasMarkSize
diff --git a/src/cd_primitives.c b/src/cd_primitives.c
index ca6ad6d..8714e70 100644
--- a/src/cd_primitives.c
+++ b/src/cd_primitives.c
@@ -136,20 +136,9 @@ void cdCanvasBegin(cdCanvas* canvas, int mode)
return;
}
- canvas->sim_poly = 0;
-
if (canvas->interior_style == CD_HOLLOW && mode == CD_FILL)
mode = CD_CLOSED_LINES;
- /* simulacao de linhas */
- if ((mode == CD_CLOSED_LINES || mode == CD_OPEN_LINES || mode == CD_BEZIER) &&
- canvas->sim_mode & CD_SIM_POLYLINE)
- canvas->sim_poly = 1;
-
- /* simulacao de poligonos preenchidos */
- if (mode == CD_FILL && canvas->sim_mode & CD_SIM_POLYGON)
- canvas->sim_poly = 1;
-
canvas->poly_mode = mode;
}
@@ -182,7 +171,7 @@ void cdCanvasVertex(cdCanvas* canvas, int x, int y)
canvas->poly = (cdPoint*)realloc(canvas->poly, sizeof(cdPoint) * (canvas->poly_size+1));
}
- if (canvas->poly_mode != CD_BEZIER &&
+ if (canvas->poly_mode != CD_BEZIER && canvas->poly_mode != CD_PATH &&
canvas->poly_n > 0 &&
canvas->poly[canvas->poly_n-1].x == x &&
canvas->poly[canvas->poly_n-1].y == y)
@@ -258,6 +247,27 @@ void cdCanvasPathSet(cdCanvas* canvas, int action)
canvas->path_n++;
}
+void cdCanvasPoly(cdCanvas* canvas, int mode, cdPoint* points, int n)
+{
+ int sim_poly = 0;
+
+ /* simulacao de linhas */
+ if ((mode == CD_CLOSED_LINES || mode == CD_OPEN_LINES ||
+ mode == CD_BEZIER || mode == CD_PATH) &&
+ canvas->sim_mode & CD_SIM_POLYLINE)
+ sim_poly = 1;
+
+ /* simulacao de poligonos preenchidos */
+ if ((mode == CD_FILL || mode == CD_PATH) &&
+ canvas->sim_mode & CD_SIM_POLYGON)
+ sim_poly = 1;
+
+ if (sim_poly)
+ cdSimPoly(canvas->ctxcanvas, mode, points, n);
+ else
+ canvas->cxPoly(canvas->ctxcanvas, mode, points, n);
+}
+
void cdCanvasEnd(cdCanvas* canvas)
{
assert(canvas);
@@ -297,15 +307,10 @@ void cdCanvasEnd(cdCanvas* canvas)
return;
}
- if (canvas->sim_poly)
- cdSimPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
+ if (canvas->use_fpoly)
+ canvas->cxFPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->fpoly, canvas->poly_n);
else
- {
- if (canvas->use_fpoly)
- canvas->cxFPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->fpoly, canvas->poly_n);
- else
- canvas->cxPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
- }
+ cdCanvasPoly(canvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
if (canvas->poly_mode == CD_CLIP)
{
@@ -462,7 +467,7 @@ void cdfCanvasBox(cdCanvas* canvas, double xmin, double xmax, double ymin, doubl
canvas->cxBox(canvas->ctxcanvas, _cdRound(xmin), _cdRound(xmax), _cdRound(ymin), _cdRound(ymax));
}
-static void normAngles(double *angle1, double *angle2)
+static void sNormAngles(double *angle1, double *angle2)
{
*angle1 = fmod(*angle1,360);
*angle2 = fmod(*angle2,360);
@@ -477,7 +482,7 @@ void cdCanvasArc(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->use_origin)
{
@@ -499,7 +504,7 @@ void cdfCanvasArc(cdCanvas* canvas, double xc, double yc, double w, double h, do
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->use_origin)
{
@@ -525,7 +530,7 @@ void cdCanvasSector(cdCanvas* canvas, int xc, int yc, int w, int h, double angle
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -568,7 +573,7 @@ void cdfCanvasSector(cdCanvas* canvas, double xc, double yc, double w, double h,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -614,7 +619,7 @@ void cdCanvasChord(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -654,7 +659,7 @@ void cdfCanvasChord(cdCanvas* canvas, double xc, double yc, double w, double h,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -689,23 +694,43 @@ void cdfCanvasChord(cdCanvas* canvas, double xc, double yc, double w, double h,
canvas->cxChord(canvas->ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), angle1, angle2);
}
-void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax)
+void cdCanvasGetArcStartEnd(int xc, int yc, int w, int h, double a1, double a2, int *x1, int *y1, int *x2, int *y2)
{
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
+ /* leave xc and yc outside the round, so the center will be always the same */
+
+ if (x1) *x1 = xc + cdRound((w/2.0)*cos(a1*CD_DEG2RAD));
+ if (y1) *y1 = yc + cdRound((h/2.0)*sin(a1*CD_DEG2RAD));
+ if (x2) *x2 = xc + cdRound((w/2.0)*cos(a2*CD_DEG2RAD));
+ if (y2) *y2 = yc + cdRound((h/2.0)*sin(a2*CD_DEG2RAD));
+}
+
+void cdfCanvasGetArcStartEnd(double xc, double yc, double w, double h, double a1, double a2, double *x1, double *y1, double *x2, double *y2)
+{
+ if (x1) *x1 = xc + (w/2.0)*cos(a1*CD_DEG2RAD);
+ if (y1) *y1 = yc + (h/2.0)*sin(a1*CD_DEG2RAD);
+ if (x2) *x2 = xc + (w/2.0)*cos(a2*CD_DEG2RAD);
+ if (y2) *y2 = yc + (h/2.0)*sin(a2*CD_DEG2RAD);
+}
+
+void cdCanvasGetArcBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax)
+{
+ int x, y;
+
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
#define _BBOX() \
if (x > *xmax) *xmax = x; \
if (y > *ymax) *ymax = y; \
if (x < *xmin) *xmin = x; \
if (y < *ymin) *ymin = y;
- int x, y;
-
- *xmin = (int)(xc+w/2*cos(a1*CD_DEG2RAD));
- *ymin = (int)(yc+h/2*sin(a1*CD_DEG2RAD));
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, xmin, ymin, &x, &y);
*xmax = *xmin;
*ymax = *ymin;
-
- x = (int)(xc+w/2*cos(a2*CD_DEG2RAD));
- y = (int)(yc+h/2*sin(a2*CD_DEG2RAD));
_BBOX()
if (a1 > a2)
@@ -733,3 +758,77 @@ void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, i
_BBOX()
}
}
+
+int cdCanvasGetArcPath(cdCanvas* canvas, const cdPoint* poly, int *xc, int *yc, int *w, int *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ /* fix integer scale */
+ *a1 /= 1000.0;
+ *a2 /= 1000.0;
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1a2) */
+ return 1;
+}
+
+int cdfCanvasGetArcPath(cdCanvas* canvas, const cdfPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1a2) */
+ return 1;
+}
+
+int cdCanvasGetArcPathF(cdCanvas* canvas, const cdPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ /* fix integer scale */
+ *a1 /= 1000.0;
+ *a2 /= 1000.0;
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1a2) */
+ return 1;
+}
diff --git a/src/cd_util.c b/src/cd_util.c
index 39d491d..b278dfc 100644
--- a/src/cd_util.c
+++ b/src/cd_util.c
@@ -397,3 +397,4 @@ void cdSetPaperSize(int size, double *w_pt, double *h_pt)
*w_pt = (double)paper[size].w_pt;
*h_pt = (double)paper[size].h_pt;
}
+
diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c
index e6cb4b5..9f367e0 100644
--- a/src/drv/cdirgb.c
+++ b/src/drv/cdirgb.c
@@ -580,7 +580,7 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
memcpy(t_poly, poly, sizeof(cdPoint)*n);
poly = t_poly;
- for(i = 0; i < n; i++)
+ for(i = 0; i < n; i++) /* must duplicate because clip poly is stored */
cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
}
@@ -642,79 +642,6 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
irgPostProcessIntersect(ctxcanvas->clip_region, ctxcanvas->canvas->w * ctxcanvas->canvas->h);
}
-static void irgbClipElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2, int sector)
-{
- float c, s, sx, sy, x, y, prev_x, prev_y;
- double da;
- int i, p;
- cdPoint* poly;
-
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = cdSimCalcEllipseNumSegments(ctxcanvas->canvas, xc, yc, width, height);
-
- /* number of segments for the arc */
- n = cdRound((fabs(angle2-angle1)*n)/360);
- if (n < 1) n = 1;
-
- poly = (cdPoint*)malloc(sizeof(cdPoint)*(n+2+1)); /* n+1 points +1 center */
-
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
-
- /* generates arc points at origin with axis x and y */
-
- da = (angle2-angle1)/n;
- c = (float)cos(da);
- s = (float)sin(da);
- sx = -(width*s)/height;
- sy = (height*s)/width;
-
- x = xc + (width/2.0f)*(float)cos(angle1);
- y = yc + (height/2.0f)*(float)sin(angle1);
- poly[0].x = _cdRound(x);
- poly[0].y = _cdRound(y);
- prev_x = x;
- prev_y = y;
- p = 1;
-
- for (i = 1; i < n+1; i++) /* n+1 points */
- {
- x = xc + c*(prev_x-xc) + sx*(prev_y-yc);
- y = yc + sy*(prev_x-xc) + c*(prev_y-yc);
-
- poly[p].x = _cdRound(x);
- poly[p].y = _cdRound(y);
-
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
-
- prev_x = x;
- prev_y = y;
- }
-
- if (poly[p-1].x != poly[0].x || poly[p-1].y != poly[0].y)
- {
- if (sector) /* cdSector */
- {
- /* add center */
- poly[p].x = xc;
- poly[p].y = yc;
- }
- else /* cdChord */
- {
- /* add initial point */
- poly[p].x = poly[0].x;
- poly[p].y = poly[0].y;
- }
- p++;
- }
-
- irgbClipPoly(ctxcanvas, ctxcanvas->clip_region, poly, p, ctxcanvas->canvas->combine_mode);
-
- free(poly);
-}
-
static void irgbClipBox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
int combine_mode = ctxcanvas->canvas->combine_mode;
@@ -952,54 +879,6 @@ static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin
cdfSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
}
-static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- /* matrix transformation is done inside irgbClip* if necessary */
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 1);
- return;
- }
-
- cdSimSector(ctxcanvas, xc, yc, w, h, a1, a2);
-}
-
-static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- /* matrix transformation is done inside irgbClip* if necessary */
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 0);
- return;
- }
-
- cdSimChord(ctxcanvas, xc, yc, w, h, a1, a2);
-}
-
-static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- /* matrix transformation is done inside irgbClip* if necessary */
- irgbClipElipse(ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, 1);
- return;
- }
-
- cdfSimSector(ctxcanvas, xc, yc, w, h, a1, a2);
-}
-
-static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- /* matrix transformation is done inside irgbClip* if necessary */
- irgbClipElipse(ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, 0);
- return;
- }
-
- cdfSimChord(ctxcanvas, xc, yc, w, h, a1, a2);
-}
-
static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
{
if (ctxcanvas->canvas->new_region)
@@ -1035,59 +914,6 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
cdSimPoly(ctxcanvas, mode, poly, n);
}
-static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
-{
- int i;
-
- switch(mode)
- {
- case CD_CLOSED_LINES:
- fpoly[n] = fpoly[0];
- n++;
- /* continue */
- case CD_OPEN_LINES:
- cdfSimPolyLine(ctxcanvas->canvas, fpoly, n);
- break;
- case CD_BEZIER:
- cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
- break;
- case CD_PATH:
- cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
- break;
- case CD_FILL:
- {
- cdPoint* poly = malloc(sizeof(cdPoint)*n);
-
- for (i = 0; icanvas->clip_mode == CD_CLIPPOLYGON) cdclip(ctxcanvas, CD_CLIPPOLYGON);
- }
- break;
- }
-}
-
static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)
{
int dst_offset, src_offset, l, xsize, ysize, xpos, ypos;
@@ -2031,8 +1857,8 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxRect = cdSimRect;
canvas->cxBox = cdbox;
canvas->cxArc = cdSimArc;
- canvas->cxSector = cdsector;
- canvas->cxChord = cdchord;
+ canvas->cxSector = cdSimSector;
+ canvas->cxChord = cdSimChord;
canvas->cxPoly = cdpoly;
canvas->cxText = cdtext;
@@ -2040,9 +1866,9 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFRect = cdfSimRect;
canvas->cxFBox = cdfbox;
canvas->cxFArc = cdfSimArc;
- canvas->cxFSector = cdfsector;
- canvas->cxFChord = cdfchord;
- canvas->cxFPoly = cdfpoly;
+ canvas->cxFSector = cdfSimSector;
+ canvas->cxFChord = cdfSimChord;
+ canvas->cxFPoly = cdfSimPoly;
canvas->cxKillCanvas = cdkillcanvas;
diff --git a/src/drv/cdpdf.c b/src/drv/cdpdf.c
index 2c48d50..f6621d3 100644
--- a/src/drv/cdpdf.c
+++ b/src/drv/cdpdf.c
@@ -570,15 +570,16 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
if (i+3 > n) return;
- 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 (!cdCanvasGetArcPathF(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
if (w==h)
- PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ {
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ }
else /* Ellipse: change the scale to create from the circle */
{
PDF_save(ctxcanvas->pdf); /* save to use the local transform */
@@ -587,7 +588,10 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
PDF_scale(ctxcanvas->pdf, w/h, 1);
PDF_translate(ctxcanvas->pdf, -xc, -yc);
- PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
PDF_restore(ctxcanvas->pdf); /* restore from local */
}
@@ -716,12 +720,8 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
if (i+3 > n) return;
- xc = poly[i].x,
- yc = poly[i].y,
- w = poly[i+1].x,
- h = poly[i+1].y,
- a1 = poly[i+2].x,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
if (w==h)
PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
diff --git a/src/drv/cdpicture.c b/src/drv/cdpicture.c
index f1d089a..4cbc5d5 100644
--- a/src/drv/cdpicture.c
+++ b/src/drv/cdpicture.c
@@ -508,7 +508,7 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width);
picUpdateBBox(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width);
}
@@ -525,7 +525,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width);
picUpdateBBox(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width);
}
@@ -542,7 +542,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
picUpdateBBox(ctxcanvas, xc, yc, 0);
@@ -560,7 +560,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
picUpdateBBox(ctxcanvas, _cdRound(xc), _cdRound(yc), 0);
@@ -578,7 +578,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
}
@@ -595,7 +595,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
}
diff --git a/src/drv/cdps.c b/src/drv/cdps.c
index b651994..357abf4 100644
--- a/src/drv/cdps.c
+++ b/src/drv/cdps.c
@@ -648,7 +648,7 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -680,7 +680,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -720,7 +720,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
bbox(ctxcanvas, xc, yc);
@@ -761,7 +761,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
fbbox(ctxcanvas, xc, yc);
@@ -800,7 +800,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -838,7 +838,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -1110,19 +1110,19 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
case CD_PATH_ARC:
{
double xc, yc, w, h, a1, a2;
+ char* arc = "arc";
if (i+3 > n) return;
- 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 (!cdCanvasGetArcPathF(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if ((a2-a1)<0)
+ arc = "arcn";
if (w==h) /* Circulo: PS implementa direto */
{
- fprintf(ctxcanvas->file, "N %d %d %g %g %g arc\n", xc, yc, 0.5*w, a1, a2);
+ fprintf(ctxcanvas->file, "N %d %d %g %g %g %s\n", xc, yc, 0.5*w, a1, a2, arc);
}
else /* Elipse: mudar a escala p/ criar a partir do circulo */
{
@@ -1130,7 +1130,7 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
fprintf(ctxcanvas->file, "%d %d translate\n", xc, yc);
fprintf(ctxcanvas->file, "1 %g scale\n", ((double)h)/w);
fprintf(ctxcanvas->file, "N\n");
- fprintf(ctxcanvas->file, "0 0 %g %g %g arc\n", 0.5*w, a1, a2);
+ fprintf(ctxcanvas->file, "0 0 %g %g %g %s\n", 0.5*w, a1, a2, arc);
fprintf(ctxcanvas->file, "setmatrix\n"); /* back to CTM */
}
@@ -1303,19 +1303,19 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
case CD_PATH_ARC:
{
double xc, yc, w, h, a1, a2;
+ char* arc = "arc";
if (i+3 > n) return;
- xc = poly[i].x,
- yc = poly[i].y,
- w = poly[i+1].x,
- h = poly[i+1].y,
- a1 = poly[i+2].x,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if ((a2-a1)<0)
+ arc = "arcn";
if (w==h) /* Circulo: PS implementa direto */
{
- fprintf(ctxcanvas->file, "N %g %g %g %g %g arc\n", xc, yc, 0.5*w, a1, a2);
+ fprintf(ctxcanvas->file, "N %g %g %g %g %g %s\n", xc, yc, 0.5*w, a1, a2, arc);
}
else /* Elipse: mudar a escala p/ criar a partir do circulo */
{
@@ -1323,7 +1323,7 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
fprintf(ctxcanvas->file, "%g %g translate\n", xc, yc);
fprintf(ctxcanvas->file, "1 %g scale\n", ((double)h)/w);
fprintf(ctxcanvas->file, "N\n");
- fprintf(ctxcanvas->file, "0 0 %g %g %g arc\n", 0.5*w, a1, a2);
+ fprintf(ctxcanvas->file, "0 0 %g %g %g %s\n", 0.5*w, a1, a2, arc);
fprintf(ctxcanvas->file, "setmatrix\n"); /* back to CTM */
}
diff --git a/src/gdiplus/cdwinp.cpp b/src/gdiplus/cdwinp.cpp
index a2eec55..52c19a1 100644
--- a/src/gdiplus/cdwinp.cpp
+++ b/src/gdiplus/cdwinp.cpp
@@ -626,15 +626,21 @@ static void cdfbox(cdCtxCanvas* ctxcanvas, double xmin, double xmax, double ymin
}
}
-static void cdwpFixAngles(cdCtxCanvas* ctxcanvas, double *angle1, double *angle2)
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2)
{
- if (ctxcanvas->canvas->invert_yaxis)
+ // GDI+ angles are clock-wise by default, in degrees
+
+ /* if NOT inverted means a transformation is set,
+ so the angle will follow the transformation that includes the axis invertion,
+ then it is already counter-clockwise */
+
+ if (canvas->invert_yaxis)
{
- // GDI+ angles are clock-wise by default, in degrees
- *angle1 *= -1;
- *angle2 *= -1;
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
- // no need to swap, because we will use (angle2-angle1)
+ /* no need to swap, because we will use (angle2-angle1) */
}
}
@@ -645,7 +651,7 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
ctxcanvas->dirty = 1;
@@ -658,7 +664,7 @@ static void cdfarc(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, doubl
ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
ctxcanvas->dirty = 1;
@@ -674,7 +680,7 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
}
Region region(&path);
@@ -692,7 +698,7 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
}
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
@@ -710,7 +716,7 @@ static void cdfsector(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, do
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
}
Region region(&path);
@@ -728,7 +734,7 @@ static void cdfsector(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, do
}
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
@@ -746,7 +752,7 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
path.CloseFigure();
}
@@ -760,7 +766,7 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
else
{
GraphicsPath path;
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
}
@@ -780,7 +786,7 @@ static void cdfchord(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, dou
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
path.CloseFigure();
}
@@ -794,7 +800,7 @@ static void cdfchord(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, dou
else
{
GraphicsPath path;
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
}
@@ -850,27 +856,17 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
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 (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
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);
- }
+ cdCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
else
- {
- StartX = xc + cdRound(w * cos(CD_DEG2RAD * a2) / 2.0);
- StartY = yc + cdRound(h * sin(CD_DEG2RAD * a2) / 2.0);
- }
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
graphics_path->AddLine(current_x, current_y, StartX, StartY);
}
@@ -880,7 +876,7 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
graphics_path->AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
}
@@ -1084,27 +1080,17 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
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,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
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;
- }
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
else
- {
- StartX = xc + w * cos(CD_DEG2RAD * a2) / 2.0;
- StartY = yc + h * sin(CD_DEG2RAD * a2) / 2.0;
- }
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)StartX, (REAL)StartY);
}
@@ -1114,7 +1100,7 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
graphics_path->AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &a1, &a2);
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
}
diff --git a/src/gdk/cdgdk.c b/src/gdk/cdgdk.c
index 56055a7..d5236c7 100644
--- a/src/gdk/cdgdk.c
+++ b/src/gdk/cdgdk.c
@@ -890,7 +890,7 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
int i;
- if (mode != CD_BEZIER)
+ if (mode != CD_BEZIER && mode != CD_PATH)
{
for (i = 0; i < n; i++)
{
diff --git a/src/sim/sim_primitives.c b/src/sim/sim_primitives.c
index 9470b21..4b3ebf3 100644
--- a/src/sim/sim_primitives.c
+++ b/src/sim/sim_primitives.c
@@ -19,7 +19,7 @@ void cdSimLine(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
cdPoint poly[2];
poly[0].x = x1; poly[0].y = y1;
poly[1].x = x2; poly[1].y = y2;
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, 2);
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, 2);
}
void cdfSimLine(cdCtxCanvas* ctxcanvas, double x1, double y1, double x2, double y2)
@@ -39,7 +39,7 @@ void cdSimRect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
poly[1].x = xmin; poly[1].y = ymax;
poly[2].x = xmax; poly[2].y = ymax;
poly[3].x = xmax; poly[3].y = ymin;
- canvas->cxPoly(canvas->ctxcanvas, CD_CLOSED_LINES, poly, 4);
+ cdCanvasPoly(canvas, CD_CLOSED_LINES, poly, 4);
}
void cdfSimRect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
@@ -62,7 +62,7 @@ void cdSimBox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
poly[1].x = xmin; poly[1].y = ymax;
poly[2].x = xmax; poly[2].y = ymax;
poly[3].x = xmax; poly[3].y = ymin;
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
+ cdCanvasPoly(canvas, CD_FILL, poly, 4);
}
void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
@@ -77,9 +77,9 @@ void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, do
canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
}
-int cdSimCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height)
+static int sCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height, double angle1, double angle2)
{
- int n, dx, dy, hd;
+ int K, dx, dy, hd;
int w2 = width/2;
int h2 = height/2;
int x1 = xc-w2,
@@ -93,6 +93,8 @@ int cdSimCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int
cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
}
+ /* first calculate the number of segments of equivalent poligonal for a full ellipse */
+
dx = (x1-x2);
dy = (y1-y2);
hd = (int)(sqrt(dx*dx + dy*dy)/2);
@@ -104,40 +106,39 @@ int cdSimCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int
The number of segments will be 360 / min_angle.
*/
- n = (int)((360.0*CD_DEG2RAD) / acos((double)hd / (hd + 1.0)) + 0.5); /* round up */
+ K = (int)((360.0*CD_DEG2RAD) / acos((double)hd / (hd + 1.0)) + 0.5); /* round up */
/* multiple of 4 */
- n = ((n + 3)/4)*4;
+ K = ((K + 3)/4)*4;
/* minimum number is 4 */
- if (n < 4) n = 4;
+ if (K < 4) K = 4;
+
+
+ /* finally, calculate the number of segments for the arc */
+ K = cdRound((fabs(angle2-angle1)*K)/(360*CD_DEG2RAD));
+ if (K < 1) K = 1;
- return n;
+ return K;
}
-static void sFixAngles(cdCanvas* canvas, double *angle1, double *angle2)
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2)
{
+ /* computation in PolyAddArc is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
if (canvas->invert_yaxis)
{
- double t;
-
- /* computation is done as if the angles are counterclockwise,
- and yaxis is NOT inverted. */
-
- /* if yaxis is inverted then must orient clockwise */
- /* change angle orientation */
- *angle1 = 360 - *angle1;
- *angle2 = 360 - *angle2;
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
- /* swap, so the start angle is the smaller */
- t = *angle1;
- *angle1 = *angle2;
- *angle2 = t;
+ /* no need to swap, because we will use (angle2-angle1) */
}
/* convert to radians */
- *angle1 *= CD_DEG2RAD;
- *angle2 *= CD_DEG2RAD;
+ *a1 *= CD_DEG2RAD;
+ *a2 *= CD_DEG2RAD;
}
static cdPoint* sPolyAddArc(cdCanvas* canvas, cdPoint* poly, int *n, int xc, int yc, int width, int height, double angle1, double angle2, cdPoint* current)
@@ -147,14 +148,10 @@ static cdPoint* sPolyAddArc(cdCanvas* canvas, cdPoint* poly, int *n, int xc, int
int i, K, k, p, new_n;
cdPoint* old_poly = poly;
- /* number of segments of equivalent poligonal for a full ellipse */
- K = cdSimCalcEllipseNumSegments(canvas, xc, yc, width, height);
-
sFixAngles(canvas, &angle1, &angle2);
/* number of segments for the arc */
- K = cdRound((fabs(angle2-angle1)*K)/(360*CD_DEG2RAD));
- if (K < 1) K = 1;
+ K = sCalcEllipseNumSegments(canvas, xc, yc, width, height, angle1, angle2);
new_n = *n + K+1; /* add room for K+1 samples */
poly = (cdPoint*)realloc(poly, sizeof(cdPoint)*(new_n+2)); /* add room also for points at start and end */
@@ -208,17 +205,13 @@ static cdPoint* sPolyAddArc(cdCanvas* canvas, cdPoint* poly, int *n, int xc, int
static cdfPoint* sfPolyAddArc(cdCanvas* canvas, cdfPoint* poly, int *n, double xc, double yc, double width, double height, double angle1, double angle2, cdfPoint* current)
{
double c, s, sx, sy, x, y, prev_x, prev_y, da;
- int i, k, p, new_n;
+ int i, k, K, p, new_n;
cdfPoint* old_poly = poly;
- /* number of segments of equivalent poligonal for a full ellipse */
- int K = cdSimCalcEllipseNumSegments(canvas, (int)xc, (int)yc, (int)width, (int)height);
-
sFixAngles(canvas, &angle1, &angle2);
/* number of segments for the arc */
- K = cdRound((fabs(angle2-angle1)*K)/(360*CD_DEG2RAD));
- if (K < 1) K = 1;
+ K = sCalcEllipseNumSegments(canvas, (int)xc, (int)yc, (int)width, (int)height, angle1, angle2);
new_n = *n + K+1; /* add room for K+1 samples */
poly = (cdfPoint*)realloc(poly, sizeof(cdfPoint)*(new_n+2)); /* add room also for points at start and end */
@@ -284,7 +277,7 @@ void cdSimArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, dou
if (poly)
{
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, n);
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, n);
free(poly);
}
}
@@ -336,7 +329,7 @@ static void sElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int heigh
if (poly)
{
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, poly, n);
+ cdCanvasPoly(canvas, CD_FILL, poly, n);
free(poly);
}
}
@@ -684,7 +677,7 @@ void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n)
if (poly)
{
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, poly_n);
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, poly_n);
free(poly);
}
}
@@ -789,12 +782,8 @@ void cdfSimPolyPath(cdCanvas* canvas, const cdfPoint* poly, int n)
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,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
if (current_set)
path_poly = sfPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, ¤t);
@@ -909,12 +898,8 @@ static void sSimPolyFPath(cdCanvas* canvas, const cdPoint* poly, int n)
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 (!cdCanvasGetArcPathF(canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
if (current_set)
path_poly = sfPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, ¤t);
@@ -1043,12 +1028,8 @@ void cdSimPolyPath(cdCanvas* canvas, const cdPoint* poly, int n)
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 (!cdCanvasGetArcPath(canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
if (current_set)
path_poly = sPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, ¤t);
@@ -1091,22 +1072,22 @@ void cdSimPolyPath(cdCanvas* canvas, const cdPoint* poly, int n)
break;
case CD_PATH_FILL:
if (poly)
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
+ cdCanvasPoly(canvas, CD_FILL, path_poly, path_poly_n);
break;
case CD_PATH_STROKE:
if (poly)
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ cdCanvasPoly(canvas, CD_OPEN_LINES, path_poly, path_poly_n);
break;
case CD_PATH_FILLSTROKE:
if (poly)
{
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ cdCanvasPoly(canvas, CD_FILL, path_poly, path_poly_n);
+ cdCanvasPoly(canvas, CD_OPEN_LINES, path_poly, path_poly_n);
}
break;
case CD_PATH_CLIP:
if (poly)
- canvas->cxPoly(canvas->ctxcanvas, CD_CLIP, path_poly, path_poly_n);
+ cdCanvasPoly(canvas, CD_CLIP, path_poly, path_poly_n);
break;
}
}
@@ -1117,6 +1098,11 @@ void cdSimPolyPath(cdCanvas* canvas, const cdPoint* poly, int n)
/************************************************************************/
+/* Simulation functions that depend on the simulation base driver. */
+static void cdSimPolyFill(cdCanvas* canvas, cdPoint* poly, int n);
+static void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n);
+static void cdfSimPolyLine(cdCanvas* canvas, const cdfPoint* poly, int n);
+
void cdSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
@@ -1142,6 +1128,45 @@ void cdSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
}
}
+void cdfSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
+{
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+
+ switch(mode)
+ {
+ case CD_CLOSED_LINES:
+ fpoly[n] = fpoly[0];
+ n++;
+ /* continue */
+ case CD_OPEN_LINES:
+ cdfSimPolyLine(canvas, fpoly, n);
+ break;
+ case CD_BEZIER:
+ cdfSimPolyBezier(canvas, fpoly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(canvas, fpoly, n);
+ break;
+ case CD_CLIP:
+ case CD_FILL:
+ {
+ cdPoint* poly = malloc(sizeof(cdPoint)*n);
+ int i;
+
+ for (i = 0; iinterior_style;
@@ -1218,9 +1243,9 @@ void cdSimMark(cdCanvas* canvas, int x, int y)
poly[3].y = bottom;
if (canvas->mark_type == CD_DIAMOND)
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
+ cdCanvasPoly(canvas, CD_FILL, poly, 4);
else
- canvas->cxPoly(canvas->ctxcanvas, CD_CLOSED_LINES, poly, 4);
+ cdCanvasPoly(canvas, CD_CLOSED_LINES, poly, 4);
}
break;
}
@@ -1296,7 +1321,7 @@ void cdSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char
#include "cd_truetype.h"
#include "sim.h"
-void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n)
+static void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n)
{
int i, reset = 1, transform = 0;
int old_use_matrix = canvas->use_matrix;
@@ -1342,7 +1367,7 @@ void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n)
canvas->use_matrix = old_use_matrix;
}
-void cdfSimPolyLine(cdCanvas* canvas, const cdfPoint* poly, int n)
+static void cdfSimPolyLine(cdCanvas* canvas, const cdfPoint* poly, int n)
{
int i, reset = 1, transform = 0;
int old_use_matrix = canvas->use_matrix;
@@ -1429,14 +1454,14 @@ static void sGetBox(cdPoint* poly, int *xmin, int *xmax, int *ymin, int *ymax)
}
}
-void cdSimPolyFill(cdCanvas* canvas, cdPoint* poly, int n)
+static void cdSimPolyFill(cdCanvas* canvas, cdPoint* poly, int n)
{
int old_use_matrix = canvas->use_matrix;
if (canvas->use_matrix)
{
int i;
- for(i = 0; i < n; i++) /* can do that because poly is internal of the CD */
+ for(i = 0; i < n; i++) /* can do that because poly is internal of the CD, and it will NOT be stored */
cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
}
diff --git a/src/svg/cdsvg.c b/src/svg/cdsvg.c
index f84e4b5..789ece3 100644
--- a/src/svg/cdsvg.c
+++ b/src/svg/cdsvg.c
@@ -215,9 +215,36 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
}
-static void sCalcArc(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double a1, double a2, double *arcStartX, double *arcStartY, double *arcEndX, double *arcEndY, int *largeArc)
+static void sCalcArc(cdCanvas* canvas, double xc, double yc, double w, double h, double a1, double a2, double *arcStartX, double *arcStartY, double *arcEndX, double *arcEndY, int *largeArc)
{
- if (ctxcanvas->canvas->invert_yaxis==0)
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
+ if (canvas->invert_yaxis)
+ {
+ double t;
+
+ /* change orientation */
+ a1 *= -1;
+ a2 *= -1;
+
+ /* swap, so the start angle is the smaller */
+ t = a1;
+ a1 = a2;
+ a2 = t;
+ }
+
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, arcStartX, arcStartY, arcEndX, arcEndY);
+
+ if (fabs(a2-a1) > 180.0)
+ *largeArc = 1;
+ else
+ *largeArc = 0;
+}
+
+static void sCalcArc_OLD(cdCanvas* canvas, double xc, double yc, double w, double h, double a1, double a2, double *arcStartX, double *arcStartY, double *arcEndX, double *arcEndY, int *largeArc)
+{
+ if (canvas->invert_yaxis==0)
{
double t;
@@ -263,7 +290,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
return;
}
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
fprintf(ctxcanvas->file, "\n",
arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
@@ -286,7 +313,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
return;
}
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
fprintf(ctxcanvas->file, "\n",
xc, yc, arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
@@ -302,7 +329,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
double arcStartX, arcStartY, arcEndX, arcEndY;
int largeArc;
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
fprintf(ctxcanvas->file, "\n",
arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
@@ -477,14 +504,10 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
if (i+3 > n) return;
- xc = poly[i].x,
- yc = poly[i].y,
- w = poly[i+1].x,
- h = poly[i+1].y,
- a1 = poly[i+2].x,
- a2 = poly[i+2].y;
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
fprintf(ctxcanvas->file, "M %g %g A %g %g 0 %d 0 %g %g ",
arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY);
@@ -636,14 +659,10 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
if (i+3 > n) return;
- 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 (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc);
fprintf(ctxcanvas->file, "M %g %g A %d %d 0 %d 0 %g %g ",
arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY);
diff --git a/src/win32/cdwin.c b/src/win32/cdwin.c
index 37c4c0d..246ea5e 100644
--- a/src/win32/cdwin.c
+++ b/src/win32/cdwin.c
@@ -710,41 +710,45 @@ typedef struct _winArcParam
YEndArc; /* second radial ending point */
} winArcParam;
-static void sCalcArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2, winArcParam* arc)
+static void sCalcArc(cdCanvas* canvas, int xc, int yc, int w, int h, double a1, double a2, winArcParam* arc, int swap)
{
- /* convert to radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
+ /* computation is done as if the angles are counter-clockwise,
+ and yaxis is NOT inverted. */
- arc->LeftRect = xc - w/2;
- arc->RightRect = xc + w/2 + 1;
- arc->XStartArc = xc + cdRound(w * cos(angle1) / 2.0);
- arc->XEndArc = xc + cdRound(w * cos(angle2) / 2.0);
+ arc->LeftRect = xc - w/2;
+ arc->TopRect = yc - h/2;
+ arc->RightRect = xc + w/2 + 1;
+ arc->BottomRect = yc + h/2 + 1;
- if (ctxcanvas->canvas->invert_yaxis)
+ /* GDI orientation is the same as CD */
+
+ if (!canvas->invert_yaxis)
+ _cdSwapInt(arc->BottomRect, arc->TopRect); /* not necessary, but done for clarity */
+
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &(arc->XStartArc), &(arc->YStartArc), &(arc->XEndArc), &(arc->YEndArc));
+
+ if (canvas->invert_yaxis)
{
- arc->TopRect = yc - h/2;
- arc->BottomRect = yc + h/2 + 1;
- arc->YStartArc = yc - cdRound(h * sin(angle1) / 2.0);
- arc->YEndArc = yc - cdRound(h * sin(angle2) / 2.0);
+ /* fix axis orientation only, because angle orientation is the same */
+ arc->YStartArc = 2*yc - arc->YStartArc;
+ arc->YEndArc = 2*yc - arc->YEndArc;
}
else
{
- arc->BottomRect = yc - h/2;
- arc->TopRect = yc + h/2 + 1;
- arc->YStartArc = yc + cdRound(h * sin(angle1) / 2.0);
- arc->YEndArc = yc + cdRound(h * sin(angle2) / 2.0);
-
+ /* Arc behave diferent when GM_ADVANCED is set */
/* it is clock-wise when axis NOT inverted */
- _cdSwapInt(arc->XStartArc, arc->XEndArc);
- _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ if (swap)
+ {
+ _cdSwapInt(arc->XStartArc, arc->XEndArc);
+ _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ }
}
}
static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- sCalcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
sUpdateFill(ctxcanvas, 0);
@@ -754,7 +758,7 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- sCalcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
sUpdateFill(ctxcanvas, 1);
@@ -796,7 +800,7 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- sCalcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
sUpdateFill(ctxcanvas, 1);
@@ -843,10 +847,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
if (mode == CD_PATH)
{
- int p;
+ int p, current_set;
/* if there is any current path, remove it */
BeginPath(ctxcanvas->hDC);
+ current_set = 0;
i = 0;
for (p=0; pcanvas->path_n; p++)
@@ -856,42 +861,57 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
case CD_PATH_NEW:
EndPath(ctxcanvas->hDC);
BeginPath(ctxcanvas->hDC);
+ current_set = 0;
break;
case CD_PATH_MOVETO:
if (i+1 > n) return;
MoveToEx(ctxcanvas->hDC, poly[i].x, poly[i].y, NULL);
+ current_set = 1;
i++;
break;
case CD_PATH_LINETO:
if (i+1 > n) return;
LineTo(ctxcanvas->hDC, poly[i].x, poly[i].y);
+ current_set = 1;
i++;
break;
case CD_PATH_ARC:
{
- int xc, yc, w, h;
+ int xc, yc, w, h, old_arcmode = 0;
double a1, a2;
winArcParam arc;
if (i+3 > n) return;
- 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 (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arc, 0);
- sCalcArc(ctxcanvas, xc, yc, w, h, a1, a2, &arc);
+ if (current_set)
+ LineTo(ctxcanvas->hDC, arc.XStartArc, arc.YStartArc);
+ if ((a2-a1)<0) /* can be clockwise */
+ {
+ /* Arc behave diferent when GM_ADVANCED is set */
+ old_arcmode = SetArcDirection(ctxcanvas->hDC, ctxcanvas->canvas->invert_yaxis? AD_CLOCKWISE: AD_COUNTERCLOCKWISE);
+ }
+
Arc(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
+ if (old_arcmode) /* restore */
+ SetArcDirection(ctxcanvas->hDC, old_arcmode);
+
+ MoveToEx(ctxcanvas->hDC, arc.XEndArc, arc.YEndArc, NULL);
+ current_set = 1;
+
i += 3;
}
break;
case CD_PATH_CURVETO:
if (i+3 > n) return;
PolyBezierTo(ctxcanvas->hDC, (POINT*)(poly + i), 3);
+ current_set = 1;
i += 3;
break;
case CD_PATH_CLOSE:
diff --git a/test/simple/simple.c b/test/simple/simple.c
index eb7acab..891caef 100644
--- a/test/simple/simple.c
+++ b/test/simple/simple.c
@@ -705,18 +705,26 @@ int SimpleDrawAll(void)
cdCanvasPathSet(canvas, CD_PATH_MOVETO);
cdVertex(w/2 + 200, h/2);
cdCanvasPathSet(canvas, CD_PATH_LINETO);
+ cdVertex(w/2 + 230, h/2 + 50);
+ cdCanvasPathSet(canvas, CD_PATH_LINETO);
cdVertex(w/2 + 250, h/2 + 50);
cdCanvasPathSet(canvas, CD_PATH_CURVETO);
- cdVertex(w/2+150+150, h/2+200-50);
- cdVertex(w/2+150+180, h/2+250-50);
- cdVertex(w/2+150+180, h/2+200-50);
+ cdVertex(w/2+150+150, h/2+200-50); /* control point for start */
+ cdVertex(w/2+150+180, h/2+250-50); /* control point for end */
+ cdVertex(w/2+150+180, h/2+200-50); /* end point */
cdCanvasPathSet(canvas, CD_PATH_CURVETO);
cdVertex(w/2+150+180, h/2+150-50);
cdVertex(w/2+150+150, h/2+100-50);
cdVertex(w/2+150+300, h/2+100-50);
- cdCanvasPathSet(canvas, CD_PATH_CLOSE);
-// cdCanvasPathSet(canvas, CD_PATH_STROKE);
- cdCanvasPathSet(canvas, CD_PATH_FILL);
+ cdCanvasPathSet(canvas, CD_PATH_LINETO);
+ cdVertex(w/2+150+300, h/2-50);
+ cdCanvasPathSet(canvas, CD_PATH_ARC);
+ cdVertex(w/2+300, h/2); /* center */
+ cdVertex(200, 100); /* width, height */
+ cdVertex(-30*1000, -170*1000); /* start angle, end angle (degrees / 1000) */
+// cdCanvasPathSet(canvas, CD_PATH_CLOSE);
+ cdCanvasPathSet(canvas, CD_PATH_STROKE);
+// cdCanvasPathSet(canvas, CD_PATH_FILL);
// cdCanvasPathSet(canvas, CD_PATH_FILLSTROKE);
cdEnd();
--
cgit v1.2.3