summaryrefslogtreecommitdiff
path: root/src/drv/cdpicture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drv/cdpicture.c')
-rw-r--r--src/drv/cdpicture.c201
1 files changed, 198 insertions, 3 deletions
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;