summaryrefslogtreecommitdiff
path: root/src/drv/cdpicture.c
diff options
context:
space:
mode:
authorscuri <scuri>2008-10-17 06:10:33 +0000
committerscuri <scuri>2008-10-17 06:10:33 +0000
commit7b52cc13af4e85f1ca2deb6b6c77de9c95ea0dcf (patch)
treed0857278bde2eff784227c57dcaf930346ceb7ac /src/drv/cdpicture.c
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/drv/cdpicture.c')
-rw-r--r--src/drv/cdpicture.c1133
1 files changed, 1133 insertions, 0 deletions
diff --git a/src/drv/cdpicture.c b/src/drv/cdpicture.c
new file mode 100644
index 0000000..9bc5104
--- /dev/null
+++ b/src/drv/cdpicture.c
@@ -0,0 +1,1133 @@
+/** \file
+ * \brief CD Picture driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+
+#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_FLINE,
+ CDPIC_FRECT,
+ CDPIC_FBOX,
+ CDPIC_FARC,
+ CDPIC_FSECTOR,
+ CDPIC_FCHORD,
+ CDPIC_FTEXT,
+ CDPIC_FPOLY,
+ 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 _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;
+ 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 = strdup(canvas->native_font);
+ prim->attrib.text.native_font = prim->attrib_buffer;
+ }
+ else
+ {
+ prim->attrib_buffer = strdup(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 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);
+ cdCanvasGetEllipseBox(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);
+ cdCanvasGetEllipseBox(_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);
+ cdCanvasGetEllipseBox(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);
+ cdCanvasGetEllipseBox(_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);
+ cdCanvasGetEllipseBox(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);
+ cdCanvasGetEllipseBox(_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 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 = strdup(text);
+ prim->param_buffer = prim->param.text.s;
+ picAddPrim(ctxcanvas, prim);
+ cdCanvasGetTextBox(ctxcanvas->canvas, x, y, text, &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 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 = strdup(text);
+ prim->param_buffer = prim->param.textf.s;
+ picAddPrim(ctxcanvas, prim);
+ cdCanvasGetTextBox(ctxcanvas->canvas, _cdRound(x), _cdRound(y), text, &xmin, &xmax, &ymin, &ymax);
+ picUpdateBBox(ctxcanvas, xmin, ymin, 0);
+ picUpdateBBox(ctxcanvas, xmax, ymax, 0);
+}
+
+static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
+{
+ int i;
+ tPrimNode *prim;
+ if (mode == CD_CLIP || mode == CD_REGION) return;
+ prim = primCreate(CDPIC_POLY);
+ if (mode == CD_FILL)
+ primAddAttrib_Fill(prim, ctxcanvas->canvas);
+ else
+ primAddAttrib_Line(prim, ctxcanvas->canvas);
+ 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 cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
+{
+ int i;
+ tPrimNode *prim;
+ if (mode == CD_CLIP || mode == CD_REGION) return;
+ prim = primCreate(CDPIC_FPOLY);
+ if (mode == CD_FILL)
+ primAddAttrib_Fill(prim, ctxcanvas->canvas);
+ else
+ primAddAttrib_Line(prim, ctxcanvas->canvas);
+ prim->param.polyf.n = n;
+ prim->param.polyf.points = malloc(n * sizeof(cdPoint));
+ memcpy(prim->param.polyf.points, poly, n * sizeof(cdPoint));
+ 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, 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_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_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->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,
+ cdcreatecanvas,
+ cdinittable,
+ cdplay,
+ cdregistercallback,
+};
+
+cdContext* cdContextPicture(void)
+{
+ return &cdPictureContext;
+}