/** \file * \brief CD Picture driver * * See Copyright Notice in cd.h */ #include #include #include #include #include #include "cd.h" #include "cd_private.h" #include "cdpicture.h" /* codes for the primitives. */ typedef enum _tPrim { CDPIC_LINE, CDPIC_RECT, CDPIC_BOX, CDPIC_ARC, CDPIC_SECTOR, CDPIC_CHORD, CDPIC_TEXT, CDPIC_POLY, CDPIC_PATH, CDPIC_FLINE, CDPIC_FRECT, CDPIC_FBOX, CDPIC_FARC, CDPIC_FSECTOR, CDPIC_FCHORD, CDPIC_FTEXT, CDPIC_FPOLY, CDPIC_FPATH, CDPIC_PIXEL, CDPIC_IMAGEMAP, CDPIC_IMAGERGB, CDPIC_IMAGERGBA, } tPrim; typedef struct _tFillAttrib { long foreground, background; int back_opacity; int interior_style, hatch_style; int fill_mode; int pattern_w, pattern_h; long* pattern; int stipple_w, stipple_h; unsigned char* stipple; } tFillAttrib; typedef struct _tLineAttrib { long foreground, background; int back_opacity; int line_style, line_width; int line_cap, line_join; int* line_dashes; int line_dashes_count; } tLineAttrib; typedef struct _tTextAttrib { long foreground; char* font_type_face; int font_style, font_size; int text_alignment; double text_orientation; char* native_font; } tTextAttrib; typedef struct _tLBR { int x1, y1, x2, y2; } tLBR; /* Line or Box or Rect */ typedef struct _tfLBR { double x1, y1, x2, y2; } tfLBR; /* Line or Box or Rect */ typedef struct _tASC { int xc, yc, w, h; double angle1, angle2; } tASC; /* Arc or Sector or Chord */ typedef struct _tfASC { double xc, yc, w, h; double angle1, angle2; } tfASC; /* Arc or Sector or Chord */ typedef struct _tPoly { int mode; int n; cdPoint* points; } tPoly; /* Begin, Vertex and End */ typedef struct _tfPoly { int mode; int n; 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; char *s; } tText; /* Text */ typedef struct _tfText { double x, y; char *s; } tfText; /* Text */ typedef struct _tPixel { int x, y; long color; } tPixel; /* Pixel */ typedef struct _tImageMap { int iw, ih; unsigned char *index; long int *colors; int x, y, w, h; } tImageMap; typedef struct _tImageRGBA { int iw, ih; unsigned char *r; unsigned char *g; unsigned char *b; unsigned char *a; int x, y, w, h; } tImageRGBA; typedef struct _tPrimNode { tPrim type; void* param_buffer; /* dinamically allocated memory for the parameter */ union { tLBR lineboxrect; tfLBR lineboxrectf; tASC arcsectorchord; tfASC arcsectorchordf; tPoly poly; tfPoly polyf; tPath path; tfPath pathf; tText text; tfText textf; tPixel pixel; tImageMap imagemap; tImageRGBA imagergba; } param; void* attrib_buffer; /* dinamically allocated memory for the attributes */ union { tLineAttrib line; tFillAttrib fill; tTextAttrib text; } attrib; struct _tPrimNode *next; } tPrimNode; struct _cdCtxCanvas { cdCanvas* canvas; /* primitives list */ tPrimNode *prim_first, *prim_last; int prim_n; /* bounding box */ int xmin, xmax, ymin, ymax; }; static void picUpdateSize(cdCtxCanvas *ctxcanvas) { ctxcanvas->canvas->w = ctxcanvas->xmax-ctxcanvas->xmin+1; ctxcanvas->canvas->h = ctxcanvas->ymax-ctxcanvas->ymin+1; ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres; ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres; } static void picUpdateBBox(cdCtxCanvas *ctxcanvas, int x, int y, int ew) { if (x+ew > ctxcanvas->xmax) ctxcanvas->xmax = x+ew; if (y+ew > ctxcanvas->ymax) ctxcanvas->ymax = y+ew; if (x-ew < ctxcanvas->xmin) ctxcanvas->xmin = x-ew; if (y-ew < ctxcanvas->ymin) ctxcanvas->ymin = y-ew; picUpdateSize(ctxcanvas); } static void picUpdateBBoxF(cdCtxCanvas *ctxcanvas, double x, double y, int ew) { if ((int)ceil(x+ew) > ctxcanvas->xmax) ctxcanvas->xmax = (int)ceil(x+ew); if ((int)ceil(y+ew) > ctxcanvas->ymax) ctxcanvas->ymax = (int)ceil(y+ew); if ((int)floor(x-ew) < ctxcanvas->xmin) ctxcanvas->xmin = (int)floor(x-ew); if ((int)floor(y-ew) < ctxcanvas->ymin) ctxcanvas->ymin = (int)floor(y-ew); picUpdateSize(ctxcanvas); } static void picAddPrim(cdCtxCanvas *ctxcanvas, tPrimNode *prim) { if (ctxcanvas->prim_n == 0) ctxcanvas->prim_first = prim; else ctxcanvas->prim_last->next = prim; ctxcanvas->prim_last = prim; ctxcanvas->prim_n++; } static tPrimNode* primCreate(tPrim type) { tPrimNode *prim = malloc(sizeof(tPrimNode)); memset(prim, 0, sizeof(tPrimNode)); prim->type = type; return prim; } static void primDestroy(tPrimNode *prim) { if (prim->param_buffer) free(prim->param_buffer); if (prim->attrib_buffer) free(prim->attrib_buffer); free(prim); } static void primAddAttrib_Line(tPrimNode *prim, cdCanvas *canvas) { prim->attrib.line.foreground = canvas->foreground; prim->attrib.line.background = canvas->background; prim->attrib.line.back_opacity = canvas->back_opacity; prim->attrib.line.line_style = canvas->line_style; prim->attrib.line.line_width = canvas->line_width; prim->attrib.line.line_cap = canvas->line_cap; prim->attrib.line.line_join = canvas->line_join; if (canvas->line_style==CD_CUSTOM && canvas->line_dashes) { prim->attrib.line.line_dashes_count = canvas->line_dashes_count; prim->attrib_buffer = malloc(canvas->line_dashes_count*sizeof(int)); prim->attrib.line.line_dashes = prim->attrib_buffer; memcpy(prim->attrib.line.line_dashes, canvas->line_dashes, canvas->line_dashes_count*sizeof(int)); } } static void primAddAttrib_Fill(tPrimNode *prim, cdCanvas *canvas) { prim->attrib.fill.foreground = canvas->foreground; prim->attrib.fill.background = canvas->background; prim->attrib.fill.back_opacity = canvas->back_opacity; prim->attrib.fill.interior_style = canvas->interior_style; prim->attrib.fill.hatch_style = canvas->hatch_style; prim->attrib.fill.fill_mode = canvas->fill_mode; prim->attrib.fill.pattern_w = canvas->pattern_w; prim->attrib.fill.pattern_h = canvas->pattern_h; prim->attrib.fill.stipple_w = canvas->stipple_w; prim->attrib.fill.stipple_h = canvas->stipple_h; if (canvas->interior_style==CD_PATTERN && canvas->pattern) { prim->attrib_buffer = malloc(canvas->pattern_size*sizeof(long)); prim->attrib.fill.pattern = prim->attrib_buffer; memcpy(prim->attrib.fill.pattern, canvas->pattern, canvas->pattern_size*sizeof(long)); } if (canvas->interior_style==CD_STIPPLE && canvas->stipple) { prim->attrib_buffer = malloc(canvas->stipple_size*sizeof(long)); prim->attrib.fill.stipple = prim->attrib_buffer; memcpy(prim->attrib.fill.stipple, canvas->stipple, canvas->stipple_size*sizeof(long)); } } static void primAddAttrib_Text(tPrimNode *prim, cdCanvas *canvas) { prim->attrib.text.foreground = canvas->foreground; prim->attrib.text.font_style = canvas->font_style; prim->attrib.text.font_size = canvas->font_size; prim->attrib.text.text_alignment = canvas->text_alignment; prim->attrib.text.text_orientation = canvas->text_orientation; if (canvas->native_font[0]) { prim->attrib_buffer = cdStrDup(canvas->native_font); prim->attrib.text.native_font = prim->attrib_buffer; } else { prim->attrib_buffer = cdStrDup(canvas->font_type_face); prim->attrib.text.font_type_face = prim->attrib_buffer; } } static void primUpdateAttrib_Line(tPrimNode *prim, cdCanvas *canvas) { cdCanvasSetBackground(canvas, prim->attrib.line.background); cdCanvasSetForeground(canvas, prim->attrib.line.foreground); cdCanvasBackOpacity(canvas, prim->attrib.line.back_opacity); cdCanvasLineStyle(canvas, prim->attrib.line.line_style); cdCanvasLineWidth(canvas, prim->attrib.line.line_width); cdCanvasLineCap(canvas, prim->attrib.line.line_cap); cdCanvasLineJoin(canvas, prim->attrib.line.line_join); if (prim->attrib.line.line_style==CD_CUSTOM && prim->attrib.line.line_dashes) cdCanvasLineStyleDashes(canvas, prim->attrib.line.line_dashes, prim->attrib.line.line_dashes_count); } void primUpdateAttrib_Fill(tPrimNode *prim, cdCanvas *canvas) { cdCanvasSetBackground(canvas, prim->attrib.fill.background); cdCanvasSetForeground(canvas, prim->attrib.fill.foreground); cdCanvasBackOpacity(canvas, prim->attrib.fill.back_opacity); cdCanvasFillMode(canvas, prim->attrib.fill.fill_mode); if (prim->attrib.fill.interior_style==CD_HATCH) cdCanvasHatch(canvas, prim->attrib.fill.hatch_style); else if (prim->attrib.fill.interior_style==CD_PATTERN && prim->attrib.fill.pattern) cdCanvasPattern(canvas, prim->attrib.fill.pattern_w, prim->attrib.fill.pattern_h, prim->attrib.fill.pattern); else if (prim->attrib.fill.interior_style==CD_STIPPLE && prim->attrib.fill.stipple) cdCanvasStipple(canvas, prim->attrib.fill.stipple_w, prim->attrib.fill.stipple_h, prim->attrib.fill.stipple); cdCanvasInteriorStyle(canvas, prim->attrib.fill.interior_style); } void primUpdateAttrib_Text(tPrimNode *prim, cdCanvas *canvas) { cdCanvasSetForeground(canvas, prim->attrib.text.foreground); cdCanvasTextAlignment(canvas, prim->attrib.text.text_alignment); cdCanvasTextOrientation(canvas, prim->attrib.text.text_orientation); if (canvas->native_font[0]) cdCanvasNativeFont(canvas, prim->attrib.text.native_font); else cdCanvasFont(canvas, prim->attrib.text.font_type_face, prim->attrib.text.font_style, prim->attrib.text.font_size); } static int cdfont(cdCtxCanvas *ctxcanvas, const char *type_face, int style, int size) { (void)ctxcanvas; (void)type_face; (void)style; (void)size; return 1; } static void cdclear(cdCtxCanvas *ctxcanvas) { tPrimNode *prim; int i; for (i = 0; i < ctxcanvas->prim_n; i++) { prim = ctxcanvas->prim_first; ctxcanvas->prim_first = prim->next; primDestroy(prim); } ctxcanvas->prim_n = 0; ctxcanvas->prim_first = NULL; ctxcanvas->prim_last = NULL; } static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color) { tPrimNode *prim = primCreate(CDPIC_PIXEL); prim->param.pixel.x = x; prim->param.pixel.y = y; prim->param.pixel.color = color; picAddPrim(ctxcanvas, prim); picUpdateBBox(ctxcanvas, x, y, 0); } static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2) { tPrimNode *prim = primCreate(CDPIC_LINE); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.lineboxrect.x1 = x1; prim->param.lineboxrect.y1 = y1; prim->param.lineboxrect.x2 = x2; prim->param.lineboxrect.y2 = y2; picAddPrim(ctxcanvas, prim); picUpdateBBox(ctxcanvas, x1, y1, ctxcanvas->canvas->line_width); picUpdateBBox(ctxcanvas, x2, y2, ctxcanvas->canvas->line_width); } static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2) { tPrimNode *prim = primCreate(CDPIC_FLINE); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.lineboxrectf.x1 = x1; prim->param.lineboxrectf.y1 = y1; prim->param.lineboxrectf.x2 = x2; prim->param.lineboxrectf.y2 = y2; picAddPrim(ctxcanvas, prim); picUpdateBBoxF(ctxcanvas, x1, y1, ctxcanvas->canvas->line_width); picUpdateBBoxF(ctxcanvas, x2, y2, ctxcanvas->canvas->line_width); } static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) { tPrimNode *prim = primCreate(CDPIC_RECT); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.lineboxrect.x1 = xmin; prim->param.lineboxrect.y1 = ymin; prim->param.lineboxrect.x2 = xmax; prim->param.lineboxrect.y2 = ymax; picAddPrim(ctxcanvas, prim); picUpdateBBox(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width); picUpdateBBox(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width); } static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) { tPrimNode *prim = primCreate(CDPIC_FRECT); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.lineboxrectf.x1 = xmin; prim->param.lineboxrectf.y1 = ymin; prim->param.lineboxrectf.x2 = xmax; prim->param.lineboxrectf.y2 = ymax; picAddPrim(ctxcanvas, prim); picUpdateBBoxF(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width); picUpdateBBoxF(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width); } static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) { tPrimNode *prim = primCreate(CDPIC_BOX); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.lineboxrect.x1 = xmin; prim->param.lineboxrect.y1 = ymin; prim->param.lineboxrect.x2 = xmax; prim->param.lineboxrect.y2 = ymax; picAddPrim(ctxcanvas, prim); picUpdateBBox(ctxcanvas, xmin, ymin, 0); picUpdateBBox(ctxcanvas, xmax, ymax, 0); } static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) { tPrimNode *prim = primCreate(CDPIC_FBOX); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.lineboxrectf.x1 = xmin; prim->param.lineboxrectf.y1 = ymin; prim->param.lineboxrectf.x2 = xmax; prim->param.lineboxrectf.y2 = ymax; picAddPrim(ctxcanvas, prim); picUpdateBBoxF(ctxcanvas, xmin, ymin, 0); picUpdateBBoxF(ctxcanvas, xmax, ymax, 0); } static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_ARC); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.arcsectorchord.xc = xc; prim->param.arcsectorchord.yc = yc; prim->param.arcsectorchord.w = w; prim->param.arcsectorchord.h = h; prim->param.arcsectorchord.angle1 = a1; prim->param.arcsectorchord.angle2 = a2; picAddPrim(ctxcanvas, prim); 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); } static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_FARC); primAddAttrib_Line(prim, ctxcanvas->canvas); prim->param.arcsectorchordf.xc = xc; prim->param.arcsectorchordf.yc = yc; prim->param.arcsectorchordf.w = w; prim->param.arcsectorchordf.h = h; prim->param.arcsectorchordf.angle1 = a1; prim->param.arcsectorchordf.angle2 = a2; picAddPrim(ctxcanvas, prim); 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); } static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_SECTOR); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.arcsectorchord.xc = xc; prim->param.arcsectorchord.yc = yc; prim->param.arcsectorchord.w = w; prim->param.arcsectorchord.h = h; prim->param.arcsectorchord.angle1 = a1; prim->param.arcsectorchord.angle2 = a2; picAddPrim(ctxcanvas, prim); 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); } static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_FSECTOR); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.arcsectorchordf.xc = xc; prim->param.arcsectorchordf.yc = yc; prim->param.arcsectorchordf.w = w; prim->param.arcsectorchordf.h = h; prim->param.arcsectorchordf.angle1 = a1; prim->param.arcsectorchordf.angle2 = a2; picAddPrim(ctxcanvas, prim); 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); } static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_CHORD); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.arcsectorchord.xc = xc; prim->param.arcsectorchord.yc = yc; prim->param.arcsectorchord.w = w; prim->param.arcsectorchord.h = h; prim->param.arcsectorchord.angle1 = a1; prim->param.arcsectorchord.angle2 = a2; picAddPrim(ctxcanvas, prim); cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax); picUpdateBBox(ctxcanvas, xmin, ymin, 0); picUpdateBBox(ctxcanvas, xmax, ymax, 0); } static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_FCHORD); primAddAttrib_Fill(prim, ctxcanvas->canvas); prim->param.arcsectorchordf.xc = xc; prim->param.arcsectorchordf.yc = yc; prim->param.arcsectorchordf.w = w; prim->param.arcsectorchordf.h = h; prim->param.arcsectorchordf.angle1 = a1; prim->param.arcsectorchordf.angle2 = a2; picAddPrim(ctxcanvas, prim); 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); } static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text, int len) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_TEXT); primAddAttrib_Text(prim, ctxcanvas->canvas); prim->param.text.x = x; prim->param.text.y = y; prim->param.text.s = cdStrDupN(text, len); prim->param_buffer = prim->param.text.s; picAddPrim(ctxcanvas, prim); cdCanvasGetTextBox(ctxcanvas->canvas, x, y, prim->param.text.s, &xmin, &xmax, &ymin, &ymax); picUpdateBBox(ctxcanvas, xmin, ymin, 0); picUpdateBBox(ctxcanvas, xmax, ymax, 0); } static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text, int len) { int xmin, xmax, ymin, ymax; tPrimNode *prim = primCreate(CDPIC_FTEXT); primAddAttrib_Text(prim, ctxcanvas->canvas); prim->param.textf.x = x; prim->param.textf.y = y; prim->param.textf.s = cdStrDupN(text, len); prim->param_buffer = prim->param.textf.s; picAddPrim(ctxcanvas, prim); cdCanvasGetTextBox(ctxcanvas->canvas, _cdRound(x), _cdRound(y), prim->param.text.s, &xmin, &xmax, &ymin, &ymax); picUpdateBBox(ctxcanvas, xmin, ymin, 0); picUpdateBBox(ctxcanvas, xmax, ymax, 0); } static void cdpath(cdCtxCanvas *ctxcanvas, cdPoint* poly, int n) { int i, p, fill = -1; tPrimNode *prim; for (p=0; pcanvas->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)); prim->param_buffer = prim->param.poly.points; picAddPrim(ctxcanvas, prim); for (i = 0; i < n; i++) { if (mode == CD_FILL) picUpdateBBox(ctxcanvas, poly[i].x, poly[i].y, 0); else picUpdateBBox(ctxcanvas, poly[i].x, poly[i].y, ctxcanvas->canvas->line_width); } } static void cdfpath(cdCtxCanvas *ctxcanvas, cdfPoint* poly, int n) { int i, p, fill = -1; tPrimNode *prim; for (p=0; pcanvas->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; tPrimNode *prim; if (mode == CD_CLIP || mode == CD_REGION) return; if (mode == CD_PATH) { cdfpath(ctxcanvas, poly, n); return; } prim = primCreate(CDPIC_FPOLY); if (mode == CD_FILL) 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(cdfPoint)); memcpy(prim->param.polyf.points, poly, n * sizeof(cdfPoint)); prim->param_buffer = prim->param.polyf.points; picAddPrim(ctxcanvas, prim); for (i = 0; i < n; i++) { if (mode == CD_FILL) picUpdateBBox(ctxcanvas, _cdRound(poly[i].x), _cdRound(poly[i].y), 0); else picUpdateBBox(ctxcanvas, _cdRound(poly[i].x), _cdRound(poly[i].y), ctxcanvas->canvas->line_width); } } static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) { int l, offset, size; unsigned char *dr, *dg, *db; tPrimNode *prim = primCreate(CDPIC_IMAGERGB); prim->param.imagergba.iw = xmax-xmin+1; prim->param.imagergba.ih = ymax-ymin+1; prim->param.imagergba.x = x; prim->param.imagergba.y = y; prim->param.imagergba.w = w; prim->param.imagergba.h = h; size = prim->param.imagergba.iw*prim->param.imagergba.ih; prim->param_buffer = malloc(3*size); prim->param.imagergba.r = prim->param_buffer; prim->param.imagergba.g = prim->param.imagergba.r + size; prim->param.imagergba.b = prim->param.imagergba.g + size; offset = ymin*iw + xmin; r += offset; g += offset; b += offset; dr = prim->param.imagergba.r; dg = prim->param.imagergba.g; db = prim->param.imagergba.b; offset = prim->param.imagergba.iw; for (l = ymin; l <= ymax; l++) { memcpy(dr, r, offset); memcpy(dg, g, offset); memcpy(db, b, offset); r += iw; g += iw; b += iw; dr += offset; dg += offset; db += offset; } picUpdateBBox(ctxcanvas, x, y, 0); picUpdateBBox(ctxcanvas, x+prim->param.imagergba.iw-1, y+prim->param.imagergba.ih-1, 0); } static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, 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) { int l, offset, size; unsigned char *dr, *dg, *db, *da; tPrimNode *prim = primCreate(CDPIC_IMAGERGBA); prim->param.imagergba.iw = xmax-xmin+1; prim->param.imagergba.ih = ymax-ymin+1; prim->param.imagergba.x = x; prim->param.imagergba.y = y; prim->param.imagergba.w = w; prim->param.imagergba.h = h; size = prim->param.imagergba.iw*prim->param.imagergba.ih; prim->param_buffer = malloc(4*size); prim->param.imagergba.r = prim->param_buffer; prim->param.imagergba.g = prim->param.imagergba.r + size; prim->param.imagergba.b = prim->param.imagergba.g + size; prim->param.imagergba.a = prim->param.imagergba.b + size; offset = ymin*iw + xmin; r += offset; g += offset; b += offset; a += offset; dr = prim->param.imagergba.r; dg = prim->param.imagergba.g; db = prim->param.imagergba.b; da = prim->param.imagergba.a; offset = prim->param.imagergba.iw; for (l = ymin; l <= ymax; l++) { memcpy(dr, r, offset); memcpy(dg, g, offset); memcpy(db, b, offset); memcpy(da, a, offset); r += iw; g += iw; b += iw; a += iw; dr += offset; dg += offset; db += offset; da += offset; } picUpdateBBox(ctxcanvas, x, y, 0); picUpdateBBox(ctxcanvas, x+prim->param.imagergba.iw-1, y+prim->param.imagergba.ih-1, 0); } static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) { int c, l, n = 0, offset, size; unsigned char *dindex; long *dcolors; tPrimNode *prim = primCreate(CDPIC_IMAGEMAP); prim->param.imagemap.iw = xmax-xmin+1; prim->param.imagemap.ih = ymax-ymin+1; prim->param.imagemap.x = x; prim->param.imagemap.y = y; prim->param.imagemap.w = w; prim->param.imagemap.h = h; size = prim->param.imagemap.iw*prim->param.imagemap.ih; prim->param_buffer = malloc(size + 256); prim->param.imagemap.index = prim->param_buffer; prim->param.imagemap.colors = (long*)(prim->param.imagemap.index + size); offset = ymin*iw + xmin; index += offset; dindex = prim->param.imagemap.index; dcolors = prim->param.imagemap.colors; offset = iw - prim->param.imagemap.iw; for (l = ymin; l <= ymax; l++) { for (c = xmin; c <= xmax; c++) { if (*index > n) n = *index; *dindex++ = *index++; } index += offset; } n++; for (c = 0; c < n; c++) dcolors[c] = colors[c]; picUpdateBBox(ctxcanvas, x, y, 0); picUpdateBBox(ctxcanvas, x+prim->param.imagemap.iw-1, y+prim->param.imagemap.ih-1, 0); } /**********/ /* cdPlay */ /**********/ typedef int(*_cdsizecb)(cdCanvas* canvas, int w, int h, double w_mm, double h_mm); static _cdsizecb cdsizecb = NULL; static int cdregistercallback(int cb, cdCallback func) { switch (cb) { case CD_SIZECB: cdsizecb = (_cdsizecb)func; return CD_OK; } return CD_ERROR; } #define sMin1(_v) (_v == 0? 1: _v) #define sScaleX(_x) cdRound((_x - pic_xmin) * factorX + xmin) #define sScaleY(_y) cdRound((_y - pic_ymin) * factorY + ymin) #define sScaleW(_w) sMin1(cdRound(_w * factorX)) #define sScaleH(_h) sMin1(cdRound(_h * factorY)) #define sfScaleX(_x) ((_x - pic_xmin) * factorX + xmin) #define sfScaleY(_y) ((_y - pic_ymin) * factorY + ymin) #define sfScaleW(_w) (_w * factorX) #define sfScaleH(_h) (_h * factorY) static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void *data) { tPrimNode *prim; cdCanvas* pic_canvas = (cdCanvas*)data; cdCtxCanvas* ctxcanvas = pic_canvas->ctxcanvas; int p, i, n, scale = 0, pic_xmin = ctxcanvas->xmin, pic_ymin = ctxcanvas->ymin; double factorX = 1, factorY = 1; if ((ctxcanvas->xmax-ctxcanvas->xmin)!=0 && (ctxcanvas->ymax-ctxcanvas->ymin)!=0 && (xmax-xmin)!=0 && (ymax-ymin)!=0) { scale = 1; factorX = ((double)(xmax-xmin)) / (ctxcanvas->xmax-ctxcanvas->xmin); factorY = ((double)(ymax-ymin)) / (ctxcanvas->ymax-ctxcanvas->ymin); } if (cdsizecb) { int err; err = cdsizecb(canvas, pic_canvas->w, pic_canvas->h, pic_canvas->w_mm, pic_canvas->h_mm); if (err) return CD_ERROR; } prim = ctxcanvas->prim_first; for (i = 0; i < ctxcanvas->prim_n; i++) { if (scale) { switch (prim->type) { case CDPIC_LINE: primUpdateAttrib_Line(prim, canvas); cdCanvasLine(canvas, sScaleX(prim->param.lineboxrect.x1), sScaleY(prim->param.lineboxrect.y1), sScaleX(prim->param.lineboxrect.x2), sScaleY(prim->param.lineboxrect.y2)); break; case CDPIC_FLINE: primUpdateAttrib_Line(prim, canvas); cdfCanvasLine(canvas, sfScaleX(prim->param.lineboxrectf.x1), sfScaleY(prim->param.lineboxrectf.y1), sfScaleX(prim->param.lineboxrectf.x2), sfScaleY(prim->param.lineboxrectf.y2)); break; case CDPIC_RECT: primUpdateAttrib_Line(prim, canvas); cdCanvasRect(canvas, sScaleX(prim->param.lineboxrect.x1), sScaleX(prim->param.lineboxrect.x2), sScaleY(prim->param.lineboxrect.y1), sScaleY(prim->param.lineboxrect.y2)); break; case CDPIC_FRECT: primUpdateAttrib_Line(prim, canvas); cdfCanvasRect(canvas, sfScaleX(prim->param.lineboxrectf.x1), sfScaleX(prim->param.lineboxrectf.x2), sfScaleY(prim->param.lineboxrectf.y1), sfScaleY(prim->param.lineboxrectf.y2)); break; case CDPIC_BOX: primUpdateAttrib_Fill(prim, canvas); cdCanvasBox(canvas, sScaleX(prim->param.lineboxrect.x1), sScaleX(prim->param.lineboxrect.x2), sScaleY(prim->param.lineboxrect.y1), sScaleY(prim->param.lineboxrect.y2)); break; case CDPIC_FBOX: primUpdateAttrib_Fill(prim, canvas); cdfCanvasBox(canvas, sfScaleX(prim->param.lineboxrectf.x1), sfScaleX(prim->param.lineboxrectf.x2), sfScaleY(prim->param.lineboxrectf.y1), sfScaleY(prim->param.lineboxrectf.y2)); break; case CDPIC_ARC: primUpdateAttrib_Line(prim, canvas); cdCanvasArc(canvas, sScaleX(prim->param.arcsectorchord.xc), sScaleY(prim->param.arcsectorchord.yc), sScaleW(prim->param.arcsectorchord.w), sScaleH(prim->param.arcsectorchord.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FARC: primUpdateAttrib_Line(prim, canvas); cdfCanvasArc(canvas, sfScaleX(prim->param.arcsectorchordf.xc), sfScaleY(prim->param.arcsectorchordf.yc), sfScaleW(prim->param.arcsectorchordf.w), sfScaleH(prim->param.arcsectorchordf.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_SECTOR: primUpdateAttrib_Fill(prim, canvas); cdCanvasSector(canvas, sScaleX(prim->param.arcsectorchord.xc), sScaleY(prim->param.arcsectorchord.yc), sScaleW(prim->param.arcsectorchord.w), sScaleH(prim->param.arcsectorchord.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FSECTOR: primUpdateAttrib_Fill(prim, canvas); cdfCanvasSector(canvas, sfScaleX(prim->param.arcsectorchordf.xc), sfScaleY(prim->param.arcsectorchordf.yc), sfScaleW(prim->param.arcsectorchordf.w), sfScaleH(prim->param.arcsectorchordf.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_CHORD: primUpdateAttrib_Fill(prim, canvas); cdCanvasChord(canvas, sScaleX(prim->param.arcsectorchord.xc), sScaleY(prim->param.arcsectorchord.yc), sScaleW(prim->param.arcsectorchord.w), sScaleH(prim->param.arcsectorchord.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FCHORD: primUpdateAttrib_Fill(prim, canvas); cdfCanvasChord(canvas, sfScaleX(prim->param.arcsectorchordf.xc), sfScaleY(prim->param.arcsectorchordf.yc), sfScaleW(prim->param.arcsectorchordf.w), sfScaleH(prim->param.arcsectorchordf.h), prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_TEXT: primUpdateAttrib_Text(prim, canvas); cdCanvasText(canvas, sScaleX(prim->param.text.x), sScaleY(prim->param.text.y), prim->param.text.s); break; case CDPIC_FTEXT: primUpdateAttrib_Text(prim, canvas); cdfCanvasText(canvas, sfScaleX(prim->param.textf.x), sfScaleY(prim->param.textf.y), prim->param.text.s); break; case CDPIC_POLY: if (prim->param.poly.mode == CD_FILL) primUpdateAttrib_Fill(prim, canvas); else primUpdateAttrib_Line(prim, canvas); cdCanvasBegin(canvas, prim->param.poly.mode); for (p = 0; p < prim->param.poly.n; p++) cdCanvasVertex(canvas, sScaleX(prim->param.poly.points[p].x), sScaleY(prim->param.poly.points[p].y)); cdCanvasEnd(canvas); break; case CDPIC_FPOLY: if (prim->param.poly.mode == CD_FILL) primUpdateAttrib_Fill(prim, canvas); else primUpdateAttrib_Line(prim, canvas); cdCanvasBegin(canvas, prim->param.polyf.mode); for (p = 0; p < prim->param.polyf.n; p++) 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; pparam.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; pparam.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; case CDPIC_IMAGERGBA: cdCanvasPutImageRectRGBA(canvas, prim->param.imagergba.iw, prim->param.imagergba.ih, prim->param.imagergba.r, prim->param.imagergba.g, prim->param.imagergba.b, prim->param.imagergba.a, 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; case CDPIC_IMAGEMAP: cdCanvasPutImageRectMap(canvas, prim->param.imagemap.iw, prim->param.imagemap.ih, prim->param.imagemap.index, prim->param.imagemap.colors, sScaleX(prim->param.imagemap.x), sScaleY(prim->param.imagemap.y), sScaleW(prim->param.imagemap.w), sScaleH(prim->param.imagemap.h), 0, 0, 0, 0); break; case CDPIC_PIXEL: cdCanvasPixel(canvas, sScaleX(prim->param.pixel.x), sScaleY(prim->param.pixel.y), prim->param.pixel.color); break; } } else { switch (prim->type) { case CDPIC_LINE: primUpdateAttrib_Line(prim, canvas); cdCanvasLine(canvas, prim->param.lineboxrect.x1, prim->param.lineboxrect.y1, prim->param.lineboxrect.x2, prim->param.lineboxrect.y2); break; case CDPIC_FLINE: primUpdateAttrib_Line(prim, canvas); cdfCanvasLine(canvas, prim->param.lineboxrectf.x1, prim->param.lineboxrectf.y1, prim->param.lineboxrectf.x2, prim->param.lineboxrectf.y2); break; case CDPIC_RECT: primUpdateAttrib_Line(prim, canvas); cdCanvasRect(canvas, prim->param.lineboxrect.x1, prim->param.lineboxrect.x2, prim->param.lineboxrect.y1, prim->param.lineboxrect.y2); break; case CDPIC_FRECT: primUpdateAttrib_Line(prim, canvas); cdfCanvasRect(canvas, prim->param.lineboxrectf.x1, prim->param.lineboxrectf.x2, prim->param.lineboxrectf.y1, prim->param.lineboxrectf.y2); break; case CDPIC_BOX: primUpdateAttrib_Fill(prim, canvas); cdCanvasBox(canvas, prim->param.lineboxrect.x1, prim->param.lineboxrect.x2, prim->param.lineboxrect.y1, prim->param.lineboxrect.y2); break; case CDPIC_FBOX: primUpdateAttrib_Fill(prim, canvas); cdfCanvasBox(canvas, prim->param.lineboxrectf.x1, prim->param.lineboxrectf.x2, prim->param.lineboxrectf.y1, prim->param.lineboxrectf.y2); break; case CDPIC_ARC: primUpdateAttrib_Line(prim, canvas); cdCanvasArc(canvas, prim->param.arcsectorchord.xc, prim->param.arcsectorchord.yc, prim->param.arcsectorchord.w, prim->param.arcsectorchord.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FARC: primUpdateAttrib_Line(prim, canvas); cdfCanvasArc(canvas, prim->param.arcsectorchordf.xc, prim->param.arcsectorchordf.yc, prim->param.arcsectorchordf.w, prim->param.arcsectorchordf.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_SECTOR: primUpdateAttrib_Fill(prim, canvas); cdCanvasSector(canvas, prim->param.arcsectorchord.xc, prim->param.arcsectorchord.yc, prim->param.arcsectorchord.w, prim->param.arcsectorchord.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FSECTOR: primUpdateAttrib_Fill(prim, canvas); cdfCanvasSector(canvas, prim->param.arcsectorchordf.xc, prim->param.arcsectorchordf.yc, prim->param.arcsectorchordf.w, prim->param.arcsectorchordf.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_CHORD: primUpdateAttrib_Fill(prim, canvas); cdCanvasChord(canvas, prim->param.arcsectorchord.xc, prim->param.arcsectorchord.yc, prim->param.arcsectorchord.w, prim->param.arcsectorchord.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_FCHORD: primUpdateAttrib_Fill(prim, canvas); cdfCanvasChord(canvas, prim->param.arcsectorchordf.xc, prim->param.arcsectorchordf.yc, prim->param.arcsectorchordf.w, prim->param.arcsectorchordf.h, prim->param.arcsectorchord.angle1, prim->param.arcsectorchord.angle2); break; case CDPIC_TEXT: primUpdateAttrib_Text(prim, canvas); cdCanvasText(canvas, prim->param.text.x, prim->param.text.y, prim->param.text.s); break; case CDPIC_FTEXT: primUpdateAttrib_Text(prim, canvas); cdfCanvasText(canvas, prim->param.textf.x, prim->param.textf.y, prim->param.text.s); break; case CDPIC_POLY: if (prim->param.poly.mode == CD_FILL) primUpdateAttrib_Fill(prim, canvas); else primUpdateAttrib_Line(prim, canvas); cdCanvasBegin(canvas, prim->param.poly.mode); for (p = 0; p < prim->param.poly.n; p++) cdCanvasVertex(canvas, prim->param.poly.points[p].x, prim->param.poly.points[p].y); cdCanvasEnd(canvas); break; case CDPIC_FPOLY: if (prim->param.poly.mode == CD_FILL) primUpdateAttrib_Fill(prim, canvas); else primUpdateAttrib_Line(prim, canvas); cdCanvasBegin(canvas, prim->param.polyf.mode); for (p = 0; p < prim->param.polyf.n; p++) cdfCanvasVertex(canvas, prim->param.polyf.points[p].x, 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; pparam.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, prim->param.path.points[n].x, prim->param.path.points[n].y); n++; break; case CD_PATH_CURVETO: case CD_PATH_ARC: { if (n+3 > n) break; cdCanvasVertex(canvas, prim->param.path.points[n].x, prim->param.path.points[n].y); cdCanvasVertex(canvas, prim->param.path.points[n+1].x, prim->param.path.points[n+1].y); cdCanvasVertex(canvas, prim->param.path.points[n+2].x, 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; pparam.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, prim->param.pathf.points[n].x, prim->param.pathf.points[n].y); n++; break; case CD_PATH_CURVETO: case CD_PATH_ARC: { if (n+3 > n) break; cdfCanvasVertex(canvas, prim->param.pathf.points[n].x, prim->param.pathf.points[n].y); cdfCanvasVertex(canvas, prim->param.pathf.points[n+1].x, prim->param.pathf.points[n+1].y); cdfCanvasVertex(canvas, prim->param.pathf.points[n+2].x, 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, prim->param.imagergba.x, prim->param.imagergba.y, prim->param.imagergba.w, prim->param.imagergba.h, 0, 0, 0, 0); break; case CDPIC_IMAGERGBA: cdCanvasPutImageRectRGBA(canvas, prim->param.imagergba.iw, prim->param.imagergba.ih, prim->param.imagergba.r, prim->param.imagergba.g, prim->param.imagergba.b, prim->param.imagergba.a, prim->param.imagergba.x, prim->param.imagergba.y, prim->param.imagergba.w, prim->param.imagergba.h, 0, 0, 0, 0); break; case CDPIC_IMAGEMAP: cdCanvasPutImageRectMap(canvas, prim->param.imagemap.iw, prim->param.imagemap.ih, prim->param.imagemap.index, prim->param.imagemap.colors, prim->param.imagemap.x, prim->param.imagemap.y, prim->param.imagemap.w, prim->param.imagemap.h, 0, 0, 0, 0); break; case CDPIC_PIXEL: cdCanvasPixel(canvas, prim->param.pixel.x, prim->param.pixel.y, prim->param.pixel.color); break; } } prim = prim->next; } return CD_OK; } static void cdkillcanvas(cdCtxCanvas *ctxcanvas) { cdclear(ctxcanvas); memset(ctxcanvas, 0, sizeof(cdCtxCanvas)); free(ctxcanvas); } /*******************/ /* Canvas Creation */ /*******************/ static void cdcreatecanvas(cdCanvas *canvas, void *data) { char* strdata = (char*)data; double res = 3.78; cdCtxCanvas* ctxcanvas; sscanf(strdata, "%lg", &res); ctxcanvas = (cdCtxCanvas *)malloc(sizeof(cdCtxCanvas)); memset(ctxcanvas, 0, sizeof(cdCtxCanvas)); ctxcanvas->canvas = canvas; canvas->ctxcanvas = ctxcanvas; /* update canvas context */ canvas->w = 0; canvas->h = 0; canvas->w_mm = 0; canvas->h_mm = 0; canvas->bpp = 24; canvas->xres = res; canvas->yres = res; } static void cdinittable(cdCanvas* canvas) { canvas->cxFont = cdfont; canvas->cxClear = cdclear; canvas->cxPixel = cdpixel; canvas->cxLine = cdline; canvas->cxFLine = cdfline; canvas->cxRect = cdrect; canvas->cxFRect = cdfrect; canvas->cxBox = cdbox; canvas->cxFBox = cdfbox; canvas->cxArc = cdarc; canvas->cxFArc = cdfarc; canvas->cxSector = cdsector; canvas->cxFSector = cdfsector; canvas->cxChord = cdchord; canvas->cxFChord = cdfchord; canvas->cxText = cdtext; canvas->cxFText = cdftext; canvas->cxPoly = cdpoly; canvas->cxFPoly = cdfpoly; canvas->cxPutImageRectRGB = cdputimagerectrgb; canvas->cxPutImageRectRGBA = cdputimagerectrgba; canvas->cxPutImageRectMap = cdputimagerectmap; canvas->cxKillCanvas = cdkillcanvas; } static cdContext cdPictureContext = { CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_REGION | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE), 0, CD_CTX_DEVICE, cdcreatecanvas, cdinittable, cdplay, cdregistercallback, }; cdContext* cdContextPicture(void) { return &cdPictureContext; }