diff options
author | scuri <scuri> | 2010-06-01 22:31:45 +0000 |
---|---|---|
committer | scuri <scuri> | 2010-06-01 22:31:45 +0000 |
commit | 17be65cfea56a53dc3a9cb617895adf5300db099 (patch) | |
tree | 03362237b113b92157f433ce0e018c39821b1f84 /src/sim | |
parent | 3e4bae27558fd3bcec4bc54928b0a5d3145cd7c3 (diff) |
*** empty log message ***
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/sim_primitives.c | 161 |
1 files changed, 93 insertions, 68 deletions
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; i<n; i++) + { + poly[i].x = _cdRound(fpoly[i].x); + poly[i].y = _cdRound(fpoly[i].y); + } + + cdCanvasPoly(canvas, mode, poly, n); + + free(poly); + } + break; + } +} + void cdSimMark(cdCanvas* canvas, int x, int y) { int oldinteriorstyle = canvas->interior_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); } |