summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2010-09-09 01:48:52 +0200
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2010-09-09 01:50:25 +0200
commite9a184546b18cf3b796bd560561f312934004c54 (patch)
treeaa785af9a8d03f8ce276c9e9ecec78397005ec22
parent92efe73791d0998536042bfab5a1babc67d168c7 (diff)
Upgrading to CD 5.4 - and cleaning up.
-rwxr-xr-xcd/include/cd.h56
-rwxr-xr-xcd/include/cd_private.h24
-rw-r--r--cd/include/cdcairo.h45
-rw-r--r--cd/include/cdgl.h23
-rwxr-xr-xcd/include/cdlua.h1
-rwxr-xr-xcd/include/cdlua5_private.h3
-rw-r--r--cd/include/cdluagl.h27
-rwxr-xr-xcd/include/cdpdf.h15
-rwxr-xr-xcd/include/cdps.h14
-rwxr-xr-xcd/mak.vc8/cd.sln155
-rwxr-xr-xcd/mak.vc8/cd.vcproj623
-rwxr-xr-xcd/mak.vc8/cd_freetype.vcproj275
-rwxr-xr-xcd/mak.vc8/cd_pdflib.vcproj733
-rwxr-xr-xcd/mak.vc8/cdgdiplus.vcproj135
-rw-r--r--cd/mak.vc8/cdgdk.vcproj603
-rwxr-xr-xcd/mak.vc8/cdlua3.vcproj131
-rwxr-xr-xcd/mak.vc8/cdlua5.vcproj131
-rwxr-xr-xcd/mak.vc8/cdluacontextplus5.vcproj106
-rwxr-xr-xcd/mak.vc8/cdluaim5.vcproj111
-rwxr-xr-xcd/mak.vc8/cdluapdf3.vcproj106
-rwxr-xr-xcd/mak.vc8/cdluapdf5.vcproj106
-rwxr-xr-xcd/mak.vc8/cdpdf.vcproj108
-rw-r--r--cd/mak.vc8/cdsimple.vcproj133
-rw-r--r--cd/mak.vc8/cdsimplegdk.vcproj133
-rw-r--r--cd/mak.vc8/cdtest.vcproj161
-rwxr-xr-xcd/mak.vc8/cdx11.vcproj141
-rwxr-xr-xcd/mak.vc8/cdxrender.vcproj103
-rw-r--r--cd/src/cairo/cdcairo.c2110
-rw-r--r--cd/src/cairo/cdcairo.def9
-rw-r--r--cd/src/cairo/cdcairoctx.h88
-rw-r--r--cd/src/cairo/cdcairodbuf.c169
-rw-r--r--cd/src/cairo/cdcairoemf.c122
-rw-r--r--cd/src/cairo/cdcairoimg.c51
-rw-r--r--cd/src/cairo/cdcairoirgb.c159
-rw-r--r--cd/src/cairo/cdcaironative_gdk.c80
-rw-r--r--cd/src/cairo/cdcaironative_win32.c160
-rw-r--r--cd/src/cairo/cdcaironative_x11.c98
-rw-r--r--cd/src/cairo/cdcairopdf.c122
-rw-r--r--cd/src/cairo/cdcairoplus.c30
-rw-r--r--cd/src/cairo/cdcairoprn_unix.c196
-rw-r--r--cd/src/cairo/cdcairoprn_win32.c194
-rw-r--r--cd/src/cairo/cdcairops.c172
-rw-r--r--cd/src/cairo/cdcairosvg.c83
-rwxr-xr-xcd/src/cd.c32
-rwxr-xr-xcd/src/cd.def34
-rwxr-xr-xcd/src/cd_image.c28
-rwxr-xr-xcd/src/cd_primitives.c208
-rwxr-xr-xcd/src/cd_text.c2
-rwxr-xr-xcd/src/cd_util.c144
-rwxr-xr-xcd/src/drv/cd0emf.c8
-rwxr-xr-xcd/src/drv/cd0prn.c8
-rwxr-xr-xcd/src/drv/cdcgm.c14
-rwxr-xr-xcd/src/drv/cddebug.c125
-rwxr-xr-xcd/src/drv/cddgn.c13
-rwxr-xr-xcd/src/drv/cddxf.c206
-rw-r--r--cd/src/drv/cdgl.c1559
-rwxr-xr-xcd/src/drv/cdirgb.c235
-rwxr-xr-xcd/src/drv/cdmf.c93
-rwxr-xr-xcd/src/drv/cdpdf.c399
-rwxr-xr-xcd/src/drv/cdpicture.c284
-rwxr-xr-xcd/src/drv/cdps.c486
-rwxr-xr-xcd/src/drv/cgm.c4
-rwxr-xr-xcd/src/gdiplus/cdwclpp.cpp6
-rwxr-xr-xcd/src/gdiplus/cdwdbufp.cpp5
-rwxr-xr-xcd/src/gdiplus/cdwemfp.cpp3
-rwxr-xr-xcd/src/gdiplus/cdwimgp.cpp3
-rwxr-xr-xcd/src/gdiplus/cdwinp.cpp596
-rwxr-xr-xcd/src/gdiplus/cdwinp.h5
-rwxr-xr-xcd/src/gdiplus/cdwnativep.cpp3
-rwxr-xr-xcd/src/gdiplus/cdwprnp.cpp1
-rw-r--r--cd/src/gdk/cdgdk.c196
-rw-r--r--cd/src/gdk/cdgdk.h2
-rw-r--r--cd/src/gdk/cdgdkclp.c2
-rw-r--r--cd/src/gdk/cdgdkdbuf.c3
-rw-r--r--cd/src/gdk/cdgdkimg.c2
-rw-r--r--cd/src/gdk/cdgdknative.c2
-rwxr-xr-xcd/src/lua5/cdlua5.c20
-rwxr-xr-xcd/src/lua5/cdlua5.def1
-rwxr-xr-xcd/src/lua5/cdlua5_canvas.c45
-rwxr-xr-xcd/src/lua5/cdlua5ctx.c67
-rwxr-xr-xcd/src/lua5/cdluacontextplus5.c5
-rwxr-xr-xcd/src/lua5/cdluacontextplus5.def1
-rwxr-xr-xcd/src/lua5/cdluaim5.c5
-rwxr-xr-xcd/src/lua5/cdluaim5.def1
-rwxr-xr-xcd/src/lua5/cdluapdf5.c8
-rwxr-xr-xcd/src/lua5/cdluapdf5.def1
-rwxr-xr-xcd/src/lua5/cdvoid5.c6
-rwxr-xr-xcd/src/make_uname17
-rwxr-xr-xcd/src/sim/sim.c53
-rwxr-xr-xcd/src/sim/sim.h6
-rwxr-xr-xcd/src/sim/sim_linepolyfill.c98
-rwxr-xr-xcd/src/sim/sim_other.c411
-rwxr-xr-xcd/src/sim/sim_primitives.c1562
-rwxr-xr-xcd/src/sim/truetype.h46
-rw-r--r--cd/src/svg/cdsvg.c920
-rwxr-xr-xcd/src/win32/cdwdbuf.c1
-rwxr-xr-xcd/src/win32/cdwdib.c38
-rwxr-xr-xcd/src/win32/cdwin.c313
-rwxr-xr-xcd/src/win32/cdwin.h1
-rwxr-xr-xcd/src/win32/cdwnative.c11
-rwxr-xr-xcd/src/x11/cdx11.c21
-rwxr-xr-xcd/src/x11/cdxclp.c2
-rwxr-xr-xcd/src/x11/cdxdbuf.c3
-rwxr-xr-xcd/src/x11/cdximg.c2
-rwxr-xr-xcd/src/x11/cdxnative.c2
-rwxr-xr-xcd/src/xrender/cdxrender.c117
-rwxr-xr-xcd/test/cdtest/cdtest.c2
-rwxr-xr-xcd/test/cdtest/drivers.c2
-rwxr-xr-xcd/test/simple/config.mak52
-rwxr-xr-xcd/test/simple/gdiplustest.cpp116
-rwxr-xr-xcd/test/simple/iupmain.c81
-rwxr-xr-xcd/test/simple/simple.c1061
-rwxr-xr-xcd/test/simple/simple.h14
-rwxr-xr-xcd/test/simple/simple.led11
-rwxr-xr-xcd/test/simple/simple_led.c52
115 files changed, 11210 insertions, 6721 deletions
diff --git a/cd/include/cd.h b/cd/include/cd.h
index ca38983..85b02c2 100755
--- a/cd/include/cd.h
+++ b/cd/include/cd.h
@@ -19,9 +19,9 @@ extern "C" {
#define CD_NAME "CD - Canvas Draw"
#define CD_DESCRIPTION "A 2D Graphics Library"
#define CD_COPYRIGHT "Copyright (C) 1994-2010 Tecgraf, PUC-Rio."
-#define CD_VERSION "5.3" /* bug fixes are reported only by cdVersion functions */
-#define CD_VERSION_NUMBER 503000
-#define CD_VERSION_DATE "2010/01/26"
+#define CD_VERSION "5.4" /* bug fixes are reported only by cdVersion functions */
+#define CD_VERSION_NUMBER 504000
+#define CD_VERSION_DATE "2010/06/24" /* does not include bug fix releases */
typedef struct _cdContext cdContext;
typedef struct _cdCanvas cdCanvas;
@@ -113,10 +113,12 @@ int cdCanvasRegionCombineMode(cdCanvas* canvas, int mode);
void cdCanvasPixel(cdCanvas* canvas, int x, int y, long color);
void cdCanvasMark(cdCanvas* canvas, int x, int y);
-void cdCanvasLine(cdCanvas* canvas, int x1, int y1, int x2, int y2);
void cdCanvasBegin(cdCanvas* canvas, int mode);
-void cdCanvasVertex(cdCanvas* canvas, int x, int y);
+void cdCanvasPathSet(cdCanvas* canvas, int action);
void cdCanvasEnd(cdCanvas* canvas);
+
+void cdCanvasLine(cdCanvas* canvas, int x1, int y1, int x2, int y2);
+void cdCanvasVertex(cdCanvas* canvas, int x, int y);
void cdCanvasRect(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax);
void cdCanvasBox(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax);
void cdCanvasArc(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1, double angle2);
@@ -152,7 +154,7 @@ unsigned char* cdCanvasGetStipple(cdCanvas* canvas, int *n, int *m);
void cdCanvasPattern(cdCanvas* canvas, int w, int h, long const int *pattern);
long* cdCanvasGetPattern(cdCanvas* canvas, int* n, int* m);
int cdCanvasFillMode(cdCanvas* canvas, int mode);
-int cdCanvasFont(cdCanvas* canvas, const char* type_face, int style, int size);
+int cdCanvasFont(cdCanvas* canvas, const char* type_face, int style, int size);
void cdCanvasGetFont(cdCanvas* canvas, char *type_face, int *style, int *size);
char* cdCanvasNativeFont(cdCanvas* canvas, const char* font);
int cdCanvasTextAlignment(cdCanvas* canvas, int alignment);
@@ -165,13 +167,13 @@ void cdCanvasVectorText(cdCanvas* canvas, int x, int y, const char* s);
void cdCanvasMultiLineVectorText(cdCanvas* canvas, int x, int y, const char* s);
/* vector text attributes */
-char *cdCanvasVectorFont(cdCanvas* canvas, const char *filename);
-void cdCanvasVectorTextDirection(cdCanvas* canvas, int x1, int y1, int x2, int y2);
+char* cdCanvasVectorFont(cdCanvas* canvas, const char *filename);
+void cdCanvasVectorTextDirection(cdCanvas* canvas, int x1, int y1, int x2, int y2);
double* cdCanvasVectorTextTransform(cdCanvas* canvas, const double* matrix);
-void cdCanvasVectorTextSize(cdCanvas* canvas, int size_x, int size_y, const char* s);
-int cdCanvasVectorCharSize(cdCanvas* canvas, int size);
-void cdCanvasVectorFontSize(cdCanvas* canvas, double size_x, double size_y);
-void cdCanvasGetVectorFontSize(cdCanvas* canvas, double *size_x, double *size_y);
+void cdCanvasVectorTextSize(cdCanvas* canvas, int size_x, int size_y, const char* s);
+int cdCanvasVectorCharSize(cdCanvas* canvas, int size);
+void cdCanvasVectorFontSize(cdCanvas* canvas, double size_x, double size_y);
+void cdCanvasGetVectorFontSize(cdCanvas* canvas, double *size_x, double *size_y);
/* vector text properties */
void cdCanvasGetVectorTextSize(cdCanvas* canvas, const char* s, int *x, int *y);
@@ -271,11 +273,25 @@ enum { /* polygon mode (begin...end) */
CD_CLOSED_LINES,
CD_CLIP,
CD_BEZIER,
- CD_REGION
+ CD_REGION,
+ CD_PATH
};
#define CD_POLYCUSTOM 10
+enum { /* path actions */
+ CD_PATH_NEW,
+ CD_PATH_MOVETO,
+ CD_PATH_LINETO,
+ CD_PATH_ARC,
+ CD_PATH_CURVETO,
+ CD_PATH_CLOSE,
+ CD_PATH_FILL,
+ CD_PATH_STROKE,
+ CD_PATH_FILLSTROKE,
+ CD_PATH_CLIP
+};
+
enum { /* fill mode */
CD_EVENODD,
CD_WINDING
@@ -410,6 +426,8 @@ enum { /* some font sizes */
#define CD_CAP_PALETTE 0x08000000
#define CD_CAP_LINECAP 0x10000000
#define CD_CAP_LINEJOIN 0x20000000
+#define CD_CAP_PATH 0x40000000
+#define CD_CAP_BEZIER 0x80000000
#define CD_CAP_ALL 0xFFFFFFFF
/* cdPlay definitions */
@@ -459,6 +477,18 @@ typedef int(*cdSizeCB)(cdCanvas *canvas, int w, int h, double w_mm, double h_mm)
#define CD_RAD2DEG 57.295779513 /* radians to degrees (deg = CD_RAD2DEG * rad) */
#define CD_DEG2RAD 0.01745329252 /* degrees to radians (rad = CD_DEG2RAD * deg) */
+/* paper sizes */
+enum {
+ CD_A0,
+ CD_A1,
+ CD_A2,
+ CD_A3,
+ CD_A4,
+ CD_A5,
+ CD_LETTER,
+ CD_LEGAL
+};
+
#ifdef __cplusplus
}
diff --git a/cd/include/cd_private.h b/cd/include/cd_private.h
index b9a3243..6138f60 100755
--- a/cd/include/cd_private.h
+++ b/cd/include/cd_private.h
@@ -215,9 +215,13 @@ struct _cdCanvas
cdfPoint* fpoly; /* used during an real poligon creation, only if ->fPoly exists */
int use_fpoly;
+ /* last path */
+ int path_n, /* current number of actions */
+ path_size; /* allocated number of actions, only increases */
+ int* path; /* used during path creation */
+
/* simulation flags */
int sim_mode;
- int sim_poly;
/* WC */
double s, sx, tx, sy, ty; /* Transformacao Window -> Viewport (scale+translation)*/
@@ -264,15 +268,25 @@ enum{CD_CTX_NATIVEWINDOW, CD_CTX_IMAGE, CD_CTX_DBUFFER, CD_CTX_PRINTER, CD_CTX_E
/* utilities */
/*************/
int cdRound(double x);
-void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax);
int cdCheckBoxSize(int *xmin, int *xmax, int *ymin, int *ymax);
int cdfCheckBoxSize(double *xmin, double *xmax, double *ymin, double *ymax);
void cdNormalizeLimits(int w, int h, int *xmin, int *xmax, int *ymin, int *ymax);
int cdGetFileName(const char* strdata, char* filename);
int cdStrEqualNoCase(const char* str1, const char* str2);
+int cdStrEqualNoCasePartial(const char* str1, const char* str2);
int cdStrLineCount(const char* str);
char* cdStrDup(const char* str);
char* cdStrDupN(const char* str, int len);
+void cdSetPaperSize(int size, double *w_pt, double *h_pt);
+int cdGetFontFileName(const char* font, char* filename);
+
+void cdCanvasPoly(cdCanvas* canvas, int mode, cdPoint* points, int n);
+void cdCanvasGetArcBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax);
+int cdCanvasGetArcPathF(cdCanvas* canvas, const cdPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2);
+int cdfCanvasGetArcPath(cdCanvas* canvas, const cdfPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2);
+int cdCanvasGetArcPath(cdCanvas* canvas, const cdPoint* poly, int *xc, int *yc, int *w, int *h, double *a1, double *a2);
+void cdCanvasGetArcStartEnd(int xc, int yc, int w, int h, double a1, double a2, int *x1, int *y1, int *x2, int *y2);
+void cdfCanvasGetArcStartEnd(double xc, double yc, double w, double h, double a1, double a2, double *x1, double *y1, double *x2, double *y2);
#define _cdCheckCanvas(_canvas) (_canvas!=NULL && ((unsigned char*)_canvas)[0] == 'C' && ((unsigned char*)_canvas)[1] == 'D')
#define _cdInvertYAxis(_canvas, _y) (_canvas->h - (_y) - 1)
@@ -288,6 +302,7 @@ void cdMatrixTransformPoint(double* matrix, int x, int y, int *rx, int *ry);
void cdfMatrixTransformPoint(double* matrix, double x, double y, double *rx, double *ry);
void cdMatrixMultiply(const double* matrix, double* mul_matrix);
void cdMatrixInverse(const double* matrix, double* inv_matrix);
+void cdfRotatePoint(cdCanvas* canvas, double x, double y, double cx, double cy, double *rx, double *ry, double sin_theta, double cos_theta);
void cdRotatePoint(cdCanvas* canvas, int x, int y, int cx, int cy, int *rx, int *ry, double sin_teta, double cos_teta);
void cdRotatePointY(cdCanvas* canvas, int x, int y, int cx, int cy, int *ry, double sin_theta, double cos_theta);
void cdTextTranslatePoint(cdCanvas* canvas, int x, int y, int w, int h, int baseline, int *rx, int *ry);
@@ -303,6 +318,11 @@ int cdParseXWinFont(const char *nativefont, char *type_face, int *style, int *si
int cdGetFontSizePixels(cdCanvas* canvas, int size);
int cdGetFontSizePoints(cdCanvas* canvas, int size);
+/* Replacements for Font using estimation */
+/* cdfontex.c */
+void cdgetfontdimEX(cdCtxCanvas* ctxcanvas, int *max_width, int *height, int *ascent, int *descent);
+void cdgettextsizeEX(cdCtxCanvas* ctxcanvas, const char *s, int len, int *width, int *height);
+
/****************/
/* For Images */
/****************/
diff --git a/cd/include/cdcairo.h b/cd/include/cdcairo.h
new file mode 100644
index 0000000..81d54dc
--- /dev/null
+++ b/cd/include/cdcairo.h
@@ -0,0 +1,45 @@
+/** \file
+ * \brief Cairo extra drivers.
+ * Rendering PDF, PS, SVG and IMAGERGB.
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#ifndef __CD_CAIRO_H
+#define __CD_CAIRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Some of these context can be used directly or by cdInitContextPlus,
+ as CD_NATIVEWINDOW, CD_IMAGE, CD_EMF, CD_PRINTER and CD_DBUFFER.
+ The others only directly.
+*/
+
+cdContext* cdContextCairoNativeWindow(void);
+cdContext* cdContextCairoImage(void);
+cdContext* cdContextCairoDBuffer(void);
+cdContext* cdContextCairoPrinter(void);
+cdContext* cdContextCairoPS(void);
+cdContext* cdContextCairoPDF(void);
+cdContext* cdContextCairoSVG(void);
+cdContext* cdContextCairoImageRGB(void);
+cdContext* cdContextCairoEMF(void);
+
+#define CD_CAIRO_NATIVEWINDOW cdContextCairoNativeWindow()
+#define CD_CAIRO_IMAGE cdContextCairoImage()
+#define CD_CAIRO_DBUFFER cdContextCairoDBuffer()
+#define CD_CAIRO_PRINTER cdContextCairoPrinter()
+#define CD_CAIRO_PS cdContextCairoPS()
+#define CD_CAIRO_PDF cdContextCairoPDF()
+#define CD_CAIRO_SVG cdContextCairoSVG()
+#define CD_CAIRO_IMAGERGB cdContextCairoImageRGB()
+#define CD_CAIRO_EMF cdContextCairoEMF()
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef __CD_CAIRO_ */
diff --git a/cd/include/cdgl.h b/cd/include/cdgl.h
new file mode 100644
index 0000000..946268a
--- /dev/null
+++ b/cd/include/cdgl.h
@@ -0,0 +1,23 @@
+/** \file
+* \brief OpenGL driver
+*
+* See Copyright Notice in cd.h
+*/
+
+#ifndef __CD_GL_H
+#define __CD_GL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+cdContext* cdContextGL(void);
+
+#define CD_GL cdContextGL()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef __CD_GL_ */
+
diff --git a/cd/include/cdlua.h b/cd/include/cdlua.h
index 30d8174..a353dd8 100755
--- a/cd/include/cdlua.h
+++ b/cd/include/cdlua.h
@@ -29,6 +29,7 @@ int cdlua_close(lua_State *L);
cdCanvas* cdlua_getcanvas(lua_State * L); /* pos=1, deprecated use cdlua_checkcanvas */
cdCanvas* cdlua_checkcanvas(lua_State * L, int pos);
void cdlua_pushcanvas(lua_State * L, cdCanvas* canvas);
+
#endif
#ifdef __cplusplus
diff --git a/cd/include/cdlua5_private.h b/cd/include/cdlua5_private.h
index 974fb4e..3051fb6 100755
--- a/cd/include/cdlua5_private.h
+++ b/cd/include/cdlua5_private.h
@@ -133,6 +133,9 @@ void cdlua_pushbitmap(lua_State* L, cdBitmap* bitmap);
void cdlua_pushimagergb_ex(lua_State* L, unsigned char* red, unsigned char* green, unsigned char* blue, int width, int height);
void cdlua_pushimagergba_ex(lua_State* L, unsigned char* red, unsigned char* green, unsigned char* blue, unsigned char* alpha, int width, int height);
+#if LUA_VERSION_NUM < 502
+#define luaL_typeerror luaL_typerror
+#endif
#ifdef __cplusplus
}
diff --git a/cd/include/cdluagl.h b/cd/include/cdluagl.h
new file mode 100644
index 0000000..412d745
--- /dev/null
+++ b/cd/include/cdluagl.h
@@ -0,0 +1,27 @@
+/** \file
+ * \brief OpenGL Canvas Lua Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#ifndef __CD_LUAGL_H
+#define __CD_LUAGL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LUA_NOOBJECT /* Lua 3 */
+void cdluagl_open(void);
+#endif
+
+#ifdef LUA_TNONE /* Lua 5 */
+int cdluagl_open(lua_State *L);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/cd/include/cdpdf.h b/cd/include/cdpdf.h
index 70d6df5..89486fc 100755
--- a/cd/include/cdpdf.h
+++ b/cd/include/cdpdf.h
@@ -15,21 +15,6 @@ cdContext* cdContextPDF(void);
#define CD_PDF cdContextPDF()
-#ifndef CD_PAPERSIZE
-#define CD_PAPERSIZE
-enum { /* paper sizes */
- CD_A0,
- CD_A1,
- CD_A2,
- CD_A3,
- CD_A4,
- CD_A5,
- CD_LETTER,
- CD_LEGAL
-};
-#endif
-
-
#ifdef __cplusplus
}
#endif
diff --git a/cd/include/cdps.h b/cd/include/cdps.h
index 180ebad..0f4bdd8 100755
--- a/cd/include/cdps.h
+++ b/cd/include/cdps.h
@@ -15,20 +15,6 @@ cdContext* cdContextPS(void);
#define CD_PS cdContextPS()
-#ifndef CD_PAPERSIZE
-#define CD_PAPERSIZE
-enum { /* paper sizes */
- CD_A0,
- CD_A1,
- CD_A2,
- CD_A3,
- CD_A4,
- CD_A5,
- CD_LETTER,
- CD_LEGAL
-};
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/cd/mak.vc8/cd.sln b/cd/mak.vc8/cd.sln
deleted file mode 100755
index 9a76053..0000000
--- a/cd/mak.vc8/cd.sln
+++ /dev/null
@@ -1,155 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cd", "cd.vcproj", "{01818D2C-65AF-4D5C-9452-4DFF401C6461}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-AFDC-4356-1234401C6461} = {01818D2C-65AF-AFDC-4356-1234401C6461}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdlua3", "cdlua3.vcproj", "{53FC9752-81C1-4AA6-B366-AF6D0A2B81F6}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-4D5C-9452-4DFF401C6461} = {01818D2C-65AF-4D5C-9452-4DFF401C6461}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdgdiplus", "cdgdiplus.vcproj", "{51A96255-7EAB-4F36-A6E5-1BAF6245FA18}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-4D5C-9452-4DFF401C6461} = {01818D2C-65AF-4D5C-9452-4DFF401C6461}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdlua5", "cdlua5.vcproj", "{53FC9752-81C1-4AA6-B366-A7890A2B81F6}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-4D5C-9452-4DFF401C6461} = {01818D2C-65AF-4D5C-9452-4DFF401C6461}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdpdf", "cdpdf.vcproj", "{8441F69D-7135-43B2-974F-45C6123C8467}"
- ProjectSection(ProjectDependencies) = postProject
- {8441F69D-7135-ABCD-1234-45C6123C8467} = {8441F69D-7135-ABCD-1234-45C6123C8467}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdx11", "cdx11.vcproj", "{01818D2C-7689-4D5C-1234-4DFF401C6461}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdluapdf3", "cdluapdf3.vcproj", "{B4823266-DF8C-AAAA-9999-C7E78C234EAC}"
- ProjectSection(ProjectDependencies) = postProject
- {53FC9752-81C1-4AA6-B366-AF6D0A2B81F6} = {53FC9752-81C1-4AA6-B366-AF6D0A2B81F6}
- {8441F69D-7135-43B2-974F-45C6123C8467} = {8441F69D-7135-43B2-974F-45C6123C8467}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdluapdf5", "cdluapdf5.vcproj", "{B4823266-DF8C-1224-EE00-C7688C234EAC}"
- ProjectSection(ProjectDependencies) = postProject
- {53FC9752-81C1-4AA6-B366-A7890A2B81F6} = {53FC9752-81C1-4AA6-B366-A7890A2B81F6}
- {8441F69D-7135-43B2-974F-45C6123C8467} = {8441F69D-7135-43B2-974F-45C6123C8467}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdxrender", "cdxrender.vcproj", "{160DEDA5-C1AA-48C7-8B07-490C6A8DE2EE}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdluaim5", "cdluaim5.vcproj", "{CB863607-6B6C-0000-0000-123400001234}"
- ProjectSection(ProjectDependencies) = postProject
- {53FC9752-81C1-4AA6-B366-A7890A2B81F6} = {53FC9752-81C1-4AA6-B366-A7890A2B81F6}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pdflib", "cd_pdflib.vcproj", "{8441F69D-7135-ABCD-1234-45C6123C8467}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype6", "cd_freetype.vcproj", "{01818D2C-65AF-AFDC-4356-1234401C6461}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdluacontextplus5", "cdluacontextplus5.vcproj", "{B4823266-DF8C-ABCD-1234-C7688C234EAC}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lua5", "Lua5", "{EFB1BE3C-2981-456B-8E32-928CBDFF7822}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lua3", "Lua3", "{E92DB6FF-5501-4FC0-81D2-00DB8EFA2434}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{162715BD-4DB3-4007-8B50-725C0BD11878}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdtest", "cdtest.vcproj", "{A7E49FB8-700A-45EC-9174-FB1C2C7E83C9}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-4D5C-9452-4DFF401C6461} = {01818D2C-65AF-4D5C-9452-4DFF401C6461}
- {51A96255-7EAB-4F36-A6E5-1BAF6245FA18} = {51A96255-7EAB-4F36-A6E5-1BAF6245FA18}
- {8441F69D-7135-43B2-974F-45C6123C8467} = {8441F69D-7135-43B2-974F-45C6123C8467}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdsimple", "cdsimple.vcproj", "{82BC36B1-9F7A-41D4-A24F-DBE012378CE6}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-65AF-4D5C-9452-4DFF401C6461} = {01818D2C-65AF-4D5C-9452-4DFF401C6461}
- {51A96255-7EAB-4F36-A6E5-1BAF6245FA18} = {51A96255-7EAB-4F36-A6E5-1BAF6245FA18}
- {8441F69D-7135-43B2-974F-45C6123C8467} = {8441F69D-7135-43B2-974F-45C6123C8467}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdgdk", "cdgdk.vcproj", "{01818D2C-AAAA-4D5C-ABCD-1234401C6461}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdsimplegdk", "cdsimplegdk.vcproj", "{82BC36B1-DDDD-41D4-ABCD-A12312378CE6}"
- ProjectSection(ProjectDependencies) = postProject
- {01818D2C-AAAA-4D5C-ABCD-1234401C6461} = {01818D2C-AAAA-4D5C-ABCD-1234401C6461}
- {8441F69D-7135-43B2-974F-45C6123C8467} = {8441F69D-7135-43B2-974F-45C6123C8467}
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {01818D2C-65AF-4D5C-9452-4DFF401C6461}.Debug|Win32.ActiveCfg = Debug|Win32
- {01818D2C-65AF-4D5C-9452-4DFF401C6461}.Debug|Win32.Build.0 = Debug|Win32
- {53FC9752-81C1-4AA6-B366-AF6D0A2B81F6}.Debug|Win32.ActiveCfg = Debug|Win32
- {53FC9752-81C1-4AA6-B366-AF6D0A2B81F6}.Debug|Win32.Build.0 = Debug|Win32
- {51A96255-7EAB-4F36-A6E5-1BAF6245FA18}.Debug|Win32.ActiveCfg = Debug|Win32
- {51A96255-7EAB-4F36-A6E5-1BAF6245FA18}.Debug|Win32.Build.0 = Debug|Win32
- {53FC9752-81C1-4AA6-B366-A7890A2B81F6}.Debug|Win32.ActiveCfg = Debug|Win32
- {53FC9752-81C1-4AA6-B366-A7890A2B81F6}.Debug|Win32.Build.0 = Debug|Win32
- {8441F69D-7135-43B2-974F-45C6123C8467}.Debug|Win32.ActiveCfg = Debug|Win32
- {8441F69D-7135-43B2-974F-45C6123C8467}.Debug|Win32.Build.0 = Debug|Win32
- {01818D2C-7689-4D5C-1234-4DFF401C6461}.Debug|Win32.ActiveCfg = Debug|Win32
- {B4823266-DF8C-AAAA-9999-C7E78C234EAC}.Debug|Win32.ActiveCfg = Debug|Win32
- {B4823266-DF8C-AAAA-9999-C7E78C234EAC}.Debug|Win32.Build.0 = Debug|Win32
- {B4823266-DF8C-1224-EE00-C7688C234EAC}.Debug|Win32.ActiveCfg = Debug|Win32
- {B4823266-DF8C-1224-EE00-C7688C234EAC}.Debug|Win32.Build.0 = Debug|Win32
- {160DEDA5-C1AA-48C7-8B07-490C6A8DE2EE}.Debug|Win32.ActiveCfg = Debug|Win32
- {CB863607-6B6C-0000-0000-123400001234}.Debug|Win32.ActiveCfg = Debug|Win32
- {CB863607-6B6C-0000-0000-123400001234}.Debug|Win32.Build.0 = Debug|Win32
- {8441F69D-7135-ABCD-1234-45C6123C8467}.Debug|Win32.ActiveCfg = Debug|Win32
- {8441F69D-7135-ABCD-1234-45C6123C8467}.Debug|Win32.Build.0 = Debug|Win32
- {01818D2C-65AF-AFDC-4356-1234401C6461}.Debug|Win32.ActiveCfg = Debug|Win32
- {01818D2C-65AF-AFDC-4356-1234401C6461}.Debug|Win32.Build.0 = Debug|Win32
- {B4823266-DF8C-ABCD-1234-C7688C234EAC}.Debug|Win32.ActiveCfg = Debug|Win32
- {B4823266-DF8C-ABCD-1234-C7688C234EAC}.Debug|Win32.Build.0 = Debug|Win32
- {A7E49FB8-700A-45EC-9174-FB1C2C7E83C9}.Debug|Win32.ActiveCfg = Debug|Win32
- {A7E49FB8-700A-45EC-9174-FB1C2C7E83C9}.Debug|Win32.Build.0 = Debug|Win32
- {82BC36B1-9F7A-41D4-A24F-DBE012378CE6}.Debug|Win32.ActiveCfg = Debug|Win32
- {82BC36B1-9F7A-41D4-A24F-DBE012378CE6}.Debug|Win32.Build.0 = Debug|Win32
- {01818D2C-AAAA-4D5C-ABCD-1234401C6461}.Debug|Win32.ActiveCfg = Debug|Win32
- {01818D2C-AAAA-4D5C-ABCD-1234401C6461}.Debug|Win32.Build.0 = Debug|Win32
- {82BC36B1-DDDD-41D4-ABCD-A12312378CE6}.Debug|Win32.ActiveCfg = Debug|Win32
- {82BC36B1-DDDD-41D4-ABCD-A12312378CE6}.Debug|Win32.Build.0 = Debug|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {B4823266-DF8C-AAAA-9999-C7E78C234EAC} = {E92DB6FF-5501-4FC0-81D2-00DB8EFA2434}
- {53FC9752-81C1-4AA6-B366-AF6D0A2B81F6} = {E92DB6FF-5501-4FC0-81D2-00DB8EFA2434}
- {B4823266-DF8C-1224-EE00-C7688C234EAC} = {EFB1BE3C-2981-456B-8E32-928CBDFF7822}
- {CB863607-6B6C-0000-0000-123400001234} = {EFB1BE3C-2981-456B-8E32-928CBDFF7822}
- {B4823266-DF8C-ABCD-1234-C7688C234EAC} = {EFB1BE3C-2981-456B-8E32-928CBDFF7822}
- {53FC9752-81C1-4AA6-B366-A7890A2B81F6} = {EFB1BE3C-2981-456B-8E32-928CBDFF7822}
- {A7E49FB8-700A-45EC-9174-FB1C2C7E83C9} = {162715BD-4DB3-4007-8B50-725C0BD11878}
- {82BC36B1-9F7A-41D4-A24F-DBE012378CE6} = {162715BD-4DB3-4007-8B50-725C0BD11878}
- {82BC36B1-DDDD-41D4-ABCD-A12312378CE6} = {162715BD-4DB3-4007-8B50-725C0BD11878}
- EndGlobalSection
- GlobalSection(DevPartner Solution Properties) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
- GlobalSection(DevPartner) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/cd/mak.vc8/cd.vcproj b/cd/mak.vc8/cd.vcproj
deleted file mode 100755
index 2abc61f..0000000
--- a/cd/mak.vc8/cd.vcproj
+++ /dev/null
@@ -1,623 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cd"
- ProjectGUID="{01818D2C-65AF-4D5C-9452-4DFF401C6461}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include,..\src,..\src\drv,..\src\freetype2,..\src\intcgm,..\src\iup,..\src\sim"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;CD_NO_OLD_INTERFACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj/cd.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="INTCGM"
- >
- <File
- RelativePath="..\src\intcgm\bparse.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\circle.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\ellipse.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm1.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm2.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm4.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm6.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\list.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\sism.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\tparse.c"
- >
- </File>
- <Filter
- Name="INC"
- >
- <File
- RelativePath="..\src\intcgm\bparse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\circle.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\ellipse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm2.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm4.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm6.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\list.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\sism.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\tparse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\types.h"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="WIN32"
- >
- <File
- RelativePath="..\src\win32\cdwclp.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwdbuf.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwdib.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwemf.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwimg.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwin.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwin.h"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwnative.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwprn.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\cdwwmf.c"
- >
- </File>
- <File
- RelativePath="..\src\win32\wmf_emf.c"
- >
- </File>
- </Filter>
- <Filter
- Name="SIM"
- >
- <File
- RelativePath="..\src\sim\cd_truetype.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\cdfontex.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\sim\sim.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\sim\sim.h"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_linepolyfill.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_other.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_primitives.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_text.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\truetype.h"
- >
- </File>
- </Filter>
- <Filter
- Name="DRV"
- >
- <File
- RelativePath="..\src\drv\cdcgm.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cddebug.c"
- >
- </File>
- <File
- RelativePath="..\src\drv\cddgn.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cddxf.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdirgb.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdmf.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdpicture.c"
- >
- </File>
- <File
- RelativePath="..\src\drv\cdps.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cgm.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cgm.h"
- >
- </File>
- </Filter>
- <Filter
- Name="include"
- >
- <File
- RelativePath="..\include\cd.h"
- >
- </File>
- <File
- RelativePath="..\include\cd_old.h"
- >
- </File>
- <File
- RelativePath="..\include\cd_private.h"
- >
- </File>
- <File
- RelativePath="..\include\cdcgm.h"
- >
- </File>
- <File
- RelativePath="..\include\cdclipbd.h"
- >
- </File>
- <File
- RelativePath="..\include\cddbuf.h"
- >
- </File>
- <File
- RelativePath="..\include\cddebug.h"
- >
- </File>
- <File
- RelativePath="..\include\cddgn.h"
- >
- </File>
- <File
- RelativePath="..\include\cddxf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdemf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdimage.h"
- >
- </File>
- <File
- RelativePath="..\include\cdirgb.h"
- >
- </File>
- <File
- RelativePath="..\include\cdmf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdmf_private.h"
- >
- </File>
- <File
- RelativePath="..\include\cdnative.h"
- >
- </File>
- <File
- RelativePath="..\include\cdprint.h"
- >
- </File>
- <File
- RelativePath="..\include\cdps.h"
- >
- </File>
- <File
- RelativePath="..\include\cdwmf.h"
- >
- </File>
- <File
- RelativePath="..\include\wd.h"
- >
- </File>
- <File
- RelativePath="..\include\wd_old.h"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\src\cd.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd.def"
- >
- </File>
- <File
- RelativePath="..\src\cd_active.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_attributes.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_bitmap.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_image.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_primitives.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_text.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_util.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_vectortext.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\rgb2map.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\wd.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\wdhdcpy.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cd_freetype.vcproj b/cd/mak.vc8/cd_freetype.vcproj
deleted file mode 100755
index eafc33b..0000000
--- a/cd/mak.vc8/cd_freetype.vcproj
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="freetype6"
- ProjectGUID="{01818D2C-65AF-AFDC-4356-1234401C6461}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\src\freetype2"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\freetype/freetype.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="FreeType2"
- >
- <File
- RelativePath="..\src\freetype2\autofit\autofit.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\bdf\bdf.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\cff\cff.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftbase.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\cache\ftcache.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\gzip\ftgzip.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\lzw\ftlzw.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\gxvalid\gxvalid.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\otvalid\otvalid.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\pcf\pcf.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\pfr\pfr.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\psaux\psaux.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\pshinter\pshinter.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\psnames\psnames.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\raster\raster.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\sfnt\sfnt.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\smooth\smooth.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\truetype\truetype.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\type1\type1.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\cid\type1cid.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\type42\type42.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\winfonts\winfnt.c"
- >
- </File>
- <Filter
- Name="base"
- >
- <File
- RelativePath="..\src\freetype2\base\ftapi.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftbbox.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftbdf.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftbitmap.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftdebug.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftgasp.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftglyph.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftgxval.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftinit.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftlcdfil.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftmm.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftotval.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftpatent.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftpfr.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftstroke.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftsynth.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftsystem.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\fttype1.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftwinfnt.c"
- >
- </File>
- <File
- RelativePath="..\src\freetype2\base\ftxf86.c"
- >
- </File>
- </Filter>
- </Filter>
- <File
- RelativePath="..\src\cd_freetype.def"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cd_pdflib.vcproj b/cd/mak.vc8/cd_pdflib.vcproj
deleted file mode 100755
index 807d2c7..0000000
--- a/cd/mak.vc8/cd_pdflib.vcproj
+++ /dev/null
@@ -1,733 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="pdflib"
- ProjectGUID="{8441F69D-7135-ABCD-1234-45C6123C8467}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\src\pdflib\font;..\src\pdflib\flate;..\src\pdflib\pdcore;..\src\pdflib\pdflib"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;NO_vsnprintf"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile="..\obj\pdflib/pdflib.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="pdflib"
- >
- <File
- RelativePath="..\src\pdflib\pdflib\pdflib.c"
- >
- </File>
- <Filter
- Name="flate"
- >
- <File
- RelativePath="..\src\pdflib\flate\adler32.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\compress.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\crc32.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DebugInformationFormat="1"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\pdflib\flate\deflate.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inffast.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inflate.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inftrees.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\trees.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\uncompr.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\zutil.c"
- >
- </File>
- <Filter
- Name="inc"
- >
- <File
- RelativePath="..\src\pdflib\flate\crc32.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\deflate.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inffast.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inffixed.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inflate.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\inftrees.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\trees.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\zconf.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\zlib.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\zprefix.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\flate\zutil.h"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="font"
- >
- <File
- RelativePath="..\src\pdflib\font\ft_cid.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_corefont.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_font.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_hostfont.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_pdffont.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_truetype.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_type1.c"
- >
- </File>
- <Filter
- Name="inc"
- >
- <File
- RelativePath="..\src\pdflib\font\ft_cid.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_corefont.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_font.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_generr.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_pdffont.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\font\ft_truetype.h"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="pdcore"
- >
- <File
- RelativePath="..\src\pdflib\pdcore\pc_aes.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_aescbc.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_arc4.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_chartabs.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_contain.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_core.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_crypt.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_ctype.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_digsig.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_ebcdic.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_encoding.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_file.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_geom.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_md5.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_optparse.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_output.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_resource.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_scan.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_scope.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_string.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_unicode.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_util.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_xmp.c"
- >
- </File>
- <Filter
- Name="inc"
- >
- <File
- RelativePath="..\src\pdflib\pdcore\pc_aes.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_aeslocal.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_arc4.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_chartabs.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_classic.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_config.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_contain.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_core.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_crypt.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_ctype.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_digsig.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_ebcdic.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_encoding.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_exports.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_file.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_generr.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_geom.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_md5.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_optparse.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_output.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_prefix.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_pstok.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_resource.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_scan.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_scantok.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_scope.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_strconst.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_string.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_unicode.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_util.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdcore\pc_xmp.h"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="pdflib"
- >
- <File
- RelativePath="..\src\pdflib\pdflib\p_actions.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_afm.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_annots.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_bmp.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_ccitt.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_cid.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_color.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_document.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_draw.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_encoding.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_filter.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_font.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_gif.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_gstate.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_hyper.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_icclib.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_image.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_jpeg.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_jpx.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_kerning.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_mbox.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_object.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_opi.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_page.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_params.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_pattern.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_pfm.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_photoshp.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_png.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_shading.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_subsett.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_tagged.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_template.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_text.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_tiff.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_truetype.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_type1.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_type3.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_util.c"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_xgstate.c"
- >
- </File>
- <Filter
- Name="inc"
- >
- <File
- RelativePath="..\src\pdflib\pdflib\p_color.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_defopt.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_font.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_generr.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_hkscmyk.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_hkslab.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_icc.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_icc9809.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_icclib.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_image.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_intern.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_keyconn.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_layer.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_page.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_pantlab.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_params.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\p_tagged.h"
- >
- </File>
- <File
- RelativePath="..\src\pdflib\pdflib\pdflib.h"
- >
- </File>
- </Filter>
- </Filter>
- </Filter>
- <File
- RelativePath="..\src\cd_pdflib.def"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdgdiplus.vcproj b/cd/mak.vc8/cdgdiplus.vcproj
deleted file mode 100755
index 9b71790..0000000
--- a/cd/mak.vc8/cdgdiplus.vcproj
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdgdiplus"
- ProjectGUID="{51A96255-7EAB-4F36-A6E5-1BAF6245FA18}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include,..\src,..\src\gdiplus,..\src\drv"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile="..\obj\gdiplus/cdgdiplus.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/cdcontextplus.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\include\cdgdiplus.h"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwclpp.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwdbufp.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwemfp.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwgdiplus.c"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwimgp.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwinp.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwinp.h"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwnativep.cpp"
- >
- </File>
- <File
- RelativePath="..\src\gdiplus\cdwprnp.cpp"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdgdk.vcproj b/cd/mak.vc8/cdgdk.vcproj
deleted file mode 100644
index eb4514c..0000000
--- a/cd/mak.vc8/cdgdk.vcproj
+++ /dev/null
@@ -1,603 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdgdk"
- ProjectGUID="{01818D2C-AAAA-4D5C-ABCD-1234401C6461}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\src;..\src\drv;..\src\freetype2;..\src\intcgm;..\src\iup;..\src\sim;&quot;d:\lng\gtk\include\atk-1.0&quot;;d:\lng\gtk\include\cairo;&quot;d:\lng\gtk\include\glib-2.0&quot;;&quot;d:\lng\gtk\include\pango-1.0&quot;;&quot;d:\lng\gtk\include\gtk-2.0&quot;;&quot;d:\lng\gtk\lib\glib-2.0\include&quot;;&quot;d:\lng\gtk\lib\gtk-2.0\include&quot;"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;CD_NO_OLD_INTERFACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\cdgdk/cd.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="INTCGM"
- >
- <File
- RelativePath="..\src\intcgm\bparse.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\circle.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\ellipse.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm1.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm2.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm4.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm6.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\list.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\sism.c"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\tparse.c"
- >
- </File>
- <Filter
- Name="INC"
- >
- <File
- RelativePath="..\src\intcgm\bparse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\circle.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\ellipse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm2.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm4.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\intcgm6.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\list.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\sism.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\tparse.h"
- >
- </File>
- <File
- RelativePath="..\src\intcgm\types.h"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="GDK"
- >
- <File
- RelativePath="..\src\gdk\cdgdk.c"
- >
- </File>
- <File
- RelativePath="..\src\gdk\cdgdk.h"
- >
- </File>
- <File
- RelativePath="..\src\gdk\cdgdkclp.c"
- >
- </File>
- <File
- RelativePath="..\src\gdk\cdgdkdbuf.c"
- >
- </File>
- <File
- RelativePath="..\src\gdk\cdgdkimg.c"
- >
- </File>
- <File
- RelativePath="..\src\gdk\cdgdknative.c"
- >
- </File>
- </Filter>
- <Filter
- Name="SIM"
- >
- <File
- RelativePath="..\src\sim\cd_truetype.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\cdfontex.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\sim\sim.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\sim\sim.h"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_linepolyfill.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_other.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_primitives.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\sim_text.c"
- >
- </File>
- <File
- RelativePath="..\src\sim\truetype.h"
- >
- </File>
- </Filter>
- <Filter
- Name="DRV"
- >
- <File
- RelativePath="..\src\drv\cdcgm.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cddebug.c"
- >
- </File>
- <File
- RelativePath="..\src\drv\cddgn.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cddxf.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdirgb.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdmf.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cdpicture.c"
- >
- </File>
- <File
- RelativePath="..\src\drv\cdps.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cgm.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\drv\cgm.h"
- >
- </File>
- </Filter>
- <Filter
- Name="include"
- >
- <File
- RelativePath="..\include\cd.h"
- >
- </File>
- <File
- RelativePath="..\include\cd_old.h"
- >
- </File>
- <File
- RelativePath="..\include\cd_private.h"
- >
- </File>
- <File
- RelativePath="..\include\cdcgm.h"
- >
- </File>
- <File
- RelativePath="..\include\cdclipbd.h"
- >
- </File>
- <File
- RelativePath="..\include\cddbuf.h"
- >
- </File>
- <File
- RelativePath="..\include\cddebug.h"
- >
- </File>
- <File
- RelativePath="..\include\cddgn.h"
- >
- </File>
- <File
- RelativePath="..\include\cddxf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdemf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdimage.h"
- >
- </File>
- <File
- RelativePath="..\include\cdirgb.h"
- >
- </File>
- <File
- RelativePath="..\include\cdmf.h"
- >
- </File>
- <File
- RelativePath="..\include\cdmf_private.h"
- >
- </File>
- <File
- RelativePath="..\include\cdnative.h"
- >
- </File>
- <File
- RelativePath="..\include\cdprint.h"
- >
- </File>
- <File
- RelativePath="..\include\cdps.h"
- >
- </File>
- <File
- RelativePath="..\include\cdwmf.h"
- >
- </File>
- <File
- RelativePath="..\include\wd.h"
- >
- </File>
- <File
- RelativePath="..\include\wd_old.h"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\src\cd.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd.def"
- >
- </File>
- <File
- RelativePath="..\src\cd_active.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_attributes.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_bitmap.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_image.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_primitives.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_text.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_util.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\cd_vectortext.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\rgb2map.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\wd.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\wdhdcpy.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WarningLevel="4"
- />
- </FileConfiguration>
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdlua3.vcproj b/cd/mak.vc8/cdlua3.vcproj
deleted file mode 100755
index 07a2fa0..0000000
--- a/cd/mak.vc8/cdlua3.vcproj
+++ /dev/null
@@ -1,131 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdlua3"
- ProjectGUID="{53FC9752-81C1-4AA6-B366-AF6D0A2B81F6}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\..\lua\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=""
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\src\lua3\cdlua.c"
- >
- </File>
- <File
- RelativePath="..\src\lua3\cdlua.def"
- >
- </File>
- <File
- RelativePath="..\include\cdlua.h"
- >
- </File>
- <File
- RelativePath="..\include\cdlua3_private.h"
- >
- </File>
- <File
- RelativePath="..\src\lua3\cdluactx.c"
- >
- </File>
- <File
- RelativePath="..\src\lua3\cdvoid.c"
- >
- </File>
- <File
- RelativePath="..\src\lua3\cdvoid.h"
- >
- </File>
- <File
- RelativePath="..\src\lua3\toluacd.c"
- >
- </File>
- <File
- RelativePath="..\src\lua3\toluawd.c"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdlua5.vcproj b/cd/mak.vc8/cdlua5.vcproj
deleted file mode 100755
index 329e056..0000000
--- a/cd/mak.vc8/cdlua5.vcproj
+++ /dev/null
@@ -1,131 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdlua5"
- ProjectGUID="{53FC9752-81C1-4AA6-B366-A7890A2B81F6}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\..\lua5.1\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=""
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName)1.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\include\cdlua.h"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdlua5.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdlua5.def"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdlua5_active.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdlua5_canvas.c"
- >
- </File>
- <File
- RelativePath="..\include\cdlua5_private.h"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdlua5ctx.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdvoid5.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdvoid5.h"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdluacontextplus5.vcproj b/cd/mak.vc8/cdluacontextplus5.vcproj
deleted file mode 100755
index 392ad5c..0000000
--- a/cd/mak.vc8/cdluacontextplus5.vcproj
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdluacontextplus5"
- ProjectGUID="{B4823266-DF8C-ABCD-1234-C7688C234EAC}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\..\lua5.1\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=""
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName)1.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\include\cdluacontextplus.h"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdluacontextplus5.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdluacontextplus5.def"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdluaim5.vcproj b/cd/mak.vc8/cdluaim5.vcproj
deleted file mode 100755
index 91b8fd7..0000000
--- a/cd/mak.vc8/cdluaim5.vcproj
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdluaim5"
- ProjectGUID="{CB863607-6B6C-0000-0000-123400001234}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../include;../../lua5.1/include;../../im/include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB,_CRT_SECURE_NO_DEPRECATE"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile="..\lib/cdluaim5.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName)1.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\src\lua5\cdluaim5.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdluaim5.def"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdluapdf3.vcproj b/cd/mak.vc8/cdluapdf3.vcproj
deleted file mode 100755
index 85a3949..0000000
--- a/cd/mak.vc8/cdluapdf3.vcproj
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdluapdf3"
- ProjectGUID="{B4823266-DF8C-AAAA-9999-C7E78C234EAC}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\..\lua\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=""
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\src\lua3\cdluapdf.c"
- >
- </File>
- <File
- RelativePath="..\src\lua3\cdluapdf.def"
- >
- </File>
- <File
- RelativePath="..\include\cdluapdf.h"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdluapdf5.vcproj b/cd/mak.vc8/cdluapdf5.vcproj
deleted file mode 100755
index ee0f991..0000000
--- a/cd/mak.vc8/cdluapdf5.vcproj
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdluapdf5"
- ProjectGUID="{B4823266-DF8C-1224-EE00-C7688C234EAC}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\..\lua5.1\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=""
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName)1.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\include\cdluapdf.h"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdluapdf5.c"
- >
- </File>
- <File
- RelativePath="..\src\lua5\cdluapdf5.def"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdpdf.vcproj b/cd/mak.vc8/cdpdf.vcproj
deleted file mode 100755
index cd3a618..0000000
--- a/cd/mak.vc8/cdpdf.vcproj
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdpdf"
- ProjectGUID="{8441F69D-7135-43B2-974F-45C6123C8467}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\src;..\src\sim;..\src\pdflib\pdflib"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;CD_NO_OLD_INTERFACE;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile="..\obj\cdpdf/cdpdf.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\src\drv\cdpdf.c"
- >
- </File>
- <File
- RelativePath="..\src\cdpdf.def"
- >
- </File>
- <File
- RelativePath="..\include\cdpdf.h"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdsimple.vcproj b/cd/mak.vc8/cdsimple.vcproj
deleted file mode 100644
index 4dd1a7e..0000000
--- a/cd/mak.vc8/cdsimple.vcproj
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdsimple"
- ProjectGUID="{82BC36B1-9F7A-41D4-A24F-DBE012378CE6}"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\bin"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\..\bin/cdsimple.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include,..\..\iup\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;__CD__;simple;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\cdsimple/cdsimple.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="freetype6.lib cd.lib iupcd.lib iup.lib comctl32.lib cdcontextplus.lib gdiplus.lib cdpdf.lib pdflib.lib iupcontrols.lib"
- OutputFile="$(OutDir)\$(ProjectName).exe"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\lib,..\..\iup\lib"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
- SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\test\simple\iupmain.c"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.c"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.h"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.led"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple_led.c"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdsimplegdk.vcproj b/cd/mak.vc8/cdsimplegdk.vcproj
deleted file mode 100644
index a98f8da..0000000
--- a/cd/mak.vc8/cdsimplegdk.vcproj
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdsimplegdk"
- ProjectGUID="{82BC36B1-DDDD-41D4-ABCD-A12312378CE6}"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\bin"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\..\bin/cdsimplegdk.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include,..\..\iup\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;__CD__;simple;_CRT_SECURE_NO_DEPRECATE;USE_GDK"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\cdsimplegdk/cdsimplegdk.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="gtk-win32-2.0.lib gdk-win32-2.0.lib gdk_pixbuf-2.0.lib cairo.lib pango-1.0.lib pangowin32-1.0.lib gobject-2.0.lib gmodule-2.0.lib glib-2.0.lib freetype6.lib cd.lib iupcd.lib iupgtk.lib comctl32.lib cdcontextplus.lib gdiplus.lib cdpdf.lib pdflib.lib iupcontrols.lib"
- OutputFile="$(OutDir)\$(ProjectName).exe"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\lib,..\..\iup\lib;d:\lng\gtk\lib"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
- SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\test\simple\iupmain.c"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.c"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.h"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple.led"
- >
- </File>
- <File
- RelativePath="..\test\simple\simple_led.c"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdtest.vcproj b/cd/mak.vc8/cdtest.vcproj
deleted file mode 100644
index 383cfca..0000000
--- a/cd/mak.vc8/cdtest.vcproj
+++ /dev/null
@@ -1,161 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdtest"
- ProjectGUID="{A7E49FB8-700A-45EC-9174-FB1C2C7E83C9}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\bin"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName="..\bin/cdtest.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include,..\..\iup\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;CDTEST_WIN32;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile="..\obj/cdtest.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="freetype6.lib comctl32.lib cd.lib iupcd.lib cdcontextplus.lib iup.lib gdiplus.lib cdpdf.lib pdflib.lib"
- OutputFile="$(OutDir)\$(ProjectName).exe"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\lib,..\..\iup\lib"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
- SubSystem="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\test\cdtest\cdtest.c"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\cdtest.led"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\cdtest.rc"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\cdtest_led.c"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\colorbar.c"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\drivers.c"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\list.c"
- >
- </File>
- <File
- RelativePath="..\test\cdtest\rubber.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl"
- >
- <File
- RelativePath="..\test\cdtest\cdtest.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdx11.vcproj b/cd/mak.vc8/cdx11.vcproj
deleted file mode 100755
index 5b7d433..0000000
--- a/cd/mak.vc8/cdx11.vcproj
+++ /dev/null
@@ -1,141 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdx11"
- ProjectGUID="{01818D2C-7689-4D5C-1234-4DFF401C6461}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\src;..\src\drv;..\src\iup;..\src\x11;..\src\sim;D:\LNG\x11inc;..\..\iup\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\x11/cdx11.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\src\x11\cdx11.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\cdx11.h"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\x11\cdxclp.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\cdxdbuf.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\cdximg.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\cdxnative.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\xvertex.c"
- >
- </File>
- <File
- RelativePath="..\src\x11\xvertex.h"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- />
- </FileConfiguration>
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/mak.vc8/cdxrender.vcproj b/cd/mak.vc8/cdxrender.vcproj
deleted file mode 100755
index 05c9662..0000000
--- a/cd/mak.vc8/cdxrender.vcproj
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="cdxrender"
- ProjectGUID="{160DEDA5-C1AA-48C7-8B07-490C6A8DE2EE}"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\lib"
- IntermediateDirectory="..\obj\Debug\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\include;..\src;..\src\drv;..\src\iup;..\src\x11;..\src\xrender;..\src\sim;C:\cygwin\usr\X11R6\include\;C:\LNG\x11inc;..\..\iup\include;..\src\freetype2"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,CD_NO_OLD_INTERFACE,_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\..\obj\xrender/cdxrender.pch"
- AssemblerListingLocation=""
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
- WarningLevel="4"
- SuppressStartupBanner="true"
- DebugInformationFormat="1"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1046"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/$(ProjectName).lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\src\xrender\cdxrender.c"
- >
- </File>
- <File
- RelativePath="..\src\xrender\cdxrplus.c"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cd/src/cairo/cdcairo.c b/cd/src/cairo/cdcairo.c
new file mode 100644
index 0000000..b86c046
--- /dev/null
+++ b/cd/src/cairo/cdcairo.c
@@ -0,0 +1,2110 @@
+/** \file
+* \brief Cairo Base Driver
+*
+* See Copyright Notice in cd.h
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <math.h>
+
+#include <glib.h>
+#include <pango/pangocairo.h>
+
+#include "cdcairoctx.h"
+
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static int sStrIsAscii(const char* str)
+{
+ while(*str)
+ {
+ int c = *str;
+ if (c < 0)
+ return 0;
+ str++;
+ }
+ return 1;
+}
+
+static char* sStrToUTF8(const char *str, const char* charset, int length)
+{
+ return g_convert(str, length, "UTF-8", charset, NULL, NULL, NULL);
+}
+
+static char* sStrConvertToUTF8(cdCtxCanvas *ctxcanvas, const char* str, int length)
+{
+ const char *charset = NULL;
+
+ if (!str || *str == 0)
+ return (char*)str;
+
+ if (g_get_charset(&charset)) /* current locale is already UTF-8 */
+ {
+ if (g_utf8_validate(str, -1, NULL))
+ {
+ return (char*)str;
+ }
+ else
+ {
+ ctxcanvas->strLastConvertUTF8 = sStrToUTF8(str, "ISO8859-1", length); /* if string is not UTF-8, assume ISO8859-1 */
+
+ if (!ctxcanvas->strLastConvertUTF8)
+ return (char*)str;
+
+ return ctxcanvas->strLastConvertUTF8;
+ }
+ }
+ else
+ {
+ if (sStrIsAscii(str) || !charset)
+ {
+ return (char*)str;
+ }
+ else if (charset)
+ {
+ ctxcanvas->strLastConvertUTF8 = sStrToUTF8(str, charset, length);
+
+ if (!ctxcanvas->strLastConvertUTF8)
+ return (char*)str;
+
+ return ctxcanvas->strLastConvertUTF8;
+ }
+ }
+
+ return (char*)str;
+}
+
+static void sUpdateFill(cdCtxCanvas *ctxcanvas, int fill)
+{
+ if (fill == 0 || ctxcanvas->canvas->interior_style == CD_SOLID)
+ {
+ if (ctxcanvas->last_source == 0)
+ return;
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->solid);
+ ctxcanvas->last_source = 0;
+ }
+ else
+ {
+ if (ctxcanvas->last_source == 1)
+ return;
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+ }
+}
+
+/******************************************************/
+
+void cdcairoKillCanvas(cdCtxCanvas *ctxcanvas)
+{
+ if (ctxcanvas->solid)
+ cairo_pattern_destroy(ctxcanvas->solid);
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ if (ctxcanvas->fontdesc) pango_font_description_free(ctxcanvas->fontdesc);
+ if (ctxcanvas->fontlayout) g_object_unref(ctxcanvas->fontlayout);
+ if (ctxcanvas->fontcontext) g_object_unref(ctxcanvas->fontcontext);
+
+ if (ctxcanvas->strLastConvertUTF8)
+ g_free(ctxcanvas->strLastConvertUTF8);
+
+ cairo_destroy(ctxcanvas->cr);
+
+ memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
+ free(ctxcanvas);
+}
+
+/******************************************************/
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ cairo_surface_flush(cairo_get_target(ctxcanvas->cr));
+ cairo_show_page(ctxcanvas->cr);
+}
+
+/******************************************************/
+
+static void cdfcliparea(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ if (ctxcanvas->canvas->clip_mode != CD_CLIPAREA)
+ return;
+
+ cairo_reset_clip(ctxcanvas->cr);
+ cairo_rectangle(ctxcanvas->cr, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
+ cairo_clip(ctxcanvas->cr);
+}
+
+static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfcliparea(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+static int cdclip(cdCtxCanvas *ctxcanvas, int mode)
+{
+ cairo_reset_clip(ctxcanvas->cr);
+
+ switch (mode)
+ {
+ case CD_CLIPOFF:
+ cairo_rectangle(ctxcanvas->cr, 0, 0, ctxcanvas->canvas->w, ctxcanvas->canvas->h);
+ break;
+ case CD_CLIPAREA:
+ cairo_rectangle(ctxcanvas->cr, ctxcanvas->canvas->clip_frect.xmin,
+ ctxcanvas->canvas->clip_frect.ymin,
+ ctxcanvas->canvas->clip_frect.xmax,
+ ctxcanvas->canvas->clip_frect.ymax);
+ break;
+ case CD_CLIPPOLYGON:
+ {
+ int hole_index = 0;
+ int i;
+
+ if (ctxcanvas->canvas->clip_poly)
+ {
+ cdPoint *poly = ctxcanvas->canvas->clip_poly;
+ cairo_move_to(ctxcanvas->cr, poly[0].x, poly[0].y);
+ for (i=1; i<ctxcanvas->canvas->clip_poly_n; i++)
+ {
+ if (ctxcanvas->holes && i == ctxcanvas->poly_holes[hole_index])
+ {
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ hole_index++;
+ }
+ else
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ }
+ }
+ else if (ctxcanvas->canvas->clip_fpoly)
+ {
+ cdfPoint *poly = ctxcanvas->canvas->clip_fpoly;
+ cairo_move_to(ctxcanvas->cr, poly[0].x, poly[0].y);
+ for (i=1; i<ctxcanvas->canvas->clip_poly_n; i++)
+ {
+ if (ctxcanvas->holes && i == ctxcanvas->poly_holes[hole_index])
+ {
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ hole_index++;
+ }
+ else
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ }
+ }
+ break;
+ }
+ case CD_CLIPREGION:
+ break;
+ }
+
+ cairo_clip(ctxcanvas->cr);
+
+ return mode;
+}
+
+/******************************************************/
+
+#define CD_ALPHAPRE(_src, _alpha) (((_src)*(_alpha))/255)
+
+static unsigned long sEncodeRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+ /* Pre-multiplied alpha */
+ if (a != 255)
+ {
+ r = CD_ALPHAPRE(r, a);
+ g = CD_ALPHAPRE(g, a);
+ b = CD_ALPHAPRE(b, a);
+ }
+
+ return (((unsigned long)a) << 24) |
+ (((unsigned long)r) << 16) |
+ (((unsigned long)g) << 8) |
+ (((unsigned long)b) << 0);
+}
+
+static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* userdata, int (*data2rgb)(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* userdata, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a))
+{
+ int i, j, offset, ret;
+ unsigned char r, g, b, a;
+ cairo_surface_t* pattern_surface;
+ unsigned long* data;
+
+ pattern_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, n, m);
+
+ data = (unsigned long*)cairo_image_surface_get_data(pattern_surface);
+ offset = cairo_image_surface_get_stride(pattern_surface)/4 - n;
+
+ for (j = 0; j < m; j++)
+ {
+ for (i = 0; i < n; i++)
+ {
+ /* internal transform, affects also pattern orientation */
+ if (ctxcanvas->canvas->invert_yaxis)
+ ret = data2rgb(ctxcanvas, n, i, m-1-j, userdata, &r, &g, &b, &a);
+ else
+ ret = data2rgb(ctxcanvas, n, i, j, userdata, &r, &g, &b, &a);
+
+ if (ret == -1)
+ {
+ data++; /* already transparent */
+ continue;
+ }
+
+ *data++ = sEncodeRGBA(r, g, b, a);
+ }
+
+ if (offset)
+ data += offset;
+ }
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ ctxcanvas->pattern = cairo_pattern_create_for_surface(pattern_surface);
+ cairo_pattern_reference(ctxcanvas->pattern);
+ cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_surface_destroy(pattern_surface);
+}
+
+static int long2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a)
+{
+ long* long_data = (long*)data;
+ long c = long_data[j*n+i];
+ (void)ctxcanvas;
+ cdDecodeColor(c, r, g, b);
+ *a = cdDecodeAlpha(c);
+ return 1;
+}
+
+static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *pattern)
+{
+ make_pattern(ctxcanvas, n, m, (void*)pattern, long2rgb);
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+}
+
+static int uchar2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a)
+{
+ unsigned char* uchar_data = (unsigned char*)data;
+ if (uchar_data[j*n+i])
+ {
+ cdDecodeColor(ctxcanvas->canvas->foreground, r, g, b);
+ *a = cdDecodeAlpha(ctxcanvas->canvas->foreground);
+ }
+ else
+ {
+ if (ctxcanvas->canvas->back_opacity == CD_TRANSPARENT)
+ return -1;
+ else
+ {
+ cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
+ *a = cdDecodeAlpha(ctxcanvas->canvas->background);
+ }
+ }
+
+ return 1;
+}
+
+static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple)
+{
+ make_pattern(ctxcanvas, n, m, (void*)stipple, uchar2rgb);
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+}
+
+static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
+{
+ int hsize = ctxcanvas->hatchboxsize;
+ int hhalf = hsize / 2;
+ cairo_surface_t* hatch_surface;
+ cairo_t* cr;
+
+ hatch_surface = cairo_surface_create_similar(cairo_get_target(ctxcanvas->cr), CAIRO_CONTENT_COLOR_ALPHA, hsize, hsize);
+ cr = cairo_create(hatch_surface);
+
+ if (ctxcanvas->canvas->back_opacity == CD_OPAQUE)
+ {
+ cairo_set_source_rgba(cr, cdCairoGetRed(ctxcanvas->canvas->background), cdCairoGetGreen(ctxcanvas->canvas->background), cdCairoGetBlue(ctxcanvas->canvas->background), cdCairoGetAlpha(ctxcanvas->canvas->background));
+ cairo_rectangle(cr, 0, 0, hsize, hsize);
+ cairo_fill(cr);
+ }
+
+ cairo_set_source_rgba(cr, cdCairoGetRed(ctxcanvas->canvas->foreground), cdCairoGetGreen(ctxcanvas->canvas->foreground), cdCairoGetBlue(ctxcanvas->canvas->foreground), cdCairoGetAlpha(ctxcanvas->canvas->foreground));
+
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_width(cr, 1);
+
+ switch(style)
+ {
+ case CD_HORIZONTAL:
+ cairo_move_to(cr, 0.0, (double)hhalf);
+ cairo_line_to(cr, (double)hsize, (double)hhalf);
+ break;
+ case CD_VERTICAL:
+ cairo_move_to(cr, (double)hhalf, 0.0);
+ cairo_line_to(cr, (double)hhalf, (double)hsize);
+ break;
+ case CD_BDIAGONAL:
+ cairo_move_to(cr, 0.0, (double)hsize);
+ cairo_line_to(cr, (double)hsize, 0.0);
+ break;
+ case CD_FDIAGONAL:
+ cairo_move_to(cr, 0.0, 0.0);
+ cairo_line_to(cr, (double)hsize, (double)hsize);
+ break;
+ case CD_CROSS:
+ cairo_move_to(cr, (double)hsize, 0.0);
+ cairo_line_to(cr, (double)hsize, (double)hsize);
+ cairo_move_to(cr, 0.0, (double)hhalf);
+ cairo_line_to(cr, (double)hsize, (double)hhalf);
+ break;
+ case CD_DIAGCROSS:
+ cairo_move_to(cr, 0.0, 0.0);
+ cairo_line_to(cr, (double)hsize, (double)hsize);
+ cairo_move_to(cr, (double)hsize, 0.0);
+ cairo_line_to(cr, 0.0, (double)hsize);
+ break;
+ }
+
+ cairo_stroke(cr);
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ ctxcanvas->pattern = cairo_pattern_create_for_surface(hatch_surface);
+ cairo_pattern_reference(ctxcanvas->pattern);
+ cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_surface_destroy(hatch_surface);
+ cairo_destroy(cr);
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+
+ return style;
+}
+
+/******************************************************/
+/* attributes */
+/******************************************************/
+
+static int cdinteriorstyle (cdCtxCanvas* ctxcanvas, int style)
+{
+ switch (style)
+ {
+ case CD_SOLID:
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->solid);
+ ctxcanvas->last_source = 0;
+ break;
+ /* must recriate the current pattern */
+ case CD_HATCH:
+ cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
+ break;
+ case CD_STIPPLE:
+ cdstipple(ctxcanvas, ctxcanvas->canvas->stipple_w, ctxcanvas->canvas->stipple_h, ctxcanvas->canvas->stipple);
+ break;
+ case CD_PATTERN:
+ cdpattern(ctxcanvas, ctxcanvas->canvas->pattern_w, ctxcanvas->canvas->pattern_h, ctxcanvas->canvas->pattern);
+ break;
+ }
+
+ return style;
+}
+
+static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
+{
+ double dashes[10];
+
+ switch (style)
+ {
+ case CD_CONTINUOUS : /* empty dash */
+ cairo_set_dash(ctxcanvas->cr, 0, 0, 0);
+ break;
+ case CD_DASHED :
+ dashes[0] = 6.0; dashes[1] = 2.0;
+ cairo_set_dash(ctxcanvas->cr, dashes, 2, 0);
+ break;
+ case CD_DOTTED :
+ dashes[0] = 2.0; dashes[1] = 2.0;
+ cairo_set_dash(ctxcanvas->cr, dashes, 2, 0);
+ break;
+ case CD_DASH_DOT :
+ dashes[0] = 6.0; dashes[1] = 2.0;
+ dashes[2] = 2.0; dashes[3] = 2.0;
+ cairo_set_dash(ctxcanvas->cr, dashes, 4, 0);
+ break;
+ case CD_DASH_DOT_DOT :
+ dashes[0] = 6.0; dashes[1] = 2.0;
+ dashes[2] = 2.0; dashes[3] = 2.0;
+ dashes[4] = 2.0; dashes[5] = 2.0;
+ cairo_set_dash(ctxcanvas->cr, dashes, 6, 0);
+ break;
+ case CD_CUSTOM :
+ {
+ int i;
+ double* dash_style = (double*)malloc(sizeof(double)*ctxcanvas->canvas->line_dashes_count);
+
+ for (i = 0; i < ctxcanvas->canvas->line_dashes_count; i++)
+ dash_style[i] = (double)ctxcanvas->canvas->line_dashes[i];
+
+ cairo_set_dash(ctxcanvas->cr, dash_style, ctxcanvas->canvas->line_dashes_count, 0);
+
+ free(dash_style);
+ }
+ break;
+ }
+
+ return style;
+}
+
+static int cdlinewidth(cdCtxCanvas *ctxcanvas, int width)
+{
+ if(width == 0)
+ width = 1;
+
+ cairo_set_line_width(ctxcanvas->cr, (double)width);
+
+ return width;
+}
+
+static int cdlinejoin(cdCtxCanvas *ctxcanvas, int join)
+{
+ int cd2ps_join[] = {CAIRO_LINE_JOIN_MITER, CAIRO_LINE_JOIN_BEVEL, CAIRO_LINE_JOIN_ROUND};
+
+ cairo_set_line_join(ctxcanvas->cr, cd2ps_join[join]);
+
+ return join;
+}
+
+static int cdlinecap(cdCtxCanvas *ctxcanvas, int cap)
+{
+ int cd2pdf_cap[] = {CAIRO_LINE_CAP_BUTT, CAIRO_LINE_CAP_SQUARE, CAIRO_LINE_CAP_ROUND};
+
+ cairo_set_line_cap(ctxcanvas->cr, cd2pdf_cap[cap]);
+
+ return cap;
+}
+
+static int cdfont(cdCtxCanvas *ctxcanvas, const char *typeface, int style, int size)
+{
+ int is_italic = 0, is_bold = 0; /* default is CD_PLAIN */
+ int is_strikeout = 0, is_underline = 0;
+ char font[256];
+ PangoAttrList *attrs;
+
+ if (cdStrEqualNoCase(typeface, "Courier") || cdStrEqualNoCase(typeface, "Courier New"))
+ typeface = "Monospace";
+ else if (cdStrEqualNoCase(typeface, "Times") || cdStrEqualNoCase(typeface, "Times New Roman"))
+ typeface = "Serif";
+ else if (cdStrEqualNoCase(typeface, "Helvetica") || cdStrEqualNoCase(typeface, "Arial"))
+ typeface = "Sans";
+
+ if (style & CD_BOLD)
+ is_bold = 1;
+
+ if (style & CD_ITALIC)
+ is_italic = 1;
+
+ if (style & CD_UNDERLINE)
+ is_underline = 1;
+
+ if (style & CD_STRIKEOUT)
+ is_strikeout = 1;
+
+ size = cdGetFontSizePoints(ctxcanvas->canvas, size);
+
+ sprintf(font, "%s, %s%s%d", typeface, is_bold?"Bold ":"", is_italic?"Italic ":"", size);
+
+ if (ctxcanvas->fontdesc)
+ pango_font_description_free(ctxcanvas->fontdesc);
+
+ ctxcanvas->fontdesc = pango_font_description_from_string(font);
+
+ if (!ctxcanvas->fontdesc)
+ return 0;
+
+ if (ctxcanvas->fontlayout)
+ g_object_unref(ctxcanvas->fontlayout);
+
+ ctxcanvas->fontlayout = pango_layout_new(ctxcanvas->fontcontext);
+ pango_layout_set_font_description(ctxcanvas->fontlayout, ctxcanvas->fontdesc);
+
+ attrs = pango_attr_list_new();
+ pango_attr_list_insert(attrs, pango_attribute_copy(pango_attr_strikethrough_new(is_strikeout ? TRUE : FALSE)));
+ pango_attr_list_insert(attrs, pango_attribute_copy(pango_attr_underline_new(is_underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE)));
+ pango_layout_set_attributes(ctxcanvas->fontlayout, attrs);
+
+ pango_attr_list_unref(attrs);
+
+ pango_cairo_update_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
+
+ return 1;
+}
+
+static void cdgetfontdim(cdCtxCanvas *ctxcanvas, int *max_width, int *height, int *ascent, int *descent)
+{
+ PangoFontMetrics* metrics;
+ int charwidth, charheight, charascent, chardescent;
+
+ if(!ctxcanvas->fontdesc)
+ return;
+
+ pango_cairo_update_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
+ metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext));
+ charascent = pango_font_metrics_get_ascent(metrics);
+ chardescent = pango_font_metrics_get_descent(metrics);
+ charheight = charascent + chardescent;
+ charwidth = pango_font_metrics_get_approximate_char_width(metrics);
+
+ if (max_width) *max_width = (((charwidth) + PANGO_SCALE/2) / PANGO_SCALE);
+ if (height) *height = (((charheight) + PANGO_SCALE/2) / PANGO_SCALE);
+ if (ascent) *ascent = (((charascent) + PANGO_SCALE/2) / PANGO_SCALE);
+ if (descent) *descent = (((chardescent) + PANGO_SCALE/2) / PANGO_SCALE);
+
+ pango_font_metrics_unref(metrics);
+}
+
+static long int cdforeground(cdCtxCanvas *ctxcanvas, long int color)
+{
+ if (ctxcanvas->solid)
+ cairo_pattern_destroy(ctxcanvas->solid);
+
+ cairo_set_source_rgba(ctxcanvas->cr, cdCairoGetRed(color),
+ cdCairoGetGreen(color),
+ cdCairoGetBlue(color),
+ cdCairoGetAlpha(color));
+ ctxcanvas->solid = cairo_get_source(ctxcanvas->cr);
+ cairo_pattern_reference(ctxcanvas->solid);
+ ctxcanvas->last_source = 0;
+ return color;
+}
+
+
+/******************************************************/
+
+static void sSetTransform(cdCtxCanvas *ctxcanvas, const double* matrix)
+{
+ if (matrix)
+ {
+ cairo_matrix_t mtx;
+
+ /* configure a bottom-up coordinate system */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = -1;
+ mtx.x0 = 0; mtx.y0 = (ctxcanvas->canvas->h-1);
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ mtx.xx = matrix[0]; mtx.yx = matrix[1];
+ mtx.xy = matrix[2]; mtx.yy = matrix[3];
+ mtx.x0 = matrix[4]; mtx.y0 = matrix[5];
+ cairo_transform(ctxcanvas->cr, &mtx);
+ }
+ else if (ctxcanvas->rotate_angle)
+ {
+ /* rotation = translate to point + rotation + translate back */
+ /* the rotation must be corrected because of the Y axis orientation */
+ cairo_translate(ctxcanvas->cr, ctxcanvas->rotate_center_x, _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
+ cairo_rotate(ctxcanvas->cr, (double)-ctxcanvas->rotate_angle * CD_DEG2RAD);
+ cairo_translate(ctxcanvas->cr, -ctxcanvas->rotate_center_x, -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
+ }
+}
+
+static void cdclear(cdCtxCanvas* ctxcanvas)
+{
+ cairo_save (ctxcanvas->cr);
+ cairo_identity_matrix(ctxcanvas->cr);
+ cairo_reset_clip(ctxcanvas->cr);
+ cairo_rectangle(ctxcanvas->cr, 0, 0, ctxcanvas->canvas->w, ctxcanvas->canvas->h);
+ cairo_clip(ctxcanvas->cr);
+ cairo_set_source_rgba(ctxcanvas->cr, cdCairoGetRed(ctxcanvas->canvas->background), cdCairoGetGreen(ctxcanvas->canvas->background), cdCairoGetBlue(ctxcanvas->canvas->background), cdCairoGetAlpha(ctxcanvas->canvas->background));
+ cairo_set_operator (ctxcanvas->cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (ctxcanvas->cr); /* paints the current source everywhere within the current clip region. */
+ cairo_restore (ctxcanvas->cr);
+}
+
+static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
+{
+ sUpdateFill(ctxcanvas, 0);
+
+ cairo_move_to(ctxcanvas->cr, x1, y1);
+ cairo_line_to(ctxcanvas->cr, x2, y2);
+ cairo_stroke(ctxcanvas->cr);
+}
+
+static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
+{
+ cdfline(ctxcanvas, (double)x1, (double)y1, (double)x2, (double)y2);
+}
+
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2, int swap)
+{
+ /* Cairo angles are clock-wise by default, in radians */
+
+ /* if NOT inverted means a transformation is set,
+ so the angle will follow the transformation that includes the axis invertion,
+ then it is already counter-clockwise */
+
+ if (canvas->invert_yaxis)
+ {
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
+
+ /* swap, so the start angle is the smaller */
+ if (swap)
+ {
+ double t = *a1;
+ *a1 = *a2;
+ *a2 = t;
+ }
+ }
+
+ /* convert to radians */
+ *a1 *= CD_DEG2RAD;
+ *a2 *= CD_DEG2RAD;
+}
+
+static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
+{
+ sUpdateFill(ctxcanvas, 0);
+
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
+
+ if (w == h)
+ {
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ cairo_stroke(ctxcanvas->cr);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ cairo_save(ctxcanvas->cr); /* save to use the local transform */
+
+ cairo_translate(ctxcanvas->cr, xc, yc);
+ cairo_scale(ctxcanvas->cr, w/h, 1.0);
+ cairo_translate(ctxcanvas->cr, -xc, -yc);
+
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ cairo_stroke(ctxcanvas->cr);
+
+ cairo_restore(ctxcanvas->cr); /* restore from local */
+ }
+}
+
+static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
+{
+ cdfarc(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2);
+}
+
+static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
+{
+ sUpdateFill(ctxcanvas, 1);
+
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
+
+ if (w == h)
+ {
+ cairo_move_to(ctxcanvas->cr, xc, yc);
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ cairo_fill(ctxcanvas->cr);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ cairo_save(ctxcanvas->cr); /* save to use the local transform */
+
+ cairo_translate(ctxcanvas->cr, xc, yc);
+ cairo_scale(ctxcanvas->cr, w/h, 1.0);
+ cairo_translate(ctxcanvas->cr, -xc, -yc);
+
+ cairo_move_to(ctxcanvas->cr, xc, yc);
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+
+ cairo_fill(ctxcanvas->cr);
+
+ cairo_restore(ctxcanvas->cr); /* restore from local */
+ }
+}
+
+static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
+{
+ cdfsector(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2);
+}
+
+static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
+{
+ sUpdateFill(ctxcanvas, 1);
+
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 1);
+
+ if (w == h)
+ {
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ cairo_fill(ctxcanvas->cr);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ cairo_save(ctxcanvas->cr); /* save to use the local transform */
+
+ /* local transform */
+ cairo_translate(ctxcanvas->cr, xc, yc);
+ cairo_scale(ctxcanvas->cr, w/h, 1.0);
+ cairo_translate(ctxcanvas->cr, -xc, -yc);
+
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ cairo_fill(ctxcanvas->cr);
+
+ cairo_restore(ctxcanvas->cr); /* restore from local */
+ }
+}
+
+static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
+{
+ cdfchord(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2);
+}
+
+static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ sUpdateFill(ctxcanvas, 0);
+ cairo_rectangle(ctxcanvas->cr, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
+ cairo_stroke(ctxcanvas->cr);
+}
+
+static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfrect(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ sUpdateFill(ctxcanvas, 1);
+ cairo_rectangle(ctxcanvas->cr, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
+ cairo_fill(ctxcanvas->cr);
+}
+
+static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+static void sGetTransformTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
+{
+ int xmin, xmax, ymin, ymax;
+ int baseline, height, ascent;
+
+ /* distance from bottom to baseline */
+ cdgetfontdim(canvas->ctxcanvas, NULL, &height, &ascent, NULL);
+ baseline = height - ascent;
+
+ /* move to bottom-left */
+ cdTextTranslatePoint(canvas, x, y, w, h, baseline, &xmin, &ymin);
+
+ xmax = xmin + w-1;
+ ymax = ymin + h-1;
+
+ if (canvas->text_orientation)
+ {
+ double cos_theta = cos(canvas->text_orientation*CD_DEG2RAD);
+ double sin_theta = sin(canvas->text_orientation*CD_DEG2RAD);
+ int rectY[4];
+
+ cdRotatePointY(canvas, xmin, ymin, x, y, &rectY[0], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmax, ymin, x, y, &rectY[1], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmax, ymax, x, y, &rectY[2], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmin, ymax, x, y, &rectY[3], sin_theta, cos_theta);
+
+ ymin = ymax = rectY[0];
+ if (rectY[1] < ymin) ymin = rectY[1];
+ if (rectY[2] < ymin) ymin = rectY[2];
+ if (rectY[3] < ymin) ymin = rectY[3];
+ if (rectY[1] > ymax) ymax = rectY[1];
+ if (rectY[2] > ymax) ymax = rectY[2];
+ if (rectY[3] > ymax) ymax = rectY[3];
+ }
+
+ *hbox = ymax-ymin+1;
+}
+
+static void sSetTextTransform(cdCtxCanvas* ctxcanvas, double *x, double *y, int w, int h)
+{
+ int hbox;
+ cairo_matrix_t mtx;
+
+ sGetTransformTextHeight(ctxcanvas->canvas, (int)*x, (int)*y, w, h, &hbox);
+
+ /* move to (x,y) and remove a vertical offset since text reference point is top-left */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = 1;
+ mtx.x0 = *x; mtx.y0 = *y - (hbox-1);
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ /* invert the text vertical orientation, relative to itself */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = -1;
+ mtx.x0 = 0; mtx.y0 = hbox-1;
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ *x = 0;
+ *y = 0;
+}
+
+static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, int len)
+{
+ PangoFontMetrics* metrics;
+ int w, h, desc, dir = -1, reset_transform = 0;
+
+ pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), -1);
+
+ pango_layout_get_pixel_size(ctxcanvas->fontlayout, &w, &h);
+ metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext));
+ desc = (((pango_font_metrics_get_descent(metrics)) + PANGO_SCALE/2) / PANGO_SCALE);
+
+ if (ctxcanvas->canvas->text_orientation ||
+ ctxcanvas->canvas->use_matrix ||
+ ctxcanvas->rotate_angle)
+ reset_transform = 1;
+
+ if (reset_transform)
+ {
+ cairo_save (ctxcanvas->cr);
+ cairo_identity_matrix(ctxcanvas->cr);
+
+ if (ctxcanvas->job)
+ cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* ??? */
+ }
+
+ if (ctxcanvas->canvas->text_orientation)
+ {
+ cairo_translate(ctxcanvas->cr, x, y);
+ cairo_rotate(ctxcanvas->cr, -ctxcanvas->canvas->text_orientation*CD_DEG2RAD);
+ cairo_translate(ctxcanvas->cr, -x, -y);
+ }
+
+ /* move to top-left corner of the text */
+ switch (ctxcanvas->canvas->text_alignment)
+ {
+ case CD_BASE_RIGHT:
+ case CD_NORTH_EAST:
+ case CD_EAST:
+ case CD_SOUTH_EAST:
+ x = x - w;
+ break;
+ case CD_BASE_CENTER:
+ case CD_CENTER:
+ case CD_NORTH:
+ case CD_SOUTH:
+ x = x - w/2;
+ break;
+ case CD_BASE_LEFT:
+ case CD_NORTH_WEST:
+ case CD_WEST:
+ case CD_SOUTH_WEST:
+ x = x;
+ break;
+ }
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ dir = 1;
+
+ switch (ctxcanvas->canvas->text_alignment)
+ {
+ case CD_BASE_LEFT:
+ case CD_BASE_CENTER:
+ case CD_BASE_RIGHT:
+ y = y - (dir*h - desc);
+ break;
+ case CD_SOUTH_EAST:
+ case CD_SOUTH_WEST:
+ case CD_SOUTH:
+ y = y - (dir*h);
+ break;
+ case CD_NORTH_EAST:
+ case CD_NORTH:
+ case CD_NORTH_WEST:
+ y = y;
+ break;
+ case CD_CENTER:
+ case CD_EAST:
+ case CD_WEST:
+ y = y - (dir*(h/2));
+ break;
+ }
+
+ if (ctxcanvas->canvas->use_matrix)
+ {
+ double* matrix = ctxcanvas->canvas->matrix;
+ sSetTransform(ctxcanvas, matrix);
+ sSetTextTransform(ctxcanvas, &x, &y, w, h);
+ }
+ else
+ sSetTransform(ctxcanvas, NULL);
+
+ /* Inform Pango to re-layout the text with the new transformation */
+ pango_cairo_update_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
+
+ sUpdateFill(ctxcanvas, 0);
+
+ cairo_move_to(ctxcanvas->cr, x, y);
+ pango_cairo_show_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
+
+ if (reset_transform)
+ cairo_restore(ctxcanvas->cr);
+
+ pango_font_metrics_unref(metrics);
+}
+
+static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
+{
+ cdftext(ctxcanvas, (double)x, (double)y, s, len);
+}
+
+static void cdgettextsize(cdCtxCanvas *ctxcanvas, const char *s, int len, int *width, int *height)
+{
+ if (!ctxcanvas->fontlayout)
+ return;
+
+ pango_cairo_update_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
+ pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), len);
+ pango_layout_get_pixel_size(ctxcanvas->fontlayout, width, height);
+}
+
+static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
+{
+ int i;
+
+ if (mode == CD_CLIP)
+ return;
+
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ /* if there is any current path, remove it */
+ cairo_new_path(ctxcanvas->cr);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ cairo_new_path(ctxcanvas->cr);
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPathF(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 0); /* do not swap because we handle negative arcs here */
+
+ if (w == h)
+ {
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ cairo_save(ctxcanvas->cr); /* save to use the local transform */
+
+ cairo_translate(ctxcanvas->cr, xc, yc);
+ cairo_scale(ctxcanvas->cr, w/h, 1.0);
+ cairo_translate(ctxcanvas->cr, -xc, -yc);
+
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+
+ cairo_restore(ctxcanvas->cr); /* restore from local */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ cairo_curve_to(ctxcanvas->cr, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ cairo_close_path(ctxcanvas->cr);
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_fill(ctxcanvas->cr);
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_fill_preserve(ctxcanvas->cr);
+ sUpdateFill(ctxcanvas, 0);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_PATH_CLIP:
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_clip(ctxcanvas->cr);
+ break;
+ }
+ }
+ return;
+ }
+
+ if (mode == CD_FILL)
+ {
+ sUpdateFill(ctxcanvas, 1);
+
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ cairo_set_fill_rule(ctxcanvas->cr, CAIRO_FILL_RULE_EVEN_ODD);
+ else
+ cairo_set_fill_rule(ctxcanvas->cr, CAIRO_FILL_RULE_WINDING);
+ }
+ else
+ sUpdateFill(ctxcanvas, 0);
+
+ cairo_move_to(ctxcanvas->cr, poly[0].x, poly[0].y);
+
+ if (mode == CD_BEZIER)
+ {
+ for (i=1; i<n; i+=3)
+ cairo_curve_to(ctxcanvas->cr, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ }
+ else
+ {
+ int hole_index = 0;
+
+ for (i=1; i<n; i++)
+ {
+ if (ctxcanvas->holes && i == ctxcanvas->poly_holes[hole_index])
+ {
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ hole_index++;
+ }
+ else
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ }
+ }
+
+ switch (mode)
+ {
+ case CD_CLOSED_LINES :
+ cairo_close_path(ctxcanvas->cr);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_OPEN_LINES :
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_BEZIER :
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_FILL :
+ cairo_fill(ctxcanvas->cr);
+ break;
+ }
+}
+
+static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
+{
+ int i;
+
+ if (mode == CD_CLIP)
+ return;
+
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ /* if there is any current path, remove it */
+ cairo_new_path(ctxcanvas->cr);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ cairo_new_path(ctxcanvas->cr);
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+
+ if (i+3 > n) return;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sFixAngles(ctxcanvas->canvas, &a1, &a2, 0); /* do not swap because we handle negative arcs here */
+
+ if (w == h)
+ {
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ cairo_save(ctxcanvas->cr); /* save to use the local transform */
+
+ cairo_translate(ctxcanvas->cr, xc, yc);
+ cairo_scale(ctxcanvas->cr, w/h, 1.0);
+ cairo_translate(ctxcanvas->cr, -xc, -yc);
+
+ if ((a2-a1)<0)
+ cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+ else
+ cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);
+
+ cairo_restore(ctxcanvas->cr); /* restore from local */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ cairo_curve_to(ctxcanvas->cr, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ cairo_close_path(ctxcanvas->cr);
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_fill(ctxcanvas->cr);
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_fill_preserve(ctxcanvas->cr);
+ sUpdateFill(ctxcanvas, 0);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_PATH_CLIP:
+ cairo_set_fill_rule(ctxcanvas->cr, ctxcanvas->canvas->fill_mode==CD_EVENODD? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
+ cairo_clip(ctxcanvas->cr);
+ break;
+ }
+ }
+ return;
+ }
+
+ if (mode == CD_FILL)
+ {
+ sUpdateFill(ctxcanvas, 1);
+
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ cairo_set_fill_rule(ctxcanvas->cr, CAIRO_FILL_RULE_EVEN_ODD);
+ else
+ cairo_set_fill_rule(ctxcanvas->cr, CAIRO_FILL_RULE_WINDING);
+ }
+ else
+ sUpdateFill(ctxcanvas, 0);
+
+ cairo_move_to(ctxcanvas->cr, poly[0].x, poly[0].y);
+
+ if (mode == CD_BEZIER)
+ {
+ for (i=1; i<n; i+=3)
+ cairo_curve_to(ctxcanvas->cr, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ }
+ else
+ {
+ int hole_index = 0;
+
+ for (i=1; i<n; i++)
+ {
+ if (ctxcanvas->holes && i == ctxcanvas->poly_holes[hole_index])
+ {
+ cairo_move_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ hole_index++;
+ }
+ else
+ cairo_line_to(ctxcanvas->cr, poly[i].x, poly[i].y);
+ }
+ }
+
+ switch (mode)
+ {
+ case CD_CLOSED_LINES :
+ cairo_close_path(ctxcanvas->cr);
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_OPEN_LINES :
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_BEZIER :
+ cairo_stroke(ctxcanvas->cr);
+ break;
+ case CD_FILL :
+ cairo_fill(ctxcanvas->cr);
+ break;
+ }
+}
+
+/******************************************************/
+
+static void cdgetimagergb(cdCtxCanvas *ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)
+{
+ int i, j, pos, offset;
+ unsigned long* data;
+ cairo_surface_t* image_surface;
+ cairo_t* cr;
+
+ cairo_save (ctxcanvas->cr);
+
+ /* reset to the identity. */
+ cairo_identity_matrix(ctxcanvas->cr);
+
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
+ y = _cdInvertYAxis(ctxcanvas->canvas, y);
+
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= h-1;
+
+ image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
+ cr = cairo_create(image_surface);
+
+ /* creates a pattern from the canvas and sets it as source in the image. */
+ cairo_set_source_surface(cr, cairo_get_target(ctxcanvas->cr), -x, -y);
+
+ cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_NONE);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr); /* paints the current source everywhere within the current clip region. */
+
+ data = (unsigned long*)cairo_image_surface_get_data(image_surface);
+ offset = cairo_image_surface_get_stride(image_surface)/4 - w;
+
+ for (i=0; i<h; i++)
+ {
+ for (j=0; j<w; j++)
+ {
+ pos = i*w+j;
+ r[pos] = cdRed(*data);
+ g[pos] = cdGreen(*data);
+ b[pos] = cdBlue(*data);
+ data++;
+ }
+
+ if (offset)
+ data += offset;
+ }
+
+ cairo_surface_destroy(image_surface);
+ cairo_destroy(cr);
+
+ cairo_restore(ctxcanvas->cr);
+}
+
+static void sFixImageY(cdCanvas* canvas, int *topdown, int *y, int h)
+{
+ if (canvas->invert_yaxis)
+ *topdown = 0;
+ else
+ *topdown = 1;
+
+ if (!(*topdown))
+ *y -= (h - 1); /* move Y to top-left corner, since it was at the bottom of the image */
+}
+
+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 i, j, rw, rh, pos, offset, topdown;
+ unsigned long* data;
+ cairo_surface_t* image_surface;
+
+ if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;
+
+ rw = xmax-xmin+1;
+ rh = ymax-ymin+1;
+
+ image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, rw, rh);
+
+ data = (unsigned long*)cairo_image_surface_get_data(image_surface);
+ offset = cairo_image_surface_get_stride(image_surface)/4 - rw;
+
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
+ {
+ for (j=xmin; j<=xmax; j++)
+ {
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
+ *data++ = sEncodeRGBA(r[pos], g[pos], b[pos], 255);
+ }
+
+ if (offset)
+ data += offset;
+ }
+
+ cairo_save (ctxcanvas->cr);
+
+ cairo_rectangle(ctxcanvas->cr, x, y, w, h);
+ cairo_clip(ctxcanvas->cr);
+
+ if (w != rw || h != rh)
+ {
+ /* Scale *before* setting the source surface (1) */
+ cairo_translate(ctxcanvas->cr, x, y);
+ cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh);
+ cairo_translate(ctxcanvas->cr, -x, -y);
+ }
+
+ cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y);
+ cairo_paint(ctxcanvas->cr);
+
+ cairo_surface_destroy(image_surface);
+ cairo_restore (ctxcanvas->cr);
+}
+
+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 i, j, rw, rh, pos, offset, topdown;
+ unsigned long* data;
+ cairo_surface_t* image_surface;
+
+ if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;
+
+ rw = xmax-xmin+1;
+ rh = ymax-ymin+1;
+
+ image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rw, rh);
+
+ data = (unsigned long*)cairo_image_surface_get_data(image_surface);
+ offset = cairo_image_surface_get_stride(image_surface)/4 - rw;
+
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
+ {
+ for (j=xmin; j<=xmax; j++)
+ {
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
+ *data++ = sEncodeRGBA(r[pos], g[pos], b[pos], a[pos]);
+ }
+
+ if (offset)
+ data += offset;
+ }
+
+ cairo_save (ctxcanvas->cr);
+
+ cairo_rectangle(ctxcanvas->cr, x, y, w, h);
+ cairo_clip(ctxcanvas->cr);
+
+ if (w != rw || h != rh)
+ {
+ /* Scale *before* setting the source surface (1) */
+ cairo_translate(ctxcanvas->cr, x, y);
+ cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh);
+ cairo_translate(ctxcanvas->cr, -x, -y);
+ }
+
+ cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y);
+ cairo_paint(ctxcanvas->cr);
+
+ cairo_surface_destroy(image_surface);
+ cairo_restore (ctxcanvas->cr);
+}
+
+static int sCalcPalSize(int size, const unsigned char *index)
+{
+ int i, pal_size = 0;
+
+ for (i = 0; i < size; i++)
+ {
+ if (index[i] > pal_size)
+ pal_size = index[i];
+ }
+
+ pal_size++;
+ return pal_size;
+}
+
+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 i, j, rw, rh, pos, offset, pal_size, topdown;
+ unsigned long* data, cairo_colors[256], c;
+ cairo_surface_t* image_surface;
+
+ if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;
+
+ rw = xmax-xmin+1;
+ rh = ymax-ymin+1;
+
+ image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, rw, rh);
+
+ data = (unsigned long*)cairo_image_surface_get_data(image_surface);
+ offset = cairo_image_surface_get_stride(image_surface)/4 - rw;
+
+ pal_size = sCalcPalSize(iw*ih, index);
+ for (i=0; i<pal_size; i++)
+ {
+ c = colors[i];
+ cairo_colors[i] = sEncodeRGBA(cdRed(c), cdGreen(c), cdBlue(c), 255);
+ }
+
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
+ {
+ for (j=xmin; j<=xmax; j++)
+ {
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
+ *data++ = cairo_colors[index[pos]];
+ }
+
+ if (offset)
+ data += offset;
+ }
+
+ cairo_save (ctxcanvas->cr);
+
+ cairo_rectangle(ctxcanvas->cr, x, y, w, h);
+ cairo_clip(ctxcanvas->cr);
+
+ if (w != rw || h != rh)
+ {
+ /* Scale *before* setting the source surface (1) */
+ cairo_translate(ctxcanvas->cr, x, y);
+ cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh);
+ cairo_translate(ctxcanvas->cr, -x, -y);
+ }
+
+ cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y);
+ cairo_paint(ctxcanvas->cr);
+
+ cairo_surface_destroy(image_surface);
+ cairo_restore (ctxcanvas->cr);
+}
+
+static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color)
+{
+ cairo_pattern_t* old_source = cairo_get_source(ctxcanvas->cr);
+ cairo_set_source_rgba(ctxcanvas->cr, cdCairoGetRed(color), cdCairoGetGreen(color), cdCairoGetBlue(color), cdCairoGetAlpha(color));
+
+ cairo_move_to(ctxcanvas->cr, (double)x, (double)y);
+ cairo_arc(ctxcanvas->cr, (double)x, (double)y, 0.5, 0.0, 2 * M_PI);
+
+ cairo_fill(ctxcanvas->cr);
+ cairo_set_source(ctxcanvas->cr, old_source);
+}
+
+static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)
+{
+ cdCtxImage *ctximage = (cdCtxImage *)malloc(sizeof(cdCtxImage));
+ cairo_surface_t* img_surface;
+
+ ctximage->w = w;
+ ctximage->h = h;
+ ctximage->bpp = ctxcanvas->canvas->bpp;
+ ctximage->xres = ctxcanvas->canvas->xres;
+ ctximage->yres = ctxcanvas->canvas->yres;
+ ctximage->w_mm = ctximage->w / ctximage->xres;
+ ctximage->h_mm = ctximage->h / ctximage->yres;
+
+ img_surface = cairo_surface_create_similar(cairo_get_target(ctxcanvas->cr), CAIRO_CONTENT_COLOR_ALPHA, w, h);
+ ctximage->cr = cairo_create(img_surface);
+
+ if (!ctximage->cr)
+ {
+ free(ctximage);
+ return (void *)0;
+ }
+
+ cairo_rectangle(ctximage->cr, 0, 0, ctximage->w, ctximage->h);
+ cairo_set_source_rgba(ctximage->cr, 1.0, 0.0, 0.0, 1.0); /* white opaque */
+ cairo_fill(ctximage->cr);
+
+ cairo_surface_destroy(img_surface);
+
+ return (void*)ctximage;
+}
+
+static void cdkillimage (cdCtxImage *ctximage)
+{
+ cairo_destroy(ctximage->cr);
+ free(ctximage);
+}
+
+static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y)
+{
+ cairo_save (ctximage->cr);
+
+ /* reset to the identity. */
+ cairo_identity_matrix(ctximage->cr);
+
+ cairo_reset_clip(ctximage->cr);
+
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
+ y = _cdInvertYAxis(ctxcanvas->canvas, y);
+
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
+
+ /* creates a pattern from the canvas and sets it as source in the image. */
+ cairo_set_source_surface(ctximage->cr, cairo_get_target(ctxcanvas->cr), -x, -y);
+
+ cairo_pattern_set_extend (cairo_get_source(ctximage->cr), CAIRO_EXTEND_NONE);
+ cairo_set_operator (ctximage->cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(ctximage->cr); /* paints the current source everywhere within the current clip region. */
+
+ /* must restore matrix, clipping and source */
+ cairo_restore (ctximage->cr);
+}
+
+static void cdputimagerect (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y, int xmin, int xmax, int ymin, int ymax)
+{
+ cairo_save (ctxcanvas->cr);
+
+ /* y is the bottom-left of the image region in CD */
+ y -= (ymax-ymin+1)-1;
+
+ cairo_rectangle(ctxcanvas->cr, x, y, xmax-xmin+1, ymax-ymin+1);
+ cairo_clip(ctxcanvas->cr);
+
+ /* creates a pattern from the image and sets it as source in the canvas. */
+ cairo_set_source_surface(ctxcanvas->cr, cairo_get_target(ctximage->cr), x, y);
+
+ cairo_pattern_set_extend (cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);
+ cairo_set_operator (ctxcanvas->cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(ctxcanvas->cr); /* paints the current source everywhere within the current clip region. */
+
+ /* must restore clipping and source */
+ cairo_restore (ctxcanvas->cr);
+}
+
+static void cdscrollarea (cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax, int dx, int dy)
+{
+ cairo_save (ctxcanvas->cr);
+
+ /* reset to identity */
+ cairo_identity_matrix(ctxcanvas->cr);
+
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
+ {
+ dy = -dy;
+ ymin = _cdInvertYAxis(ctxcanvas->canvas, ymin);
+ ymax = _cdInvertYAxis(ctxcanvas->canvas, ymax);
+ _cdSwapInt(ymin, ymax);
+ }
+
+ cairo_rectangle(ctxcanvas->cr, xmin+dx, ymin+dy, xmax-xmin+1, ymax-ymin+1);
+ cairo_clip(ctxcanvas->cr);
+
+ /* creates a pattern from the canvas and sets it as source in the canvas. */
+ cairo_set_source_surface(ctxcanvas->cr, cairo_get_target(ctxcanvas->cr), xmin, ymin);
+
+ cairo_pattern_set_extend (cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);
+ cairo_set_operator (ctxcanvas->cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(ctxcanvas->cr); /* paints the current source everywhere within the current clip region. */
+
+ /* must restore matrix, clipping and source */
+ cairo_restore (ctxcanvas->cr);
+}
+
+static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
+{
+ /* reset to identity */
+ cairo_identity_matrix(ctxcanvas->cr);
+
+ if (ctxcanvas->job)
+ cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* ??? */
+
+ if (matrix)
+ ctxcanvas->canvas->invert_yaxis = 0;
+ else
+ ctxcanvas->canvas->invert_yaxis = 1;
+
+ sSetTransform(ctxcanvas, matrix);
+}
+
+/******************************************************************/
+
+static void set_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ int hatchboxsize;
+
+ if (data == NULL)
+ {
+ ctxcanvas->hatchboxsize = 8;
+ return;
+ }
+
+ sscanf(data, "%d", &hatchboxsize);
+ ctxcanvas->hatchboxsize = hatchboxsize;
+}
+
+static char* get_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas)
+{
+ static char size[10];
+ sprintf(size, "%d", ctxcanvas->hatchboxsize);
+ return size;
+}
+
+static cdAttribute hatchboxsize_attrib =
+{
+ "HATCHBOXSIZE",
+ set_hatchboxsize_attrib,
+ get_hatchboxsize_attrib
+};
+
+static void set_poly_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ int hole;
+
+ if (data == NULL)
+ {
+ ctxcanvas->holes = 0;
+ return;
+ }
+
+ sscanf(data, "%d", &hole);
+ ctxcanvas->poly_holes[ctxcanvas->holes] = hole;
+ ctxcanvas->holes++;
+}
+
+static char* get_poly_attrib(cdCtxCanvas *ctxcanvas)
+{
+ static char holes[10];
+ sprintf(holes, "%d", ctxcanvas->holes);
+ return holes;
+}
+
+static cdAttribute poly_attrib =
+{
+ "POLYHOLE",
+ set_poly_attrib,
+ get_poly_attrib
+};
+
+static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
+ if (ctxcanvas->canvas->use_matrix)
+ return;
+
+ if (data)
+ {
+ sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
+ &ctxcanvas->rotate_center_x,
+ &ctxcanvas->rotate_center_y);
+ }
+ else
+ {
+ ctxcanvas->rotate_angle = 0;
+ ctxcanvas->rotate_center_x = 0;
+ ctxcanvas->rotate_center_y = 0;
+ }
+
+ cdtransform(ctxcanvas, NULL);
+}
+
+static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
+{
+ static char data[100];
+
+ if (!ctxcanvas->rotate_angle)
+ return NULL;
+
+ sprintf(data, "%g %d %d", (double)ctxcanvas->rotate_angle,
+ ctxcanvas->rotate_center_x,
+ ctxcanvas->rotate_center_y);
+
+ return data;
+}
+
+static cdAttribute rotate_attrib =
+{
+ "ROTATE",
+ set_rotate_attrib,
+ get_rotate_attrib
+};
+
+static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (!data || data[0] == '0')
+ cairo_set_antialias(ctxcanvas->cr, CAIRO_ANTIALIAS_NONE);
+ else
+ cairo_set_antialias(ctxcanvas->cr, CAIRO_ANTIALIAS_DEFAULT);
+}
+
+static char* get_aa_attrib(cdCtxCanvas* ctxcanvas)
+{
+ if (cairo_get_antialias(ctxcanvas->cr) != CAIRO_ANTIALIAS_NONE)
+ return "1";
+ else
+ return "0";
+}
+
+static cdAttribute aa_attrib =
+{
+ "ANTIALIAS",
+ set_aa_attrib,
+ get_aa_attrib
+};
+
+static void set_pattern_image_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ if (data)
+ {
+ cdCtxImage *ctximage = (cdCtxImage *)data;
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ ctxcanvas->pattern = cairo_pattern_create_for_surface(cairo_get_target(ctximage->cr));
+ cairo_pattern_reference(ctxcanvas->pattern);
+ cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+ }
+}
+
+static cdAttribute pattern_image_attrib =
+{
+ "PATTERNIMAGE",
+ set_pattern_image_attrib,
+ NULL
+};
+
+static void set_linegradient_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (data)
+ {
+ int x1, y1, x2, y2;
+ double offset;
+ int count = 1;
+
+ sscanf(data, "%d %d %d %d", &x1, &y1, &x2, &y2);
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ {
+ y1 = _cdInvertYAxis(ctxcanvas->canvas, y1);
+ y2 = _cdInvertYAxis(ctxcanvas->canvas, y2);
+ }
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ ctxcanvas->pattern = cairo_pattern_create_linear((double)x1, (double)y1, (double)x2, (double)y2);
+ cairo_pattern_reference(ctxcanvas->pattern);
+
+ for(offset = 0.1; offset < 1.0; offset += 0.1)
+ {
+ if ( count % 2 )
+ {
+ cairo_pattern_add_color_stop_rgb(ctxcanvas->pattern, offset,
+ cdCairoGetRed(ctxcanvas->canvas->foreground),
+ cdCairoGetGreen(ctxcanvas->canvas->foreground),
+ cdCairoGetBlue(ctxcanvas->canvas->foreground));
+ }
+ else
+ {
+ cairo_pattern_add_color_stop_rgb(ctxcanvas->pattern, offset,
+ cdCairoGetRed(ctxcanvas->canvas->background),
+ cdCairoGetGreen(ctxcanvas->canvas->background),
+ cdCairoGetBlue(ctxcanvas->canvas->background));
+ }
+ count++;
+ }
+
+ cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+ }
+}
+
+static char* get_linegradient_attrib(cdCtxCanvas* ctxcanvas)
+{
+ double x1, y1, x2, y2;
+
+ if (cairo_pattern_get_linear_points(ctxcanvas->pattern, &x1, &y1, &x2, &y2) == CAIRO_STATUS_SUCCESS)
+ {
+ static char data[100];
+ sprintf(data, "%d %d %d %d", (int)x1, (int)y1, (int)x2, (int)y2);
+ return data;
+ }
+ else
+ return NULL;
+}
+
+static cdAttribute linegradient_attrib =
+{
+ "LINEGRADIENT",
+ set_linegradient_attrib,
+ get_linegradient_attrib
+};
+
+static void set_radialgradient_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (data)
+ {
+ int cx1, cy1, cx2, cy2;
+ float rad1, rad2;
+ double offset;
+ int count = 1;
+
+ sscanf(data, "%d %d %g %d %d %g", &cx1, &cy1, &rad1, &cx2, &cy2, &rad2);
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ {
+ cy1 = _cdInvertYAxis(ctxcanvas->canvas, cy1);
+ cy2 = _cdInvertYAxis(ctxcanvas->canvas, cy2);
+ }
+
+ if (ctxcanvas->pattern)
+ cairo_pattern_destroy(ctxcanvas->pattern);
+
+ ctxcanvas->pattern = cairo_pattern_create_radial((double)cx1, (double)cx1, (double)rad1, (double)cx2, (double)cx2, (double)rad2);
+ cairo_pattern_reference(ctxcanvas->pattern);
+
+ for(offset = 0.1; offset < 1.0; offset += 0.1)
+ {
+ if ( count % 2 )
+ {
+ cairo_pattern_add_color_stop_rgb(ctxcanvas->pattern, offset,
+ cdCairoGetRed(ctxcanvas->canvas->foreground),
+ cdCairoGetGreen(ctxcanvas->canvas->foreground),
+ cdCairoGetBlue(ctxcanvas->canvas->foreground));
+ }
+ else
+ {
+ cairo_pattern_add_color_stop_rgb(ctxcanvas->pattern, offset,
+ cdCairoGetRed(ctxcanvas->canvas->background),
+ cdCairoGetGreen(ctxcanvas->canvas->background),
+ cdCairoGetBlue(ctxcanvas->canvas->background));
+ }
+ count++;
+ }
+
+ cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_set_source(ctxcanvas->cr, ctxcanvas->pattern);
+ ctxcanvas->last_source = 1;
+ }
+}
+
+static char* get_radialgradient_attrib(cdCtxCanvas* ctxcanvas)
+{
+ double cx1, cy1, rad1, cx2, cy2, rad2;
+
+ if (cairo_pattern_get_radial_circles(ctxcanvas->pattern, &cx1, &cy1, &rad1, &cx2, &cy2, &rad2) == CAIRO_STATUS_SUCCESS)
+ {
+ static char data[100];
+ sprintf(data, "%d %d %g %d %d %g", (int)cx1, (int)cy1, (float)rad1, (int)cx2, (int)cy2, (float)rad2);
+ return data;
+ }
+ else
+ return NULL;
+}
+
+static cdAttribute radialgradient_attrib =
+{
+ "RADIALGRADIENT",
+ set_radialgradient_attrib,
+ get_radialgradient_attrib
+};
+
+static char* get_version_attrib(cdCtxCanvas* ctxcanvas)
+{
+ (void)ctxcanvas;
+ return (char*)cairo_version_string();
+}
+
+static cdAttribute version_attrib =
+{
+ "CAIROVERSION",
+ NULL,
+ get_version_attrib
+};
+
+static void set_interp_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (data && cdStrEqualNoCase(data, "BEST"))
+ cairo_pattern_set_filter(cairo_get_source(ctxcanvas->cr), CAIRO_FILTER_BEST);
+ else if (data && cdStrEqualNoCase(data, "NEAREST"))
+ cairo_pattern_set_filter(cairo_get_source(ctxcanvas->cr), CAIRO_FILTER_NEAREST);
+ else if (data && cdStrEqualNoCase(data, "FAST"))
+ cairo_pattern_set_filter(cairo_get_source(ctxcanvas->cr), CAIRO_FILTER_FAST);
+ else if (data && cdStrEqualNoCase(data, "BILINEAR"))
+ cairo_pattern_set_filter(cairo_get_source(ctxcanvas->cr), CAIRO_FILTER_BILINEAR);
+ else
+ cairo_pattern_set_filter(cairo_get_source(ctxcanvas->cr), CAIRO_FILTER_GOOD);
+}
+
+static char* get_interp_attrib(cdCtxCanvas* ctxcanvas)
+{
+ if(cairo_pattern_get_filter(cairo_get_source(ctxcanvas->cr)) == CAIRO_FILTER_BEST)
+ return "BEST";
+ else if(cairo_pattern_get_filter(cairo_get_source(ctxcanvas->cr)) == CAIRO_FILTER_NEAREST)
+ return "NEAREST";
+ else if(cairo_pattern_get_filter(cairo_get_source(ctxcanvas->cr)) == CAIRO_FILTER_FAST)
+ return "FAST";
+ else if(cairo_pattern_get_filter(cairo_get_source(ctxcanvas->cr)) == CAIRO_FILTER_BILINEAR)
+ return "BILINEAR";
+ else
+ return "GOOD";
+}
+
+static cdAttribute interp_attrib =
+{
+ "IMGINTERP",
+ set_interp_attrib,
+ get_interp_attrib
+};
+
+static char* get_cairodc_attrib(cdCtxCanvas *ctxcanvas)
+{
+ return (char*)ctxcanvas->cr;
+}
+
+static cdAttribute cairodc_attrib =
+{
+ "CAIRODC",
+ NULL,
+ get_cairodc_attrib
+};
+
+
+cdCtxCanvas *cdcairoCreateCanvas(cdCanvas* canvas, cairo_t* cr)
+{
+ cdCtxCanvas *ctxcanvas = (cdCtxCanvas *)malloc(sizeof(cdCtxCanvas));
+ memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
+
+ ctxcanvas->cr = cr;
+ ctxcanvas->canvas = canvas;
+ ctxcanvas->last_source = -1;
+ ctxcanvas->hatchboxsize = 8;
+
+ canvas->ctxcanvas = ctxcanvas;
+ canvas->invert_yaxis = 1;
+
+ ctxcanvas->fontcontext = pango_cairo_create_context(ctxcanvas->cr);
+ pango_context_set_language(ctxcanvas->fontcontext, pango_language_get_default());
+
+ cdRegisterAttribute(canvas, &rotate_attrib);
+ cdRegisterAttribute(canvas, &version_attrib);
+ cdRegisterAttribute(canvas, &poly_attrib);
+ cdRegisterAttribute(canvas, &aa_attrib);
+ cdRegisterAttribute(canvas, &linegradient_attrib);
+ cdRegisterAttribute(canvas, &radialgradient_attrib);
+ cdRegisterAttribute(canvas, &interp_attrib);
+ cdRegisterAttribute(canvas, &cairodc_attrib);
+ cdRegisterAttribute(canvas, &hatchboxsize_attrib);
+ cdRegisterAttribute(canvas, &pattern_image_attrib);
+
+ cairo_save(ctxcanvas->cr);
+ cairo_set_operator(ctxcanvas->cr, CAIRO_OPERATOR_OVER);
+
+ return ctxcanvas;
+}
+
+void cdcairoInitTable(cdCanvas* canvas)
+{
+ canvas->cxFlush = cdflush;
+ canvas->cxClear = cdclear;
+
+ canvas->cxPixel = cdpixel;
+
+ canvas->cxLine = cdline;
+ canvas->cxPoly = cdpoly;
+ canvas->cxRect = cdrect;
+ canvas->cxBox = cdbox;
+ canvas->cxArc = cdarc;
+ canvas->cxSector = cdsector;
+ canvas->cxChord = cdchord;
+ canvas->cxText = cdtext;
+
+ canvas->cxFLine = cdfline;
+ canvas->cxFPoly = cdfpoly;
+ canvas->cxFRect = cdfrect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfarc;
+ canvas->cxFSector = cdfsector;
+ canvas->cxFChord = cdfchord;
+ canvas->cxFText = cdftext;
+
+ canvas->cxClip = cdclip;
+ canvas->cxClipArea = cdcliparea;
+ canvas->cxFClipArea = cdfcliparea;
+ canvas->cxLineStyle = cdlinestyle;
+ canvas->cxLineWidth = cdlinewidth;
+ canvas->cxLineCap = cdlinecap;
+ canvas->cxLineJoin = cdlinejoin;
+ canvas->cxInteriorStyle = cdinteriorstyle;
+ canvas->cxHatch = cdhatch;
+ canvas->cxStipple = cdstipple;
+ canvas->cxPattern = cdpattern;
+ canvas->cxFont = cdfont;
+ canvas->cxGetFontDim = cdgetfontdim;
+ canvas->cxGetTextSize = cdgettextsize;
+ canvas->cxTransform = cdtransform;
+ canvas->cxForeground = cdforeground;
+
+ canvas->cxGetImageRGB = cdgetimagergb;
+ canvas->cxScrollArea = cdscrollarea;
+
+ canvas->cxCreateImage = cdcreateimage;
+ canvas->cxGetImage = cdgetimage;
+ canvas->cxPutImageRect = cdputimagerect;
+ canvas->cxKillImage = cdkillimage;
+
+ canvas->cxPutImageRectRGB = cdputimagerectrgb;
+ canvas->cxPutImageRectMap = cdputimagerectmap;
+ canvas->cxPutImageRectRGBA = cdputimagerectrgba;
+}
diff --git a/cd/src/cairo/cdcairo.def b/cd/src/cairo/cdcairo.def
new file mode 100644
index 0000000..ad4dbeb
--- /dev/null
+++ b/cd/src/cairo/cdcairo.def
@@ -0,0 +1,9 @@
+EXPORTS
+ cdContextCairoImage
+ cdContextCairoImageRGB
+ cdContextCairoPS
+ cdContextCairoNativeWindow
+ cdContextCairoDBuffer
+ cdContextCairoSVG
+ cdContextCairoPDF
+ cdInitContextPlus
diff --git a/cd/src/cairo/cdcairoctx.h b/cd/src/cairo/cdcairoctx.h
new file mode 100644
index 0000000..8d1012c
--- /dev/null
+++ b/cd/src/cairo/cdcairoctx.h
@@ -0,0 +1,88 @@
+/** \file
+ * \brief Cairo Base Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#ifndef __CDCAIROCTX_H
+#define __CDCAIROCTX_H
+
+#include <cairo.h>
+#include <pango/pango.h>
+
+#include "cd.h"
+#include "cd_private.h"
+
+#ifndef __GTK_PRINT_UNIX_DIALOG_H__
+typedef struct _GtkPrintJob GtkPrintJob;
+#endif
+
+struct _cdCtxImage {
+ unsigned int w, h;
+ double w_mm, h_mm; /* size in mm */
+ double xres, yres; /* resolution in pixels/mm */
+ int bpp;
+ cairo_t* cr;
+};
+
+struct _cdCtxCanvas
+{
+ cdCanvas* canvas;
+
+ cairo_t* cr;
+
+ /* text attributes */
+ PangoContext *fontcontext;
+ PangoFontDescription *fontdesc;
+ PangoLayout *fontlayout;
+ char* strLastConvertUTF8;
+
+ /* fill attributes */
+ cairo_pattern_t *pattern, *solid;
+ int last_source;
+ int hatchboxsize;
+
+ /* custom attributes */
+
+ int img_format;
+
+ float rotate_angle;
+ int rotate_center_x;
+ int rotate_center_y;
+
+ int poly_holes[500];
+ int holes;
+
+ void* drawable; /* used in NativeWindow in GDK */
+
+#ifdef WIN32
+ void* hWnd; /* used in NativeWindow in Win32 */
+ void* hDC;
+ int isOwnedDC;
+#else
+ void* dpy; /* used in NativeWindow in X11 */
+ unsigned long wnd;
+#endif
+
+ int user_image; /* used in ImageRGB */
+ unsigned char *rgb;
+
+ int eps; /* used in PS */
+
+ cdImage* image_dbuffer; /* Used in double buffer driver */
+ cdCanvas* canvas_dbuffer;
+
+ GtkPrintJob* job; /* used in Printer (UNIX) */
+ char* printername; /* used in Printer (Win32) */
+};
+
+#define cdCairoGetRed(_) (((double)cdRed(_))/255.)
+#define cdCairoGetGreen(_) (((double)cdGreen(_))/255.)
+#define cdCairoGetBlue(_) (((double)cdBlue(_))/255.)
+#define cdCairoGetAlpha(_) (((double)cdAlpha(_))/255.)
+
+cdCtxCanvas *cdcairoCreateCanvas(cdCanvas* canvas, cairo_t* cr);
+void cdcairoInitTable(cdCanvas* canvas);
+void cdcairoKillCanvas(cdCtxCanvas *ctxcanvas);
+
+#endif
diff --git a/cd/src/cairo/cdcairodbuf.c b/cd/src/cairo/cdcairodbuf.c
new file mode 100644
index 0000000..1395e8c
--- /dev/null
+++ b/cd/src/cairo/cdcairodbuf.c
@@ -0,0 +1,169 @@
+/** \file
+ * \brief Cairo Double Buffer Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include "cdcairoctx.h"
+#include "cddbuf.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+
+static void cdkillcanvas (cdCtxCanvas* ctxcanvas)
+{
+ cdKillImage(ctxcanvas->image_dbuffer);
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cddeactivate(cdCtxCanvas* ctxcanvas)
+{
+ cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
+ /* this is done in the canvas_dbuffer context */
+ cdCanvasDeactivate(canvas_dbuffer);
+}
+
+static void cdflush(cdCtxCanvas* ctxcanvas)
+{
+ int old_writemode;
+ cdImage* image_dbuffer = ctxcanvas->image_dbuffer;
+ cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
+
+ /* flush the writing in the image */
+ cairo_show_page(ctxcanvas->cr);
+
+ /* this is done in the canvas_dbuffer context */
+ /* Flush can be affected by Origin and Clipping, but not WriteMode */
+ old_writemode = cdCanvasWriteMode(canvas_dbuffer, CD_REPLACE);
+ cdCanvasPutImageRect(canvas_dbuffer, image_dbuffer, 0, 0, 0, 0, 0, 0);
+ cdCanvasWriteMode(canvas_dbuffer, old_writemode);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
+{
+ int w, h;
+ cdCtxCanvas* ctxcanvas;
+ cdImage* image_dbuffer;
+ cdCtxImage* ctximage;
+
+ cdCanvasActivate(canvas_dbuffer);
+ w = canvas_dbuffer->w;
+ h = canvas_dbuffer->h;
+ if (w==0) w=1;
+ if (h==0) h=1;
+
+ /* this is done in the canvas_dbuffer context */
+ image_dbuffer = cdCanvasCreateImage(canvas_dbuffer, w, h);
+ if (!image_dbuffer)
+ return;
+
+ ctximage = image_dbuffer->ctximage;
+
+ /* Init the driver DBuffer */
+ ctxcanvas = cdcairoCreateCanvas(canvas, ctximage->cr);
+
+ if (!ctxcanvas)
+ return;
+
+ ctxcanvas->image_dbuffer = image_dbuffer;
+ ctxcanvas->canvas_dbuffer = canvas_dbuffer;
+
+ canvas->w = ctximage->w;
+ canvas->h = ctximage->h;
+ canvas->w_mm = ctximage->w_mm;
+ canvas->h_mm = ctximage->h_mm;
+ canvas->bpp = ctximage->bpp;
+ canvas->xres = ctximage->xres;
+ canvas->yres = ctximage->yres;
+}
+
+static int cdactivate(cdCtxCanvas* ctxcanvas)
+{
+ int w, h;
+ cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
+
+ /* this is done in the canvas_dbuffer context */
+ /* this will update canvas size */
+ cdCanvasActivate(canvas_dbuffer);
+ w = canvas_dbuffer->w;
+ h = canvas_dbuffer->h;
+ if (w==0) w=1;
+ if (h==0) h=1;
+
+ /* check if the size changed */
+ if (w != ctxcanvas->image_dbuffer->w ||
+ h != ctxcanvas->image_dbuffer->h)
+ {
+ cdCanvas* canvas = ctxcanvas->canvas;
+ /* save the current, if the rebuild fail */
+ cdImage* old_image_dbuffer = ctxcanvas->image_dbuffer;
+ cdCtxCanvas* old_ctxcanvas = ctxcanvas;
+
+ /* if the image is rebuild, the canvas that uses the image must be also rebuild */
+
+ /* rebuild the image and the canvas */
+ canvas->ctxcanvas = NULL;
+ canvas->context->cxCreateCanvas(canvas, canvas_dbuffer);
+ if (!canvas->ctxcanvas)
+ {
+ canvas->ctxcanvas = old_ctxcanvas;
+ return CD_ERROR;
+ }
+
+ /* remove the old image and canvas */
+ cdKillImage(old_image_dbuffer);
+ cdcairoKillCanvas(old_ctxcanvas);
+
+ ctxcanvas = canvas->ctxcanvas;
+
+ /* update canvas attributes */
+ canvas->cxBackground(ctxcanvas, canvas->background);
+ canvas->cxForeground(ctxcanvas, canvas->foreground);
+ canvas->cxBackOpacity(ctxcanvas, canvas->back_opacity);
+ canvas->cxWriteMode(ctxcanvas, canvas->write_mode);
+ canvas->cxLineStyle(ctxcanvas, canvas->line_style);
+ canvas->cxLineWidth(ctxcanvas, canvas->line_width);
+ canvas->cxLineCap(ctxcanvas, canvas->line_cap);
+ canvas->cxLineJoin(ctxcanvas, canvas->line_join);
+ canvas->cxHatch(ctxcanvas, canvas->hatch_style);
+ if (canvas->stipple) canvas->cxStipple(ctxcanvas, canvas->stipple_w, canvas->stipple_h, canvas->stipple);
+ if (canvas->pattern) canvas->cxPattern(ctxcanvas, canvas->pattern_w, canvas->pattern_h, canvas->pattern);
+ canvas->cxInteriorStyle(ctxcanvas, canvas->interior_style);
+ if (canvas->native_font[0] == 0) canvas->cxFont(ctxcanvas, canvas->font_type_face, canvas->font_style, canvas->font_size);
+ else canvas->cxNativeFont(ctxcanvas, canvas->native_font);
+/* canvas->cxTextAlignment(ctxcanvas, canvas->text_alignment); */
+/* canvas->cxTextOrientation(ctxcanvas, canvas->text_orientation); */
+ if (canvas->clip_mode == CD_CLIPAREA && canvas->cxClipArea) canvas->cxClipArea(ctxcanvas, canvas->clip_rect.xmin, canvas->clip_rect.xmax, canvas->clip_rect.ymin, canvas->clip_rect.ymax);
+/* if (canvas->clip_mode == CD_CLIPAREA && canvas->cxFClipArea) canvas->cxFClipArea(ctxcanvas, canvas->clip_frect.xmin, canvas->clip_frect.xmax, canvas->clip_frect.ymin, canvas->clip_frect.ymax); */
+ if (canvas->clip_mode == CD_CLIPPOLYGON && canvas->clip_poly) canvas->cxPoly(ctxcanvas, CD_CLIP, canvas->clip_poly, canvas->clip_poly_n);
+/* if (canvas->clip_mode == CD_CLIPPOLYGON && canvas->clip_fpoly) canvas->cxFPoly(ctxcanvas, CD_CLIP, canvas->clip_fpoly, canvas->clip_poly_n); */
+ if (canvas->clip_mode != CD_CLIPOFF) canvas->cxClip(ctxcanvas, canvas->clip_mode);
+ }
+
+ return CD_OK;
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxActivate = cdactivate;
+ canvas->cxDeactivate = cddeactivate;
+ canvas->cxFlush = cdflush;
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdDBufferContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE ),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+cdContext* cdContextCairoDBuffer(void)
+{
+ return &cdDBufferContext;
+}
diff --git a/cd/src/cairo/cdcairoemf.c b/cd/src/cairo/cdcairoemf.c
new file mode 100644
index 0000000..979caa7
--- /dev/null
+++ b/cd/src/cairo/cdcairoemf.c
@@ -0,0 +1,122 @@
+/** \file
+ * \brief EMF Printer Driver (Win32 Only)
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <windows.h>
+
+#include "cdcairoctx.h"
+#include "cdprint.h"
+
+#include "cairo-win32.h"
+
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr);
+ HDC hDC = cairo_win32_surface_get_dc(surface);
+ HENHMETAFILE hEMF;
+
+ cairo_surface_finish(surface);
+
+ hEMF = CloseEnhMetaFile (hDC);
+ DeleteEnhMetaFile (hEMF);
+
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ (void)ctxcanvas;
+ /* does nothing in EMF */
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ char* strdata = (char*)data;
+ int w = 0, h = 0;
+ double xres, yres;
+ FILE* file;
+ char filename[10240] = "";
+ HDC ScreenDC, hDC;
+ RECT rect;
+ HRGN clip_hrgn;
+
+ /* Inicializa parametros */
+ if (strdata == NULL)
+ return;
+
+ strdata += cdGetFileName(strdata, filename);
+ if (filename[0] == 0)
+ return;
+
+ sscanf(strdata,"%dx%d", &w, &h);
+ if (w == 0 || h == 0)
+ return;
+
+ /* Verifica se o arquivo pode ser aberto para escrita */
+ file = fopen(filename, "wb");
+ if (file == NULL) return;
+ fclose(file);
+
+ ScreenDC = GetDC(NULL);
+ /* LOGPIXELS can not be used for EMF */
+ xres = (double)GetDeviceCaps(ScreenDC, HORZRES) / (double)GetDeviceCaps(ScreenDC, HORZSIZE);
+ yres = (double)GetDeviceCaps(ScreenDC, VERTRES) / (double)GetDeviceCaps(ScreenDC, VERTSIZE);
+ /* The rectangle dimensions are given in hundredths of a millimeter */
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = (int)(100. * w / xres);
+ rect.bottom = (int)(100. * h / yres);
+ hDC = CreateEnhMetaFile(ScreenDC,filename,&rect,NULL);
+ ReleaseDC(NULL, ScreenDC);
+
+ if(!hDC)
+ return;
+
+ canvas->w = w;
+ canvas->h = h;
+ canvas->xres = xres;
+ canvas->yres = yres;
+ canvas->w_mm = ((double)w) / xres;
+ canvas->h_mm = ((double)h) / yres;
+ canvas->bpp = 24;
+
+ /* The DC will be queried for its initial clip extents, and this will be used as the size of the cairo surface. */
+ clip_hrgn = CreateRectRgn(0, 0, canvas->w, canvas->h);
+ SelectClipRgn(hDC, clip_hrgn);
+ DeleteObject(clip_hrgn);
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(cairo_win32_printing_surface_create(hDC)));
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxFlush = cdflush;
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdEMFCairoContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB |
+ CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+cdContext* cdContextCairoEMF(void)
+{
+ return &cdEMFCairoContext;
+}
+
diff --git a/cd/src/cairo/cdcairoimg.c b/cd/src/cairo/cdcairoimg.c
new file mode 100644
index 0000000..bc39129
--- /dev/null
+++ b/cd/src/cairo/cdcairoimg.c
@@ -0,0 +1,51 @@
+/** \file
+ * \brief Cairo Image Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+
+#include "cdcairoctx.h"
+#include "cdimage.h"
+
+
+static void cdkillcanvas(cdCtxCanvas* ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxImage *ctximage = ((cdImage*)data)->ctximage;
+ cdcairoCreateCanvas(canvas, (cairo_t*)ctximage->cr);
+ canvas->w = ctximage->w;
+ canvas->h = ctximage->h;
+ canvas->w_mm = ctximage->w_mm;
+ canvas->h_mm = ctximage->h_mm;
+ canvas->bpp = ctximage->bpp;
+ canvas->xres = ctximage->xres;
+ canvas->yres = ctximage->yres;
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdImageContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE ),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL
+};
+
+cdContext* cdContextCairoImage(void)
+{
+ return &cdImageContext;
+}
diff --git a/cd/src/cairo/cdcairoirgb.c b/cd/src/cairo/cdcairoirgb.c
new file mode 100644
index 0000000..b326834
--- /dev/null
+++ b/cd/src/cairo/cdcairoirgb.c
@@ -0,0 +1,159 @@
+/** \file
+ * \brief Cairo IMAGERGB Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "cd.h"
+#include "cdcairo.h"
+#include "cdcairoctx.h"
+
+
+static char* get_stride_attrib(cdCtxCanvas* ctxcanvas)
+{
+ static char data[100];
+ sprintf(data, "%d", cairo_image_surface_get_stride(cairo_get_target(ctxcanvas->cr)));
+ return data;
+}
+
+static cdAttribute stride_attrib =
+{
+ "STRIDE",
+ NULL,
+ get_stride_attrib
+};
+
+static void set_write2png_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ if (data)
+ cairo_surface_write_to_png(cairo_get_target(ctxcanvas->cr), data);
+}
+
+static cdAttribute write2png_attrib =
+{
+ "WRITE2PNG",
+ set_write2png_attrib,
+ NULL
+};
+
+static char* get_data_attrib(cdCtxCanvas* ctxcanvas)
+{
+ return (char*)ctxcanvas->rgb;
+}
+
+static cdAttribute data_attrib =
+{
+ "RGBDATA",
+ NULL,
+ get_data_attrib
+};
+
+static void cdkillcanvas (cdCtxCanvas *ctxcanvas)
+{
+ if (!ctxcanvas->user_image)
+ free(ctxcanvas->rgb);
+
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void* data)
+{
+ cdCtxCanvas* ctxcanvas;
+ cairo_surface_t *surface;
+ int w = 0, h = 0, use_alpha = 0;
+ float res = (float)3.78;
+ unsigned char *rgb = NULL;
+ char* str_data = (char*)data;
+ char* res_ptr = NULL;
+ cairo_format_t format = CAIRO_FORMAT_RGB24;
+
+ /* Starting parameters */
+ if (str_data == NULL)
+ return;
+
+ if (strstr(str_data, "-a"))
+ use_alpha = 1;
+
+ res_ptr = strstr(str_data, "-r");
+ if (res_ptr)
+ sscanf(res_ptr+2, "%g", &res);
+
+ /* size and rgb */
+#ifdef SunOS_OLD
+ sscanf(str_data, "%dx%d %d", &w, &h, &rgb);
+#else
+ sscanf(str_data, "%dx%d %p", &w, &h, &rgb);
+#endif
+
+ if (w == 0 || h == 0)
+ return;
+
+ canvas->w = w;
+ canvas->h = h;
+ canvas->yres = res;
+ canvas->xres = res;
+ canvas->w_mm = ((double)w) / res;
+ canvas->h_mm = ((double)h) / res;
+ if (use_alpha)
+ {
+ canvas->bpp = 32;
+ format = CAIRO_FORMAT_ARGB32;
+ }
+ else
+ canvas->bpp = 24; /* fake value, image bpp is always 32 */
+
+ if (rgb)
+ surface = cairo_image_surface_create_for_data(rgb, format, w, h, w*32);
+ else
+ surface = cairo_image_surface_create(format, canvas->w, canvas->h);
+
+ /* Starting Cairo driver */
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ cairo_surface_destroy(surface);
+
+ if (rgb)
+ {
+ ctxcanvas->user_image = 1;
+ ctxcanvas->rgb = rgb;
+ }
+ else
+ {
+ ctxcanvas->user_image = 0;
+ ctxcanvas->rgb = cairo_image_surface_get_data(cairo_get_target(ctxcanvas->cr));
+
+ /* fill with white */
+ /* transparent, this is the normal alpha coding */
+ cairo_set_source_rgba(ctxcanvas->cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_rectangle(ctxcanvas->cr, 0, 0, canvas->w, canvas->h);
+ cairo_fill(ctxcanvas->cr);
+ }
+
+ cdRegisterAttribute(canvas, &stride_attrib);
+ cdRegisterAttribute(canvas, &write2png_attrib);
+ cdRegisterAttribute(canvas, &data_attrib);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdCairoImageRGBContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL
+};
+
+cdContext* cdContextCairoImageRGB(void)
+{
+ return &cdCairoImageRGBContext;
+}
diff --git a/cd/src/cairo/cdcaironative_gdk.c b/cd/src/cairo/cdcaironative_gdk.c
new file mode 100644
index 0000000..29be6c6
--- /dev/null
+++ b/cd/src/cairo/cdcaironative_gdk.c
@@ -0,0 +1,80 @@
+/** \file
+* \brief Cairo Native Window Driver
+*
+* See Copyright Notice in cd.h
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gdk/gdk.h>
+
+#include "cdcairoctx.h"
+#include "cdnative.h"
+
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+int cdactivate(cdCtxCanvas *ctxcanvas)
+{
+ gdk_drawable_get_size(ctxcanvas->drawable, &ctxcanvas->canvas->w, &ctxcanvas->canvas->h);
+
+ ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres;
+ ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres;
+
+ return CD_OK;
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas *ctxcanvas;
+ cairo_t* cr;
+ GdkScreen* screen;
+ GdkDrawable* drawable = (GdkDrawable*)data;
+
+ cr = gdk_cairo_create(drawable);
+ if (!cr)
+ return;
+
+ screen = gdk_drawable_get_screen(drawable);
+ canvas->bpp = gdk_drawable_get_depth(drawable);
+ canvas->xres = ((double)gdk_screen_get_width(screen) / (double)gdk_screen_get_width_mm(screen));
+ canvas->yres = ((double)gdk_screen_get_height(screen) / (double)gdk_screen_get_height_mm(screen));
+ gdk_drawable_get_size(drawable, &canvas->w, &canvas->h);
+
+ canvas->w_mm = ((double)canvas->w) / canvas->xres;
+ canvas->h_mm = ((double)canvas->h) / canvas->yres;
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cr);
+
+ ctxcanvas->drawable = drawable;
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxKillCanvas = cdkillcanvas;
+ canvas->cxActivate = cdactivate;
+}
+
+/******************************************************/
+
+static cdContext cdNativeWindowContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 1,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+
+cdContext* cdContextCairoNativeWindow(void)
+{
+ return &cdNativeWindowContext;
+}
diff --git a/cd/src/cairo/cdcaironative_win32.c b/cd/src/cairo/cdcaironative_win32.c
new file mode 100644
index 0000000..e0b860e
--- /dev/null
+++ b/cd/src/cairo/cdcaironative_win32.c
@@ -0,0 +1,160 @@
+/** \file
+* \brief Cairo Native Window Driver
+*
+* See Copyright Notice in cd.h
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cdcairoctx.h"
+#include "cdnative.h"
+
+#include <windows.h>
+#include <cairo-win32.h>
+
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ if (ctxcanvas->hDC)
+ ReleaseDC(ctxcanvas->hWnd, ctxcanvas->hDC);
+
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+int cdactivate(cdCtxCanvas *ctxcanvas)
+{
+ if (ctxcanvas->hWnd)
+ {
+ RECT rect;
+ GetClientRect(ctxcanvas->hWnd, &rect);
+ ctxcanvas->canvas->w = rect.right - rect.left;
+ ctxcanvas->canvas->h = rect.bottom - rect.top;
+
+ ctxcanvas->canvas->bpp = cdGetScreenColorPlanes();
+ }
+
+ /* Se nao e' ownwer, tem que restaurar o contexto */
+ if (!ctxcanvas->isOwnedDC)
+ {
+ cairo_surface_t *surface;
+
+ if (ctxcanvas->hDC) /* deactivate not called */
+ {
+ cairo_destroy(ctxcanvas->cr);
+ ReleaseDC(ctxcanvas->hWnd, ctxcanvas->hDC);
+ }
+
+ ctxcanvas->hDC = GetDC(ctxcanvas->hWnd);
+ surface = cairo_win32_surface_create(ctxcanvas->hDC);
+ ctxcanvas->cr = cairo_create(surface);
+ cairo_surface_destroy(surface);
+ }
+
+ ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres;
+ ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres;
+
+ if (ctxcanvas->canvas->use_matrix)
+ ctxcanvas->canvas->cxTransform(ctxcanvas, ctxcanvas->canvas->matrix);
+
+ return CD_OK;
+}
+
+static void cddeactivate(cdCtxCanvas *ctxcanvas)
+{
+ /* If not owner, release the DC */
+ if (!ctxcanvas->isOwnedDC && ctxcanvas->hDC)
+ {
+ cairo_destroy(ctxcanvas->cr);
+ ReleaseDC(ctxcanvas->hWnd, ctxcanvas->hDC);
+ ctxcanvas->cr = NULL;
+ ctxcanvas->hDC = NULL;
+ }
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ cairo_surface_t *surface;
+
+ HWND hWnd = (HWND)data;
+ HDC ScreenDC, hDC;
+ HRGN clip_hrgn;
+
+ ScreenDC = GetDC(NULL);
+ canvas->bpp = GetDeviceCaps(ScreenDC, BITSPIXEL);
+ canvas->xres = (float)(((double)GetDeviceCaps(ScreenDC, LOGPIXELSX)) / 25.4);
+ canvas->yres = (float)(((double)GetDeviceCaps(ScreenDC, LOGPIXELSY)) / 25.4);
+ ReleaseDC(NULL, ScreenDC);
+
+ if (!data)
+ {
+ hDC = GetDC(NULL);
+ canvas->w = GetDeviceCaps(hDC, HORZRES);
+ canvas->h = GetDeviceCaps(hDC, VERTRES);
+ }
+ else
+ {
+ RECT rect;
+ hWnd = (HWND)data;
+
+ hDC = GetDC(hWnd);
+
+ GetClientRect(hWnd, &rect);
+ canvas->w = rect.right - rect.left;
+ canvas->h = rect.bottom - rect.top;
+ }
+
+ /* initial clip extents controls size */
+ clip_hrgn = CreateRectRgn(0, 0, canvas->w, canvas->h);
+ SelectClipRgn(hDC, clip_hrgn);
+ DeleteObject(clip_hrgn);
+
+ surface = cairo_win32_surface_create(hDC);
+
+ canvas->w_mm = ((double)canvas->w) / canvas->xres;
+ canvas->h_mm = ((double)canvas->h) / canvas->yres;
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ cairo_surface_destroy(surface);
+
+ ctxcanvas->hDC = hDC;
+ ctxcanvas->hWnd = hWnd;
+
+ if (hWnd)
+ {
+ LONG style = GetClassLong(hWnd, GCL_STYLE);
+ ctxcanvas->isOwnedDC = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC));
+ }
+ else
+ ctxcanvas->isOwnedDC = 1;
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxKillCanvas = cdkillcanvas;
+ canvas->cxActivate = cdactivate;
+ canvas->cxDeactivate = cddeactivate;
+}
+
+/******************************************************/
+
+static cdContext cdNativeWindowContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 1,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+
+cdContext* cdContextCairoNativeWindow(void)
+{
+ return &cdNativeWindowContext;
+}
+
+// cairo_win32_printing_surface_create CD_PRINTER
diff --git a/cd/src/cairo/cdcaironative_x11.c b/cd/src/cairo/cdcaironative_x11.c
new file mode 100644
index 0000000..1030745
--- /dev/null
+++ b/cd/src/cairo/cdcaironative_x11.c
@@ -0,0 +1,98 @@
+/** \file
+* \brief Cairo Native Window Driver
+*
+* See Copyright Notice in cd.h
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cdcairoctx.h"
+#include "cdnative.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <cairo-xlib.h>
+
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+int cdactivate(cdCtxCanvas *ctxcanvas)
+{
+ Window root;
+ int x, y;
+ unsigned int bw, d;
+ XGetGeometry(ctxcanvas->dpy, ctxcanvas->wnd, &root, &x, &y,
+ (unsigned int*)&ctxcanvas->canvas->w, (unsigned int*)&ctxcanvas->canvas->h, &bw, &d);
+
+ ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres;
+ ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres;
+
+ return CD_OK;
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ cairo_surface_t *surface;
+ char* data_str = (char*)data;
+ Window wnd, root;
+ Display *dpy;
+ XWindowAttributes wa;
+ int x, y;
+ unsigned int bw;
+
+#ifdef SunOS_OLD
+ sscanf(data_str, "%d %lu", &dpy, &wnd);
+#else
+ sscanf(data_str, "%p %lu", &dpy, &wnd);
+#endif
+ if (!dpy || !wnd)
+ return;
+
+ XGetWindowAttributes(dpy, wnd, &wa);
+
+ XGetGeometry(dpy, wnd, &root, &x, &y, (unsigned int*)&canvas->w, (unsigned int*)&canvas->h, &bw, (unsigned int*)&canvas->bpp);
+ canvas->xres = ((double)DisplayWidth(dpy, XScreenNumberOfScreen(wa.screen)) / (double)DisplayWidthMM(dpy, XScreenNumberOfScreen(wa.screen)));
+ canvas->yres = ((double)DisplayHeight(dpy, XScreenNumberOfScreen(wa.screen)) / (double)DisplayHeightMM(dpy, XScreenNumberOfScreen(wa.screen)));
+
+ surface = cairo_xlib_surface_create(dpy, wnd, wa.visual, canvas->w, canvas->h);
+
+ canvas->w_mm = ((double)canvas->w) / canvas->xres;
+ canvas->h_mm = ((double)canvas->h) / canvas->yres;
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ cairo_surface_destroy(surface);
+
+ ctxcanvas->dpy = dpy;
+ ctxcanvas->wnd = wnd;
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxKillCanvas = cdkillcanvas;
+ canvas->cxActivate = cdactivate;
+}
+
+/******************************************************/
+
+static cdContext cdNativeWindowContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE ),
+ 1,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+
+cdContext* cdContextCairoNativeWindow(void)
+{
+ return &cdNativeWindowContext;
+}
diff --git a/cd/src/cairo/cdcairopdf.c b/cd/src/cairo/cdcairopdf.c
new file mode 100644
index 0000000..f17fff4
--- /dev/null
+++ b/cd/src/cairo/cdcairopdf.c
@@ -0,0 +1,122 @@
+/** \file
+ * \brief Cairo PDF Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cd.h"
+#include "cdcairo.h"
+#include "cdcairoctx.h"
+
+#include <cairo-pdf.h>
+
+
+static void cdkillcanvas (cdCtxCanvas *ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void* data)
+{
+ cdCtxCanvas* ctxcanvas;
+ char* strdata = (char*)data;
+ char filename[10240] = "";
+ cairo_surface_t *surface;
+ int res = 300;
+ double w_pt; /* Largura do papel (points) */
+ double h_pt; /* Altura do papel (points) */
+ double scale; /* Fator de conversao de coordenadas (pixel2points) */
+ int landscape = 0; /* page orientation */
+
+ /* Starting parameters */
+ if (strdata == NULL)
+ return;
+
+ strdata += cdGetFileName(strdata, filename);
+ if (filename[0] == 0)
+ return;
+
+ cdSetPaperSize(CD_A4, &w_pt, &h_pt);
+
+ while (*strdata != '\0')
+ {
+ while (*strdata != '\0' && *strdata != '-')
+ strdata++;
+
+ if (*strdata != '\0')
+ {
+ float num;
+ strdata++;
+ switch (*strdata++)
+ {
+ case 'p':
+ {
+ int paper;
+ sscanf(strdata, "%d", &paper);
+ cdSetPaperSize(paper, &w_pt, &h_pt);
+ break;
+ }
+ case 'w':
+ sscanf(strdata, "%g", &num);
+ w_pt = CD_MM2PT*num;
+ break;
+ case 'h':
+ sscanf(strdata, "%g", &num);
+ h_pt = CD_MM2PT*num;
+ break;
+ case 'o':
+ landscape = 1;
+ break;
+ case 's':
+ sscanf(strdata, "%d", &res);
+ break;
+ }
+ }
+
+ while (*strdata != '\0' && *strdata != ' ')
+ strdata++;
+ }
+
+ if (landscape)
+ _cdSwapDouble(w_pt, h_pt);
+
+ scale = 72.0/res;
+
+ canvas->w = (int)(w_pt/scale + 0.5); /* Converte p/ unidades do usuario */
+ canvas->h = (int)(h_pt/scale + 0.5); /* Converte p/ unidades do usuario */
+ canvas->w_mm = w_pt/CD_MM2PT; /* Converte p/ milimetros */
+ canvas->h_mm = h_pt/CD_MM2PT; /* Converte p/ milimetros */
+ canvas->bpp = 24;
+ canvas->xres = canvas->w / canvas->w_mm;
+ canvas->yres = canvas->h / canvas->h_mm;
+
+ surface = cairo_pdf_surface_create(filename, w_pt, h_pt);
+
+ /* Starting Cairo driver */
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ cairo_surface_destroy(surface);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdCairoPDFContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL
+};
+
+cdContext* cdContextCairoPDF(void)
+{
+ return &cdCairoPDFContext;
+}
diff --git a/cd/src/cairo/cdcairoplus.c b/cd/src/cairo/cdcairoplus.c
new file mode 100644
index 0000000..a46d9f3
--- /dev/null
+++ b/cd/src/cairo/cdcairoplus.c
@@ -0,0 +1,30 @@
+/** \file
+ * \brief Cairo as Context Plus
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include "cd.h"
+#include "cd_private.h"
+#include "cdcairo.h"
+#include <stdlib.h>
+#include <memory.h>
+
+
+void cdInitContextPlus(void)
+{
+ cdContext* ctx_list[NUM_CONTEXTPLUS];
+ memset(ctx_list, 0, sizeof(ctx_list));
+
+ ctx_list[CD_CTX_NATIVEWINDOW] = cdContextCairoNativeWindow();
+ ctx_list[CD_CTX_IMAGE] = cdContextCairoImage();
+ ctx_list[CD_CTX_DBUFFER] = cdContextCairoDBuffer();
+#ifndef CAIRO_X11
+ ctx_list[CD_CTX_PRINTER] = cdContextCairoPrinter();
+#endif
+#ifdef WIN32
+ ctx_list[CD_CTX_EMF] = cdContextCairoEMF();
+#endif
+
+ cdInitContextPlusList(ctx_list);
+}
diff --git a/cd/src/cairo/cdcairoprn_unix.c b/cd/src/cairo/cdcairoprn_unix.c
new file mode 100644
index 0000000..fa13522
--- /dev/null
+++ b/cd/src/cairo/cdcairoprn_unix.c
@@ -0,0 +1,196 @@
+/** \file
+ * \brief Cairo/GTK Printer Driver (UNIX Only)
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gtk/gtkprintunixdialog.h>
+
+#include "cdcairoctx.h"
+#include "cdprint.h"
+
+static gboolean print_enum(GtkPrinter *printer, GtkPrinter **ret_printer)
+{
+ if (gtk_printer_is_default(printer))
+ {
+ *ret_printer = printer;
+ g_object_ref(printer);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void finish_send(GtkPrintJob *job, GMainLoop* loop, GError *error)
+{
+ if (error != NULL)
+ {
+ GtkWidget *edialog;
+ edialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error printing");
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), "%s", error->message);
+ gtk_window_set_modal (GTK_WINDOW (edialog), TRUE);
+ g_signal_connect(edialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_window_present(GTK_WINDOW(edialog));
+ }
+
+ g_main_loop_quit(loop);
+}
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ GMainLoop* loop = g_main_loop_new (NULL, FALSE);
+
+ cairo_surface_finish(cairo_get_target(ctxcanvas->cr));
+
+ gtk_print_job_send(ctxcanvas->job, (GtkPrintJobCompleteFunc)finish_send, loop, NULL);
+
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static char* get_printername_attrib(cdCtxCanvas* ctxcanvas)
+{
+ return (char*)gtk_printer_get_name(gtk_print_job_get_printer(ctxcanvas->job));
+}
+
+static cdAttribute printername_attrib =
+{
+ "PRINTERNAME",
+ NULL,
+ get_printername_attrib
+};
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ char *data_str = (char*) data;
+ char docname[256] = "CD - Canvas Draw Document";
+ GtkPrintUnixDialog* dialog = NULL;
+ GtkPrinter* printer;
+ GtkPrintSettings* settings;
+ GtkPageSetup* page_setup;
+ GtkPrintJob* job;
+ int show_dialog = 0;
+
+ /* Starting parameters */
+ if (data_str == NULL)
+ return;
+
+ if (data_str[0] != 0)
+ {
+ char *ptr = strstr(data_str, "-d");
+
+ if (ptr != NULL)
+ show_dialog = 1;
+
+ if (data_str[0] != '-')
+ {
+ strcpy(docname, data_str);
+
+ if (show_dialog)
+ docname[ptr - data_str - 1] = 0;
+ }
+ }
+
+ if (show_dialog)
+ {
+ int response;
+
+ dialog = (GtkPrintUnixDialog*)gtk_print_unix_dialog_new(NULL, NULL);
+
+ gtk_print_unix_dialog_set_manual_capabilities(dialog,
+ GTK_PRINT_CAPABILITY_PAGE_SET |
+ GTK_PRINT_CAPABILITY_COPIES |
+ GTK_PRINT_CAPABILITY_COLLATE |
+ GTK_PRINT_CAPABILITY_REVERSE |
+ GTK_PRINT_CAPABILITY_SCALE);
+
+ gtk_widget_realize(GTK_WIDGET(dialog));
+
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+
+ if (response == GTK_RESPONSE_CANCEL)
+ {
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ return;
+ }
+
+ printer = gtk_print_unix_dialog_get_selected_printer(dialog);
+ settings = gtk_print_unix_dialog_get_settings(dialog);
+ page_setup = gtk_print_unix_dialog_get_page_setup(dialog);
+ }
+ else
+ {
+ printer = NULL;
+ gtk_enumerate_printers((GtkPrinterFunc)print_enum, &printer, NULL, TRUE);
+ if (!printer)
+ return;
+ page_setup = gtk_printer_get_default_page_size(printer);
+ if (!page_setup)
+ page_setup = gtk_page_setup_new(); /* ?????? */
+
+ settings = gtk_print_settings_new(); /* ?????? */
+ }
+
+ job = gtk_print_job_new(docname, printer, settings, page_setup);
+
+ canvas->w_mm = (int)gtk_page_setup_get_page_width(page_setup, GTK_UNIT_MM);
+ canvas->h_mm = (int)gtk_page_setup_get_page_height(page_setup, GTK_UNIT_MM);
+ canvas->bpp = 24;
+#if GTK_CHECK_VERSION(2, 16, 0)
+ canvas->xres = (double)gtk_print_settings_get_resolution_x(settings) / 25.4;
+ canvas->yres = (double)gtk_print_settings_get_resolution_y(settings) / 25.4;
+#else
+ canvas->xres = (double)gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION) / 25.4;
+ canvas->yres = (double)gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION) / 25.4;
+#endif
+ canvas->w = cdRound(canvas->w_mm*canvas->xres);
+ canvas->h = cdRound(canvas->h_mm*canvas->yres);
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(gtk_print_job_get_surface(job, NULL)));
+ ctxcanvas->job = job;
+
+ cairo_identity_matrix(ctxcanvas->cr);
+ cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* TODO: why this is needed? */
+
+ cdRegisterAttribute(canvas, &printername_attrib);
+
+ if (dialog)
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+
+ g_object_unref(settings);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdPrinterCairoContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB |
+ CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+cdContext* cdContextCairoPrinter(void)
+{
+ return &cdPrinterCairoContext;
+}
diff --git a/cd/src/cairo/cdcairoprn_win32.c b/cd/src/cairo/cdcairoprn_win32.c
new file mode 100644
index 0000000..cbf4d66
--- /dev/null
+++ b/cd/src/cairo/cdcairoprn_win32.c
@@ -0,0 +1,194 @@
+/** \file
+ * \brief Cairo/GTK Printer Driver (Win32 Only)
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <windows.h>
+
+#include "cdcairoctx.h"
+#include "cdprint.h"
+
+#include "cairo-win32.h"
+
+
+#ifndef DC_COLORDEVICE
+#define DC_COLORDEVICE 32 /* declared only if WINVER 0x0500 */
+#endif
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr);
+ HDC hDC = cairo_win32_surface_get_dc(surface);
+
+ cairo_surface_finish(surface);
+
+ EndDoc(hDC);
+ DeleteDC(hDC);
+
+ if (ctxcanvas->printername)
+ free(ctxcanvas->printername);
+
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ cairo_surface_t* surface = cairo_get_target(ctxcanvas->cr);
+ HDC hDC = cairo_win32_surface_get_dc(surface);
+
+ cairo_surface_flush(surface);
+ cairo_show_page(ctxcanvas->cr);
+
+ GdiFlush();
+ EndPage(hDC);
+
+ StartPage(hDC);
+}
+
+static char* get_printername_attrib(cdCtxCanvas* ctxcanvas)
+{
+ return ctxcanvas->printername;
+}
+
+static cdAttribute printername_attrib =
+{
+ "PRINTERNAME",
+ NULL,
+ get_printername_attrib
+};
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ char *data_str = (char*) data;
+ char docname[256] = "CD - Canvas Draw Document";
+ DOCINFO di;
+ HDC hDC;
+ int dialog = 0;
+ PRINTDLG pd;
+ HRGN clip_hrgn;
+
+ /* Inicializa parametros */
+ if (data_str == NULL)
+ return;
+
+ if (data_str[0] != 0)
+ {
+ char *ptr = strstr(data_str, "-d");
+
+ if (ptr != NULL)
+ dialog = 1;
+
+ if (data_str[0] != '-')
+ {
+ strcpy(docname, data_str);
+
+ if (dialog)
+ docname[ptr - data_str - 1] = 0;
+ }
+ }
+
+ ZeroMemory(&pd, sizeof(PRINTDLG));
+ pd.lStructSize = sizeof(PRINTDLG);
+ pd.nCopies = 1;
+
+ if (dialog)
+ {
+ pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIES | PD_COLLATE | PD_NOPAGENUMS | PD_NOSELECTION;
+ pd.hwndOwner = GetForegroundWindow();
+ }
+ else
+ {
+ pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
+ }
+
+ if (!PrintDlg(&pd))
+ {
+ if(pd.hDevMode)
+ GlobalFree(pd.hDevMode);
+ if(pd.hDevNames)
+ GlobalFree(pd.hDevNames);
+ return;
+ }
+
+ hDC = pd.hDC;
+
+ canvas->w = GetDeviceCaps(hDC, HORZRES);
+ canvas->h = GetDeviceCaps(hDC, VERTRES);
+ canvas->w_mm = (double)GetDeviceCaps(hDC, HORZSIZE);
+ canvas->h_mm = (double)GetDeviceCaps(hDC, VERTSIZE);
+ canvas->bpp = GetDeviceCaps(hDC, BITSPIXEL);
+ canvas->xres = (double)canvas->w / canvas->w_mm;
+ canvas->yres = (double)canvas->h / canvas->h_mm;
+
+ /* The DC will be queried for its initial clip extents, and this will be used as the size of the cairo surface. */
+ clip_hrgn = CreateRectRgn(0, 0, canvas->w, canvas->h);
+ SelectClipRgn(hDC, clip_hrgn);
+ DeleteObject(clip_hrgn);
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(cairo_win32_printing_surface_create(hDC)));
+
+ di.cbSize = sizeof(DOCINFO);
+ di.lpszDocName = docname;
+ di.lpszOutput = (LPTSTR) NULL;
+ di.lpszDatatype = (LPTSTR) NULL;
+ di.fwType = 0;
+
+ StartDoc(hDC, &di);
+
+ StartPage(hDC);
+
+ if (pd.hDevNames)
+ {
+ unsigned char* devnames = (unsigned char*)GlobalLock(pd.hDevNames);
+ DEVNAMES* dn = (DEVNAMES*)devnames;
+ char* device = (char*)(devnames + dn->wDeviceOffset);
+
+ ctxcanvas->printername = cdStrDup(device);
+ cdRegisterAttribute(canvas, &printername_attrib);
+
+ /* PDF Writer returns bpp=1, so we check if color is supported and overwrite this value */
+ if (canvas->bpp==1)
+ {
+ char* port = (char*)(devnames + dn->wOutputOffset);
+ if (DeviceCapabilities(device, port, DC_COLORDEVICE, NULL, NULL))
+ canvas->bpp = 24;
+ }
+
+ GlobalUnlock(pd.hDevNames);
+ }
+
+ if(pd.hDevMode)
+ GlobalFree(pd.hDevMode);
+ if(pd.hDevNames)
+ GlobalFree(pd.hDevNames);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+
+ canvas->cxFlush = cdflush;
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdPrinterCairoContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB |
+ CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+cdContext* cdContextCairoPrinter(void)
+{
+ return &cdPrinterCairoContext;
+}
diff --git a/cd/src/cairo/cdcairops.c b/cd/src/cairo/cdcairops.c
new file mode 100644
index 0000000..b08aee4
--- /dev/null
+++ b/cd/src/cairo/cdcairops.c
@@ -0,0 +1,172 @@
+/** \file
+ * \brief Cairo PS Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cd.h"
+#include "cdps.h"
+#include "cdcairo.h"
+#include "cdcairoctx.h"
+
+#include <cairo-ps.h>
+
+
+static void set_comment_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ if (data)
+ cairo_ps_surface_dsc_comment(cairo_get_target(ctxcanvas->cr), data);
+}
+
+static cdAttribute comment_attrib =
+{
+ "DSCCOMMENT",
+ set_comment_attrib,
+ NULL
+};
+
+static void cdkillcanvas (cdCtxCanvas *ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ if (!ctxcanvas->eps)
+ cairo_show_page(ctxcanvas->cr);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void* data)
+{
+ cdCtxCanvas *ctxcanvas;
+ char* strdata = (char*)data;
+ char filename[10240] = "";
+ cairo_surface_t *surface;
+ int res = 300;
+ double w_pt; /* Largura do papel (points) */
+ double h_pt; /* Altura do papel (points) */
+ double scale; /* Fator de conversao de coordenadas (pixel2points) */
+ int eps = 0; /* Postscrip encapsulado? */
+ int level = 0;
+ int landscape = 0; /* page orientation */
+
+ /* Starting parameters */
+ if (strdata == NULL)
+ return;
+
+ strdata += cdGetFileName(strdata, filename);
+ if (filename[0] == 0)
+ return;
+
+ cdSetPaperSize(CD_A4, &w_pt, &h_pt);
+
+ while (*strdata != '\0')
+ {
+ while (*strdata != '\0' && *strdata != '-')
+ strdata++;
+
+ if (*strdata != '\0')
+ {
+ float num;
+ strdata++;
+ switch (*strdata++)
+ {
+ case 'p':
+ {
+ int paper;
+ sscanf(strdata, "%d", &paper);
+ cdSetPaperSize(paper, &w_pt, &h_pt);
+ break;
+ }
+ case 'w':
+ sscanf(strdata, "%g", &num);
+ w_pt = CD_MM2PT*num;
+ break;
+ case 'h':
+ sscanf(strdata, "%g", &num);
+ h_pt = CD_MM2PT*num;
+ break;
+ case 'e':
+ eps = 1;
+ break;
+ case 'o':
+ landscape = 1;
+ break;
+ case '2':
+ level = 2;
+ break;
+ case '3':
+ level = 3;
+ break;
+ case 's':
+ sscanf(strdata, "%d", &res);
+ break;
+ }
+ }
+
+ while (*strdata != '\0' && *strdata != ' ')
+ strdata++;
+ }
+
+ if (landscape)
+ _cdSwapDouble(w_pt, h_pt);
+
+ scale = 72.0/res;
+
+ canvas->w = (int)(w_pt/scale + 0.5); /* Converte p/ unidades do usuario */
+ canvas->h = (int)(h_pt/scale + 0.5); /* Converte p/ unidades do usuario */
+ canvas->w_mm = w_pt/CD_MM2PT; /* Converte p/ milimetros */
+ canvas->h_mm = h_pt/CD_MM2PT; /* Converte p/ milimetros */
+ canvas->bpp = 24;
+ canvas->xres = canvas->w / canvas->w_mm;
+ canvas->yres = canvas->h / canvas->h_mm;
+
+ surface = cairo_ps_surface_create(filename, w_pt, h_pt);
+
+#if (CAIRO_VERSION_MAJOR>1 || (CAIRO_VERSION_MAJOR==1 && CAIRO_VERSION_MINOR>=6))
+ if (level == 2)
+ cairo_ps_surface_restrict_to_level(surface, CAIRO_PS_LEVEL_2);
+ else if (level == 3)
+ cairo_ps_surface_restrict_to_level(surface, CAIRO_PS_LEVEL_3);
+#endif
+
+ if (eps)
+ cairo_ps_surface_set_eps(surface, 1);
+
+ cairo_ps_surface_dsc_comment(surface, "%%Title: CanvasDraw");
+ cairo_ps_surface_dsc_begin_setup (surface);
+ cairo_ps_surface_dsc_begin_page_setup (surface);
+
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ ctxcanvas->eps = eps;
+
+ cairo_surface_destroy(surface);
+
+ cdRegisterAttribute(canvas, &comment_attrib);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+ canvas->cxKillCanvas = cdkillcanvas;
+ canvas->cxFlush = cdflush;
+}
+
+static cdContext cdCairoPSContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL
+};
+
+cdContext* cdContextCairoPS(void)
+{
+ return &cdCairoPSContext;
+}
+
diff --git a/cd/src/cairo/cdcairosvg.c b/cd/src/cairo/cdcairosvg.c
new file mode 100644
index 0000000..d97cb24
--- /dev/null
+++ b/cd/src/cairo/cdcairosvg.c
@@ -0,0 +1,83 @@
+/** \file
+ * \brief Cairo SVG Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include "cd.h"
+#include "cdcairo.h"
+#include "cdcairoctx.h"
+
+#include <cairo-svg.h>
+
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ (void)ctxcanvas;
+ /* does nothing in SVG */
+}
+
+static void cdkillcanvas (cdCtxCanvas *ctxcanvas)
+{
+ cdcairoKillCanvas(ctxcanvas);
+}
+
+static void cdcreatecanvas(cdCanvas* canvas, void* data)
+{
+ cdCtxCanvas* ctxcanvas;
+ char* strdata = (char*)data;
+ char filename[10240] = "";
+ double w_mm = INT_MAX*3.78, h_mm = INT_MAX*3.78, res = 3.78;
+ cairo_surface_t *surface;
+
+ /* Starting parameters */
+ if (strdata == NULL)
+ return;
+
+ strdata += cdGetFileName(strdata, filename);
+ if (filename[0] == 0)
+ return;
+
+ sscanf(strdata, "%lgx%lg %lg", &w_mm, &h_mm, &res);
+
+ /* update canvas context */
+ canvas->w = (int)(w_mm * res);
+ canvas->h = (int)(h_mm * res);
+ canvas->w_mm = w_mm;
+ canvas->h_mm = h_mm;
+ canvas->bpp = 24;
+ canvas->xres = res;
+ canvas->yres = res;
+
+ surface = cairo_svg_surface_create(filename, CD_MM2PT*w_mm, CD_MM2PT*h_mm);
+
+ /* Starting Cairo driver */
+ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface));
+ cairo_surface_destroy(surface);
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ cdcairoInitTable(canvas);
+ canvas->cxKillCanvas = cdkillcanvas;
+ canvas->cxFlush = cdflush;
+}
+
+static cdContext cdCairoSVGContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL
+};
+
+cdContext* cdContextCairoSVG(void)
+{
+ return &cdCairoSVGContext;
+}
diff --git a/cd/src/cd.c b/cd/src/cd.c
index 600a1a9..3d20015 100755
--- a/cd/src/cd.c
+++ b/cd/src/cd.c
@@ -20,6 +20,7 @@
/* This appears only here to avoid changing the cd.h header fo bug fixes */
#define CD_VERSION_FIX ""
#define CD_VERSION_FIX_NUMBER 0
+/* #define CD_VERSION_FIX_DATE "" */
const char cd_ident[] =
"$CD: " CD_VERSION CD_VERSION_FIX " " CD_COPYRIGHT " $\n"
@@ -36,7 +37,11 @@ char* cdVersion(void)
char* cdVersionDate(void)
{
+#ifdef CD_VERSION_FIX_DATE
+ return CD_VERSION_FIX_DATE;
+#else
return CD_VERSION_DATE;
+#endif
}
int cdVersionNumber(void)
@@ -48,7 +53,7 @@ static void cd_setdefaultfunc(cdCanvas* canvas)
{
canvas->cxGetTextSize = cdgettextsizeEX;
canvas->cxGetFontDim = cdgetfontdimEX;
- canvas->cxRect = cdrectSIM;
+ canvas->cxRect = cdSimRect;
}
static void cd_setdefaultattrib(cdCanvas* canvas)
@@ -271,44 +276,48 @@ int cdCanvasSimulate(cdCanvas* canvas, int mode)
if (mode & CD_SIM_LINE)
{
- canvas->cxLine = cdlineSIM;
+ canvas->cxLine = cdSimLine;
canvas->cxFLine = NULL;
}
if (mode & CD_SIM_RECT)
{
- canvas->cxRect = cdrectSIM;
+ canvas->cxRect = cdSimRect;
canvas->cxFRect = NULL;
}
if (mode & CD_SIM_BOX)
{
- canvas->cxBox = cdboxSIM;
+ canvas->cxBox = cdSimBox;
canvas->cxFBox = NULL;
}
if (mode & CD_SIM_ARC)
{
- canvas->cxArc = cdarcSIM;
+ canvas->cxArc = cdSimArc;
canvas->cxFArc = NULL;
}
if (mode & CD_SIM_SECTOR)
{
- canvas->cxSector = cdsectorSIM;
+ canvas->cxSector = cdSimSector;
canvas->cxFSector = NULL;
}
if (mode & CD_SIM_CHORD)
{
- canvas->cxChord = cdchordSIM;
+ canvas->cxChord = cdSimChord;
canvas->cxFChord = NULL;
}
canvas->cxFont(canvas->ctxcanvas, canvas->font_type_face, canvas->font_style, canvas->font_size);
if (mode & CD_SIM_POLYLINE || mode & CD_SIM_POLYGON)
+ {
+ /* can NOT replace canvas->cxPoly because it will be used by the simulation,
+ handle polygon simulation in Begin/End */
canvas->cxFPoly = NULL;
+ }
return sim_mode;
}
@@ -702,14 +711,13 @@ static cdContext* context_plus[NUM_CONTEXTPLUS] = {NULL, NULL, NULL, NULL, NULL,
int cdUseContextPlus(int use)
{
+ int old_use_context_plus = use_context_plus;
+
if (use == CD_QUERY)
return use_context_plus;
- {
- int old_use_context_plus = use_context_plus;
- use_context_plus = use;
- return old_use_context_plus;
- }
+ use_context_plus = use;
+ return old_use_context_plus;
}
void cdInitContextPlusList(cdContext* ctx_list[])
diff --git a/cd/src/cd.def b/cd/src/cd.def
index c087d9d..e3802b2 100755
--- a/cd/src/cd.def
+++ b/cd/src/cd.def
@@ -192,11 +192,6 @@ EXPORTS
wdVectorText
wdMultiLineVectorText
wdGetVectorTextBounds
-
- cdwCreateCanvas
- cdwInitTable
- cdwKillCanvas
- cdwRestoreDC
cdLineStyleDashes
cdRegionBox
@@ -219,6 +214,15 @@ EXPORTS
cdGetFontSizePixels
cdGetFontSizePoints
cdStrEqualNoCase
+ cdSetPaperSize
+ cdCanvasGetArcPath
+ cdfCanvasGetArcPath
+ cdCanvasGetArcPathF
+ cdCanvasGetArcBox
+ cdCanvasGetArcStartEnd
+ cdfCanvasGetArcStartEnd
+ cdStrEqualNoCasePartial
+ cdGetFontFileName
wdCanvasLineWidth
wdCanvasMarkSize
@@ -360,6 +364,7 @@ EXPORTS
cdCanvasVectorTextDirection
cdCanvasVectorTextSize
cdCanvasVertex
+ cdCanvasPathSet
cdfCanvasGetClipArea
cdfCanvasArc
@@ -386,6 +391,23 @@ EXPORTS
cdCanvasSetBackground
cdCanvasTransformPoint
cdfCanvasTransformPoint
-
+ cdRound
+ cdStrDup
+
cdInitContextPlusList
cdGetContextPlus
+
+ cdfSimPolyPath
+ cdSimArc
+ cdSimPolyPath
+ cdfRotatePoint
+ cdSimSector
+ cdfSimArc
+ cdfSimSector
+ cdfSimChord
+ cdSimChord
+
+ cdwCreateCanvas
+ cdwInitTable
+ cdwKillCanvas
+ cdwRestoreDC
diff --git a/cd/src/cd_image.c b/cd/src/cd_image.c
index 002d288..df79af6 100755
--- a/cd/src/cd_image.c
+++ b/cd/src/cd_image.c
@@ -86,26 +86,9 @@ void cdCanvasPutImageRectRGB(cdCanvas* canvas, int iw, int ih, const unsigned ch
if (canvas->invert_yaxis)
y = _cdInvertYAxis(canvas, y);
- if (canvas->bpp <= 8)
- {
- int height = ymax-ymin+1;
- unsigned char* map = (unsigned char*)malloc(iw * height);
- int pal_size = 1L << canvas->bpp;
- long colors[256];
-
- if (!map)
- return;
-
- if (pal_size == 2) /* probably a laser printer, use a gray image for better results */
- cdRGB2Gray(iw, height, r+ymin*iw, g+ymin*iw, b+ymin*iw, map, colors);
- else
- cdRGB2Map(iw, height, r+ymin*iw, g+ymin*iw, b+ymin*iw, map, pal_size, colors);
-
- canvas->cxPutImageRectMap(canvas->ctxcanvas, iw, height, map, colors, x, y, w, h, xmin, xmax, 0, height-1);
-
- free(map);
- }
- else
+ if (canvas->cxPutImageRectMap && (canvas->bpp <= 8 || !canvas->cxPutImageRectRGB))
+ cdSimPutImageRectRGB(canvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax);
+ else if (canvas->cxPutImageRectRGB)
canvas->cxPutImageRectRGB(canvas->ctxcanvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax);
}
@@ -142,6 +125,11 @@ void cdCanvasPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned c
{
if (canvas->cxGetImageRGB)
cdSimPutImageRectRGBA(canvas, iw, ih, r, g, b, a, x, y, w, h, xmin, xmax, ymin, ymax);
+ else if (!canvas->cxPutImageRectRGB)
+ {
+ if (canvas->cxPutImageRectMap)
+ cdSimPutImageRectRGB(canvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax);
+ }
else
canvas->cxPutImageRectRGB(canvas->ctxcanvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax);
}
diff --git a/cd/src/cd_primitives.c b/cd/src/cd_primitives.c
index b1a19ba..8714e70 100755
--- a/cd/src/cd_primitives.c
+++ b/cd/src/cd_primitives.c
@@ -123,32 +123,22 @@ void cdCanvasBegin(cdCanvas* canvas, int mode)
assert(mode>=CD_FILL);
if (!_cdCheckCanvas(canvas)) return;
+ canvas->use_fpoly = -1;
+ canvas->poly_n = 0;
+ canvas->path_n = 0;
+
if (mode == CD_REGION)
{
if (!canvas->cxNewRegion) return;
canvas->new_region = 1;
- canvas->poly_n = 0;
canvas->cxNewRegion(canvas->ctxcanvas);
return;
}
- canvas->sim_poly = 0;
-
if (canvas->interior_style == CD_HOLLOW && mode == CD_FILL)
mode = CD_CLOSED_LINES;
- /* simulacao de linhas */
- if ((mode == CD_CLOSED_LINES || mode == CD_OPEN_LINES || mode == CD_BEZIER) &&
- canvas->sim_mode & CD_SIM_POLYLINE)
- canvas->sim_poly = 1;
-
- /* simulacao de poligonos preenchidos */
- if (mode == CD_FILL && canvas->sim_mode & CD_SIM_POLYGON)
- canvas->sim_poly = 1;
-
- canvas->use_fpoly = -1;
- canvas->poly_n = 0;
canvas->poly_mode = mode;
}
@@ -181,7 +171,7 @@ void cdCanvasVertex(cdCanvas* canvas, int x, int y)
canvas->poly = (cdPoint*)realloc(canvas->poly, sizeof(cdPoint) * (canvas->poly_size+1));
}
- if (canvas->poly_mode != CD_BEZIER &&
+ if (canvas->poly_mode != CD_BEZIER && canvas->poly_mode != CD_PATH &&
canvas->poly_n > 0 &&
canvas->poly[canvas->poly_n-1].x == x &&
canvas->poly[canvas->poly_n-1].y == y)
@@ -233,6 +223,51 @@ void cdfCanvasVertex(cdCanvas* canvas, double x, double y)
canvas->poly_n++;
}
+void cdCanvasPathSet(cdCanvas* canvas, int action)
+{
+ assert(canvas);
+ if (!_cdCheckCanvas(canvas)) return;
+
+ if (canvas->poly_mode!=CD_PATH)
+ return;
+
+ if (!canvas->path)
+ {
+ canvas->path = (int*)malloc(sizeof(int)*(_CD_POLY_BLOCK+1));
+ canvas->path_size = _CD_POLY_BLOCK;
+ }
+
+ if (canvas->path_n == canvas->path_size)
+ {
+ canvas->path_size += _CD_POLY_BLOCK;
+ canvas->path = (int*)realloc(canvas->path, sizeof(int) * (canvas->path_size+1));
+ }
+
+ canvas->path[canvas->path_n] = action;
+ canvas->path_n++;
+}
+
+void cdCanvasPoly(cdCanvas* canvas, int mode, cdPoint* points, int n)
+{
+ int sim_poly = 0;
+
+ /* simulacao de linhas */
+ if ((mode == CD_CLOSED_LINES || mode == CD_OPEN_LINES ||
+ mode == CD_BEZIER || mode == CD_PATH) &&
+ canvas->sim_mode & CD_SIM_POLYLINE)
+ sim_poly = 1;
+
+ /* simulacao de poligonos preenchidos */
+ if ((mode == CD_FILL || mode == CD_PATH) &&
+ canvas->sim_mode & CD_SIM_POLYGON)
+ sim_poly = 1;
+
+ if (sim_poly)
+ cdSimPoly(canvas->ctxcanvas, mode, points, n);
+ else
+ canvas->cxPoly(canvas->ctxcanvas, mode, points, n);
+}
+
void cdCanvasEnd(cdCanvas* canvas)
{
assert(canvas);
@@ -245,6 +280,13 @@ void cdCanvasEnd(cdCanvas* canvas)
return;
}
+ if (canvas->poly_mode==CD_PATH && canvas->poly_n < 2)
+ {
+ canvas->poly_n = 0;
+ canvas->path_n = 0;
+ return;
+ }
+
if (canvas->poly_mode==CD_OPEN_LINES && canvas->poly_n < 2)
{
canvas->poly_n = 0;
@@ -265,15 +307,10 @@ void cdCanvasEnd(cdCanvas* canvas)
return;
}
- if (canvas->sim_poly)
- cdpolySIM(canvas->ctxcanvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
+ if (canvas->use_fpoly)
+ canvas->cxFPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->fpoly, canvas->poly_n);
else
- {
- if (canvas->use_fpoly)
- canvas->cxFPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->fpoly, canvas->poly_n);
- else
- canvas->cxPoly(canvas->ctxcanvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
- }
+ cdCanvasPoly(canvas, canvas->poly_mode, canvas->poly, canvas->poly_n);
if (canvas->poly_mode == CD_CLIP)
{
@@ -303,6 +340,7 @@ void cdCanvasEnd(cdCanvas* canvas)
}
}
+ canvas->path_n = 0;
canvas->poly_n = 0;
canvas->use_fpoly = -1;
}
@@ -429,7 +467,7 @@ void cdfCanvasBox(cdCanvas* canvas, double xmin, double xmax, double ymin, doubl
canvas->cxBox(canvas->ctxcanvas, _cdRound(xmin), _cdRound(xmax), _cdRound(ymin), _cdRound(ymax));
}
-static void normAngles(double *angle1, double *angle2)
+static void sNormAngles(double *angle1, double *angle2)
{
*angle1 = fmod(*angle1,360);
*angle2 = fmod(*angle2,360);
@@ -444,7 +482,7 @@ void cdCanvasArc(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->use_origin)
{
@@ -466,7 +504,7 @@ void cdfCanvasArc(cdCanvas* canvas, double xc, double yc, double w, double h, do
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->use_origin)
{
@@ -492,7 +530,7 @@ void cdCanvasSector(cdCanvas* canvas, int xc, int yc, int w, int h, double angle
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -535,7 +573,7 @@ void cdfCanvasSector(cdCanvas* canvas, double xc, double yc, double w, double h,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -581,7 +619,7 @@ void cdCanvasChord(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -621,7 +659,7 @@ void cdfCanvasChord(cdCanvas* canvas, double xc, double yc, double w, double h,
if (angle1 == angle2 || w == 0 || h == 0)
return;
- normAngles(&angle1, &angle2);
+ sNormAngles(&angle1, &angle2);
if (canvas->interior_style == CD_HOLLOW)
{
@@ -656,23 +694,43 @@ void cdfCanvasChord(cdCanvas* canvas, double xc, double yc, double w, double h,
canvas->cxChord(canvas->ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), angle1, angle2);
}
-void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax)
+void cdCanvasGetArcStartEnd(int xc, int yc, int w, int h, double a1, double a2, int *x1, int *y1, int *x2, int *y2)
{
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
+ /* leave xc and yc outside the round, so the center will be always the same */
+
+ if (x1) *x1 = xc + cdRound((w/2.0)*cos(a1*CD_DEG2RAD));
+ if (y1) *y1 = yc + cdRound((h/2.0)*sin(a1*CD_DEG2RAD));
+ if (x2) *x2 = xc + cdRound((w/2.0)*cos(a2*CD_DEG2RAD));
+ if (y2) *y2 = yc + cdRound((h/2.0)*sin(a2*CD_DEG2RAD));
+}
+
+void cdfCanvasGetArcStartEnd(double xc, double yc, double w, double h, double a1, double a2, double *x1, double *y1, double *x2, double *y2)
+{
+ if (x1) *x1 = xc + (w/2.0)*cos(a1*CD_DEG2RAD);
+ if (y1) *y1 = yc + (h/2.0)*sin(a1*CD_DEG2RAD);
+ if (x2) *x2 = xc + (w/2.0)*cos(a2*CD_DEG2RAD);
+ if (y2) *y2 = yc + (h/2.0)*sin(a2*CD_DEG2RAD);
+}
+
+void cdCanvasGetArcBox(int xc, int yc, int w, int h, double a1, double a2, int *xmin, int *xmax, int *ymin, int *ymax)
+{
+ int x, y;
+
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
#define _BBOX() \
if (x > *xmax) *xmax = x; \
if (y > *ymax) *ymax = y; \
if (x < *xmin) *xmin = x; \
if (y < *ymin) *ymin = y;
- int x, y;
-
- *xmin = (int)(xc+w/2*cos(a1*CD_DEG2RAD));
- *ymin = (int)(yc+h/2*sin(a1*CD_DEG2RAD));
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, xmin, ymin, &x, &y);
*xmax = *xmin;
*ymax = *ymin;
-
- x = (int)(xc+w/2*cos(a2*CD_DEG2RAD));
- y = (int)(yc+h/2*sin(a2*CD_DEG2RAD));
_BBOX()
if (a1 > a2)
@@ -700,3 +758,77 @@ void cdCanvasGetEllipseBox(int xc, int yc, int w, int h, double a1, double a2, i
_BBOX()
}
}
+
+int cdCanvasGetArcPath(cdCanvas* canvas, const cdPoint* poly, int *xc, int *yc, int *w, int *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ /* fix integer scale */
+ *a1 /= 1000.0;
+ *a2 /= 1000.0;
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1<a2) or clockwise (a1>a2) */
+ return 1;
+}
+
+int cdfCanvasGetArcPath(cdCanvas* canvas, const cdfPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1<a2) or clockwise (a1>a2) */
+ return 1;
+}
+
+int cdCanvasGetArcPathF(cdCanvas* canvas, const cdPoint* poly, double *xc, double *yc, double *w, double *h, double *a1, double *a2)
+{
+ *xc = poly[0].x;
+ *yc = poly[0].y;
+ *w = poly[1].x;
+ *h = poly[1].y;
+ *a1 = poly[2].x;
+ *a2 = poly[2].y;
+
+ if (canvas->invert_yaxis) /* undo axis invertion */
+ {
+ *h = _cdInvertYAxis(canvas, *h);
+ *a2 = _cdInvertYAxis(canvas, *a2);
+ }
+
+ /* fix integer scale */
+ *a1 /= 1000.0;
+ *a2 /= 1000.0;
+
+ if (*a1 == *a2 || *w == 0 || *h == 0)
+ return 0;
+
+ /* path angles can be counter-clockwise (a1<a2) or clockwise (a1>a2) */
+ return 1;
+}
diff --git a/cd/src/cd_text.c b/cd/src/cd_text.c
index 2568e25..32b0645 100755
--- a/cd/src/cd_text.c
+++ b/cd/src/cd_text.c
@@ -319,7 +319,7 @@ char* cdCanvasNativeFont(cdCanvas* canvas, const char* font)
else
{
char type_face[1024];
- int size, style = CD_PLAIN;
+ int size = 12, style = CD_PLAIN;
if (!cdParseIupWinFont(font, type_face, &style, &size))
{
diff --git a/cd/src/cd_util.c b/cd/src/cd_util.c
index 1767ac4..20e9a46 100755
--- a/cd/src/cd_util.c
+++ b/cd/src/cd_util.c
@@ -263,6 +263,29 @@ void cdRotatePoint(cdCanvas* canvas, int x, int y, int cx, int cy, int *rx, int
*ry = *ry + cy;
}
+void cdfRotatePoint(cdCanvas* canvas, double x, double y, double cx, double cy, double *rx, double *ry, double sin_theta, double cos_theta)
+{
+ /* translate to (cx,cy) */
+ x = x - cx;
+ y = y - cy;
+
+ /* rotate */
+ if (canvas->invert_yaxis)
+ {
+ *rx = (x * cos_theta) + (y * sin_theta);
+ *ry = -(x * sin_theta) + (y * cos_theta);
+ }
+ else
+ {
+ *rx = (x * cos_theta) - (y * sin_theta);
+ *ry = (x * sin_theta) + (y * cos_theta);
+ }
+
+ /* translate back */
+ *rx = *rx + cx;
+ *ry = *ry + cy;
+}
+
void cdRotatePointY(cdCanvas* canvas, int x, int y, int cx, int cy, int *ry, double sin_theta, double cos_theta)
{
double t;
@@ -285,6 +308,8 @@ void cdRotatePointY(cdCanvas* canvas, int x, int y, int cx, int cy, int *ry, dou
*ry = *ry + cy;
}
+/* Copied from IUP3 */
+
int cdStrEqualNoCase(const char* str1, const char* str2)
{
int i = 0;
@@ -298,6 +323,20 @@ int cdStrEqualNoCase(const char* str1, const char* str2)
return 0;
}
+int cdStrEqualNoCasePartial(const char* str1, const char* str2)
+{
+ int i = 0;
+ if (str1 == str2) return 1;
+ if (!str1 || !str2 || tolower(*str1) != tolower(*str2)) return 0;
+
+ while (str1[i] && str2[i] && tolower(str1[i])==tolower(str2[i]))
+ i++;
+ if (str1[i] == str2[i]) return 1;
+ if (str2[i] == 0) return 1;
+
+ return 0;
+}
+
/* Copied from IUP3, simply ignore line breaks other than '\n' for CD */
int cdStrLineCount(const char* str)
@@ -349,3 +388,108 @@ char* cdStrDupN(const char *str, int len)
}
return NULL;
}
+
+void cdSetPaperSize(int size, double *w_pt, double *h_pt)
+{
+ static struct
+ {
+ int w_pt;
+ int h_pt;
+ } paper[] =
+ {
+ { 2393, 3391 }, /* A0 */
+ { 1689, 2393 }, /* A1 */
+ { 1192, 1689 }, /* A2 */
+ { 842, 1192 }, /* A3 */
+ { 595, 842 }, /* A4 */
+ { 420, 595 }, /* A5 */
+ { 612, 792 }, /* LETTER */
+ { 612, 1008 } /* LEGAL */
+ };
+
+ if (size<CD_A0 || size>CD_LEGAL)
+ return;
+
+ *w_pt = (double)paper[size].w_pt;
+ *h_pt = (double)paper[size].h_pt;
+}
+
+#ifdef WIN32
+#include <windows.h>
+static int sReadStringKey(HKEY base_key, char* key_name, char* value_name, char* value)
+{
+ HKEY key;
+ DWORD max_size = 512;
+
+ if (RegOpenKeyEx(base_key, key_name, 0, KEY_READ, &key) != ERROR_SUCCESS)
+ return 0;
+
+ if (RegQueryValueEx(key, value_name, NULL, NULL, (LPBYTE)value, &max_size) != ERROR_SUCCESS)
+ {
+ RegCloseKey(key);
+ return 0;
+ }
+
+ RegCloseKey(key);
+ return 1;
+}
+
+static char* sGetFontDir(void)
+{
+ static char font_dir[512];
+ if (!sReadStringKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Fonts", font_dir))
+ return "";
+ else
+ {
+ int i, size = (int)strlen(font_dir);
+ for(i = 0; i < size; i++)
+ {
+ if (font_dir[i] == '\\')
+ font_dir[i] = '/';
+ }
+ return font_dir;
+ }
+}
+#endif
+
+int cdGetFontFileName(const char* font, char* filename)
+{
+ FILE *file;
+
+ /* current directory */
+ sprintf(filename, "%s.ttf", font);
+ file = fopen(filename, "r");
+
+ if (file)
+ fclose(file);
+ else
+ {
+ /* CD environment */
+ char* env = getenv("CDDIR");
+ if (env)
+ {
+ sprintf(filename, "%s/%s.ttf", env, font);
+ file = fopen(filename, "r");
+ }
+
+ if (file)
+ fclose(file);
+ else
+ {
+#ifdef WIN32
+ /* Windows Font folder */
+ sprintf(filename, "%s/%s.ttf", sGetFontDir(), font);
+ file = fopen(filename, "r");
+
+ if (file)
+ fclose(file);
+ else
+ return 0;
+#else
+ return 0;
+#endif
+ }
+ }
+
+ return 1;
+}
diff --git a/cd/src/drv/cd0emf.c b/cd/src/drv/cd0emf.c
index 13beb4c..7e05134 100755
--- a/cd/src/drv/cd0emf.c
+++ b/cd/src/drv/cd0emf.c
@@ -6,11 +6,19 @@
#include <stdlib.h>
#include "cd.h"
+#include "cd_private.h"
#include "cdemf.h"
cdContext* cdContextEMF(void)
{
+ if (cdUseContextPlus(CD_QUERY))
+ {
+ cdContext* ctx = cdGetContextPlus(CD_CTX_EMF);
+ if (ctx != NULL)
+ return ctx;
+ }
+
return NULL;
}
diff --git a/cd/src/drv/cd0prn.c b/cd/src/drv/cd0prn.c
index 429a392..fa313d8 100755
--- a/cd/src/drv/cd0prn.c
+++ b/cd/src/drv/cd0prn.c
@@ -6,12 +6,20 @@
#include <stdlib.h>
#include "cd.h"
+#include "cd_private.h"
#include "cdprint.h"
cdContext* cdContextPrinter(void)
{
+ if (cdUseContextPlus(CD_QUERY))
+ {
+ cdContext* ctx = cdGetContextPlus(CD_CTX_PRINTER);
+ if (ctx != NULL)
+ return ctx;
+ }
+
return NULL;
}
diff --git a/cd/src/drv/cdcgm.c b/cd/src/drv/cdcgm.c
index ab47c1e..19f6ad7 100755
--- a/cd/src/drv/cdcgm.c
+++ b/cd/src/drv/cdcgm.c
@@ -566,6 +566,12 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
case CD_FILL:
cgm_polygon( ctxcanvas->cgm, n, fpoly);
break;
+ case CD_BEZIER:
+ cdfSimPolyBezier(ctxcanvas->canvas, (cdfPoint*)fpoly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, (cdfPoint*)fpoly, n);
+ break;
}
free(fpoly);
@@ -595,6 +601,12 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
case CD_FILL:
cgm_polygon( ctxcanvas->cgm, n, fpoly);
break;
+ case CD_BEZIER:
+ cdfSimPolyBezier(ctxcanvas->canvas, poly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
}
}
@@ -1122,7 +1134,7 @@ static cdContext cdCGMContext =
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
CD_CAP_FONTDIM | CD_CAP_TEXTSIZE |
CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB |
- CD_CAP_TEXTORIENTATION),
+ CD_CAP_TEXTORIENTATION | CD_CAP_PATH | CD_CAP_BEZIER),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/drv/cddebug.c b/cd/src/drv/cddebug.c
index 23d8446..bd91209 100755
--- a/cd/src/drv/cddebug.c
+++ b/cd/src/drv/cddebug.c
@@ -27,6 +27,7 @@
#define CDDBG_BEGIN "Begin"
#define CDDBG_VERTEX "Vertex"
#define CDDBG_END "End"
+#define CDDBG_PATHSET "PathSet"
#define CDDBG_MARK "Mark"
#define CDDBG_BACKOPACITY "BackOpacity"
#define CDDBG_WRITEMODE "WriteMode"
@@ -68,7 +69,6 @@
struct _cdCtxCanvas
{
cdCanvas* canvas;
- char* filename;
FILE* file;
int last_line_style;
int last_fill_mode;
@@ -237,7 +237,8 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
"CD_CLOSED_LINES",
"CD_CLIP",
"CD_BEZIER",
- "CD_REGION"
+ "CD_REGION",
+ "CD_PATH"
};
if (mode == CD_FILL && ctxcanvas->canvas->fill_mode != ctxcanvas->last_fill_mode)
@@ -255,8 +256,61 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
else
fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_BEGIN, enum2str[mode]);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ const char* path2str[] = {
+ "CD_PATH_NEW",
+ "CD_PATH_MOVETO",
+ "CD_PATH_LINETO",
+ "CD_PATH_ARC",
+ "CD_PATH_CURVETO",
+ "CD_PATH_CLOSE",
+ "CD_PATH_FILL",
+ "CD_PATH_STROKE",
+ "CD_PATH_FILLSTROKE",
+ "CD_PATH_CLIP"
+ };
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_PATHSET, path2str[ctxcanvas->canvas->path[p]]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%s(%d, %d)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%s()\n", CDDBG_END);
}
@@ -285,8 +339,61 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_BEGIN, enum2str[mode]);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_FVERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ const char* path2str[] = {
+ "CD_PATH_NEW",
+ "CD_PATH_MOVETO",
+ "CD_PATH_LINETO",
+ "CD_PATH_ARC",
+ "CD_PATH_CURVETO",
+ "CD_PATH_CLOSE",
+ "CD_PATH_FILL",
+ "CD_PATH_STROKE",
+ "CD_PATH_FILLSTROKE",
+ "CD_PATH_CLIP"
+ };
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%s(%s)\n", CDDBG_PATHSET, path2str[ctxcanvas->canvas->path[p]]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%s(%g, %g)\n", CDDBG_FVERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%s()\n", CDDBG_END);
}
@@ -601,7 +708,6 @@ static void cdgettextsize(cdCtxCanvas* ctxcanvas, const char *s, int len, int *w
static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
{
fprintf(ctxcanvas->file, "KillCanvas()\n");
- free(ctxcanvas->filename);
fclose(ctxcanvas->file);
memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
free(ctxcanvas);
@@ -613,7 +719,6 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data)
char* strdata = (char*)data;
double w_mm = INT_MAX*3.78, h_mm = INT_MAX*3.78, res = 3.78;
cdCtxCanvas* ctxcanvas;
- int size;
strdata += cdGetFileName(strdata, filename);
if (filename[0] == 0)
@@ -631,10 +736,6 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data)
return;
}
- size = strlen(filename);
- ctxcanvas->filename = malloc(size+1);
- memcpy(ctxcanvas->filename, filename, size+1);
-
ctxcanvas->canvas = canvas;
/* update canvas context */
diff --git a/cd/src/drv/cddgn.c b/cd/src/drv/cddgn.c
index d7dd5f9..dd049fd 100755
--- a/cd/src/drv/cddgn.c
+++ b/cd/src/drv/cddgn.c
@@ -1066,6 +1066,17 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
short is_fill=0;
+ if (mode == CD_BEZIER)
+ {
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if(mode == CD_FILL && ctxcanvas->fill_type == NOFILL)
mode = CD_CLOSED_LINES;
@@ -1667,7 +1678,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDGNContext =
{
- CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY |
+ CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PATH | CD_CAP_BEZIER |
CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB |
CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY | CD_CAP_RECT |
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
diff --git a/cd/src/drv/cddxf.c b/cd/src/drv/cddxf.c
index db05978..c5d0df5 100755
--- a/cd/src/drv/cddxf.c
+++ b/cd/src/drv/cddxf.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <math.h>
#include <limits.h>
+
#include "cd.h"
#include "cd_private.h"
#include "cddxf.h"
@@ -182,6 +183,123 @@ static void writepolyf (cdCtxCanvas *ctxcanvas, cdfPoint *poly, int nv) /* write
fprintf ( ctxcanvas->file, "SEQEND\n" );
}
+static void writehatch (cdCtxCanvas *ctxcanvas, cdPoint *poly, int nv) /* write polygon */
+{
+ int i;
+
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "HATCH\n" );
+ fprintf ( ctxcanvas->file, "8\n" );
+ fprintf ( ctxcanvas->file, "%d\n", ctxcanvas->layer); /* current layer */
+ fprintf ( ctxcanvas->file, "62\n" );
+ fprintf ( ctxcanvas->file, "%d\n", ctxcanvas->fgcolor );
+
+ fprintf ( ctxcanvas->file, "10\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "20\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "30\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+
+ fprintf ( ctxcanvas->file, "210\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "220\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "230\n" );
+ fprintf ( ctxcanvas->file, "1.0\n" );
+
+ fprintf ( ctxcanvas->file, "2\n" );
+ fprintf ( ctxcanvas->file, "SOLID\n" );
+ fprintf ( ctxcanvas->file, "70\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+ fprintf ( ctxcanvas->file, "71\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "91\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+
+ fprintf ( ctxcanvas->file, "92\n" );
+ fprintf ( ctxcanvas->file, "2\n" );
+ fprintf ( ctxcanvas->file, "72\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+
+ fprintf ( ctxcanvas->file, "73\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+ fprintf ( ctxcanvas->file, "93\n" ); /* entire polygon line width */
+ fprintf ( ctxcanvas->file, "%d\n", nv );
+ for ( i=0; i<nv; i++ )
+ {
+ fprintf ( ctxcanvas->file, "10\n" );
+ fprintf ( ctxcanvas->file, "%f\n", poly[i].x/ctxcanvas->canvas->xres );
+ fprintf ( ctxcanvas->file, "20\n" );
+ fprintf ( ctxcanvas->file, "%f\n", poly[i].y/ctxcanvas->canvas->xres );
+ }
+
+ fprintf ( ctxcanvas->file, "97\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "75\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "76\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+}
+
+static void writehatchf (cdCtxCanvas *ctxcanvas, cdfPoint *poly, int nv) /* write polygon */
+{
+ int i;
+
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "HATCH\n" );
+ fprintf ( ctxcanvas->file, "8\n" );
+ fprintf ( ctxcanvas->file, "%d\n", ctxcanvas->layer); /* current layer */
+ fprintf ( ctxcanvas->file, "62\n" );
+ fprintf ( ctxcanvas->file, "%d\n", ctxcanvas->fgcolor );
+
+ fprintf ( ctxcanvas->file, "10\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "20\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "30\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+
+ fprintf ( ctxcanvas->file, "210\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "220\n" );
+ fprintf ( ctxcanvas->file, "0.0\n" );
+ fprintf ( ctxcanvas->file, "230\n" );
+ fprintf ( ctxcanvas->file, "1.0\n" );
+
+ fprintf ( ctxcanvas->file, "2\n" );
+ fprintf ( ctxcanvas->file, "SOLID\n" );
+ fprintf ( ctxcanvas->file, "70\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+ fprintf ( ctxcanvas->file, "71\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "91\n" ); /* entire polygon line width */
+ fprintf ( ctxcanvas->file, "1\n" );
+
+ fprintf ( ctxcanvas->file, "92\n" );
+ fprintf ( ctxcanvas->file, "2\n" );
+ fprintf ( ctxcanvas->file, "72\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+
+ fprintf ( ctxcanvas->file, "73\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+ fprintf ( ctxcanvas->file, "93\n" ); /* entire polygon line width */
+ fprintf ( ctxcanvas->file, "%d\n", nv );
+ for ( i=0; i<nv; i++ )
+ {
+ fprintf ( ctxcanvas->file, "10\n" );
+ fprintf ( ctxcanvas->file, "%f\n", poly[i].x/ctxcanvas->canvas->xres );
+ fprintf ( ctxcanvas->file, "20\n" );
+ fprintf ( ctxcanvas->file, "%f\n", poly[i].y/ctxcanvas->canvas->xres );
+ }
+ fprintf ( ctxcanvas->file, "97\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "75\n" );
+ fprintf ( ctxcanvas->file, "0\n" );
+ fprintf ( ctxcanvas->file, "76\n" );
+ fprintf ( ctxcanvas->file, "1\n" );
+}
+
static void deflines (cdCtxCanvas *ctxcanvas) /* define lines */
{
int i, j;
@@ -323,6 +441,17 @@ static void cdflush (cdCtxCanvas *ctxcanvas)
/*==========================================================================*/
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
+ if (mode == CD_BEZIER)
+ {
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if (mode == CD_CLOSED_LINES || mode == CD_FILL)
{
poly[n].x = poly[0].x;
@@ -330,7 +459,10 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
n++;
}
- writepoly (ctxcanvas, poly, n); /* write polygon */
+ if( mode == CD_FILL )
+ writehatch (ctxcanvas, poly, n); /* write fill area */
+ else
+ writepoly (ctxcanvas, poly, n); /* write polygon */
}
static void cdline (cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
@@ -344,7 +476,7 @@ static void cdline (cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
writepoly (ctxcanvas, line, 2); /* draw line as a polygon */
}
-static void cdboxrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
cdPoint rect[5]; /* uses new array of points to avoid */
@@ -361,8 +493,36 @@ static void cdboxrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int
writepoly (ctxcanvas, rect, 5); /* draw box as a polygon */
}
+static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdPoint rect[5]; /* uses new array of points to avoid */
+
+ rect[0].x = xmin;
+ rect[0].y = ymin;
+ rect[1].x = xmin;
+ rect[1].y = ymax;
+ rect[2].x = xmax; /* box edges */
+ rect[2].y = ymax;
+ rect[3].x = xmax;
+ rect[3].y = ymin;
+ rect[4].x = xmin;
+ rect[4].y = ymin;
+ writehatch (ctxcanvas, rect, 5); /* write fill area */
+}
+
static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
+ if (mode == CD_BEZIER)
+ {
+ cdfSimPolyBezier(ctxcanvas->canvas, poly, n);
+ return;
+ }
+ if (mode == CD_PATH)
+ {
+ cdfSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
if (mode == CD_CLOSED_LINES || mode == CD_FILL)
{
poly[n].x = poly[0].x;
@@ -370,7 +530,10 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
n++;
}
- writepolyf (ctxcanvas, poly, n); /* write polygon */
+ if( mode == CD_FILL )
+ writehatchf (ctxcanvas, poly, n); /* write fill area */
+ else
+ writepolyf (ctxcanvas, poly, n); /* write polygon */
}
static void cdfline (cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
@@ -384,7 +547,7 @@ static void cdfline (cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, do
writepolyf (ctxcanvas, line, 2); /* draw line as a polygon */
}
-static void cdfboxrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
cdfPoint rect[5]; /* uses new array of points to avoid */
@@ -401,6 +564,23 @@ static void cdfboxrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double
writepolyf (ctxcanvas, rect, 5); /* draw box as a polygon */
}
+static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ cdfPoint rect[5]; /* uses new array of points to avoid */
+
+ rect[0].x = xmin;
+ rect[0].y = ymin;
+ rect[1].x = xmin;
+ rect[1].y = ymax;
+ rect[2].x = xmax; /* box edges */
+ rect[2].y = ymax;
+ rect[3].x = xmax;
+ rect[3].y = ymin;
+ rect[4].x = xmin;
+ rect[4].y = ymin;
+ writehatchf (ctxcanvas, rect, 5); /* write fill area */
+}
+
/*--------------------------------------------------------------------------*/
/* gives radius of the circle most resembling elliptic arc at angle t */
/*--------------------------------------------------------------------------*/
@@ -503,6 +683,7 @@ static void cdarc (cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
bulge = calc_bulge (a, b, t, t+seg_angle); /* and t+seg_angle and write */
writevertex (ctxcanvas, xc, yc, a, b, t, bulge); /* vertex at t */
}
+
writevertex (ctxcanvas, xc, yc, a, b, t2, 0); /* bulge of last vertex is useless */
fprintf ( ctxcanvas->file, "0\n" );
@@ -551,12 +732,15 @@ static void cdsector (cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doub
if ((a2-a1) != 360)
writevertex (ctxcanvas, xc, yc, 0, 0, 0, 0); /* center */
+
for (i=0, t=t1; i<nseg; i++, t+=seg_angle)
{ /* calculate bulge between t */
bulge = calc_bulge (a, b, t, t+seg_angle); /* and t+seg_angle and write */
writevertex (ctxcanvas, xc, yc, a, b, t, bulge); /* vertex at t */
}
+
writevertex (ctxcanvas, xc, yc, a, b, t2, 0); /* bulge of last vertex is useless */
+
if ((a2-a1) != 360)
writevertex (ctxcanvas, xc, yc, 0, 0, 0, 0); /* center */
@@ -1066,6 +1250,10 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
fprintf (ctxcanvas->file, "SECTION\n"); /* header maker */
fprintf (ctxcanvas->file, "2\n");
fprintf (ctxcanvas->file, "HEADER\n");
+ fprintf (ctxcanvas->file, " 9\n");
+ fprintf (ctxcanvas->file, "$ACADVER\n");
+ fprintf (ctxcanvas->file, " 1\n");
+ fprintf (ctxcanvas->file, "AC1006\n"); /* AutoCad R10 */
fprintf (ctxcanvas->file, "9\n");
fprintf (ctxcanvas->file, "$LIMCHECK\n");
fprintf (ctxcanvas->file, "70\n");
@@ -1142,12 +1330,12 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxPixel = cdpixel;
canvas->cxLine = cdline;
canvas->cxPoly = cdpoly;
- canvas->cxRect = cdboxrect;
- canvas->cxBox = cdboxrect;
+ canvas->cxRect = cdrect;
+ canvas->cxBox = cdbox;
canvas->cxFLine = cdfline;
canvas->cxFPoly = cdfpoly;
- canvas->cxFRect = cdfboxrect;
- canvas->cxFBox = cdfboxrect;
+ canvas->cxFRect = cdfrect;
+ canvas->cxFBox = cdfbox;
canvas->cxArc = cdarc;
canvas->cxSector = cdsector;
canvas->cxText = cdtext;
@@ -1169,7 +1357,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDXFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PALETTE |
- CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY |
+ CD_CAP_CLIPAREA | CD_CAP_CLIPPOLY | CD_CAP_PATH | CD_CAP_BEZIER |
CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION | CD_CAP_CHORD |
CD_CAP_IMAGERGB | CD_CAP_IMAGEMAP | CD_CAP_IMAGESRV |
CD_CAP_BACKGROUND | CD_CAP_BACKOPACITY | CD_CAP_WRITEMODE |
diff --git a/cd/src/drv/cdgl.c b/cd/src/drv/cdgl.c
new file mode 100644
index 0000000..4357e5a
--- /dev/null
+++ b/cd/src/drv/cdgl.c
@@ -0,0 +1,1559 @@
+/** \file
+ * \brief OpenGL Base Driver
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <iconv.h>
+#endif
+
+#include <GL/gl.h>
+
+#include <FTGL/ftgl.h>
+
+#include "cd.h"
+#include "cd_private.h"
+#include "cdgl.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define NUM_HATCHES 6
+#define HATCH_WIDTH 8
+#define HATCH_HEIGHT 8
+
+/*
+** 6 predefined patterns to be accessed through cdHatch(
+CD_HORIZONTAL | CD_VERTICAL | CD_FDIAGONAL | CD_BDIAGONAL |
+CD_CROSS | CD_DIAGCROSS)
+
+*/
+static char hatches[NUM_HATCHES][8] = {
+ {0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00}, /* HORIZONTAL */
+ {0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22}, /* VERTICAL */
+ {0x08,0x10,0x20,0x40,0x80,0x01,0x02,0x04}, /* FDIAGONAL */
+ {0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20}, /* BDIAGONAL */
+ {0x22,0x22,0xFF,0x22,0x22,0x22,0xFF,0x22}, /* CROSS */
+ {0x18,0x18,0x24,0x42,0x81,0x81,0x42,0x24} /* DIAGCROSS */
+};
+
+struct _cdCtxImage
+{
+ unsigned int w, h, depth;
+ GLubyte* img;
+};
+
+struct _cdCtxCanvas
+{
+ cdCanvas* canvas;
+
+ FTGLfont *font;
+
+ char* glLastConvertUTF8;
+
+ float rotate_angle;
+ int rotate_center_x;
+ int rotate_center_y;
+
+ int poly_holes[500];
+ int holes;
+};
+
+/******************************************************/
+
+static char* cdglStrConvertToUTF8(cdCtxCanvas *ctxcanvas, const char* str, int len)
+{
+ if (ctxcanvas->glLastConvertUTF8)
+ free(ctxcanvas->glLastConvertUTF8);
+
+#ifdef WIN32
+ {
+ wchar_t* toUnicode;
+ int wlen = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
+ if(!wlen)
+ return (char*)str;
+
+ toUnicode = (wchar_t*)calloc((wlen+1), sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, str, len, toUnicode, wlen);
+ toUnicode[wlen] = 0;
+
+ len = WideCharToMultiByte(CP_UTF8, 0, toUnicode, wlen, NULL, 0, NULL, NULL);
+ if(!len)
+ return (char*)str;
+
+ ctxcanvas->glLastConvertUTF8 = (char*)calloc((len+1), sizeof(char));
+ WideCharToMultiByte(CP_UTF8, 0, toUnicode, wlen, ctxcanvas->glLastConvertUTF8, len, NULL, NULL);
+ ctxcanvas->glLastConvertUTF8[len] = 0;
+
+ free(toUnicode);
+ }
+#else
+ {
+ /* Based on http://www.lemoda.net/c/iconv-example/iconv-example.html
+ Last access: June 15th, 2010. */
+ iconv_t cd;
+ size_t ulen = (size_t)len;
+ size_t utf8len = ulen*2;
+ char* utf8 = calloc(utf8len, 1);
+
+ cd = iconv_open("UTF-8", "ISO-8859-1");
+ if(cd == (iconv_t)-1)
+ return (char*)str;
+
+ ctxcanvas->glLastConvertUTF8 = utf8;
+ iconv(cd, (char**)&str, &ulen, &utf8, &utf8len);
+
+ iconv_close(cd);
+ }
+#endif
+
+ return ctxcanvas->glLastConvertUTF8;
+}
+
+/******************************************************/
+
+static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
+{
+ if(ctxcanvas->font)
+ ftglDestroyFont(ctxcanvas->font);
+
+ if (ctxcanvas->glLastConvertUTF8)
+ free(ctxcanvas->glLastConvertUTF8);
+
+ free(ctxcanvas);
+}
+
+/******************************************************/
+
+static void cdflush(cdCtxCanvas *ctxcanvas)
+{
+ glFlush();
+ (void)ctxcanvas;
+}
+
+/******************************************************/
+
+static int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode)
+{
+ switch (clip_mode)
+ {
+ case CD_CLIPOFF:
+ if(glIsEnabled(GL_SCISSOR_TEST))
+ glDisable(GL_SCISSOR_TEST);
+ break;
+ case CD_CLIPAREA:
+ {
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(ctxcanvas->canvas->clip_rect.xmin, ctxcanvas->canvas->clip_rect.ymin,
+ (ctxcanvas->canvas->clip_rect.xmax - ctxcanvas->canvas->clip_rect.xmin),
+ (ctxcanvas->canvas->clip_rect.ymax - ctxcanvas->canvas->clip_rect.ymin));
+ break;
+ }
+ case CD_CLIPPOLYGON:
+ break;
+ case CD_CLIPREGION:
+ break;
+ }
+
+ return clip_mode;
+}
+
+static void cdfcliparea(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPAREA)
+ {
+ ctxcanvas->canvas->clip_rect.xmin = (int)xmin;
+ ctxcanvas->canvas->clip_rect.ymin = (int)ymin;
+ ctxcanvas->canvas->clip_rect.xmax = (int)xmax;
+ ctxcanvas->canvas->clip_rect.ymax = (int)ymax;
+ cdclip(ctxcanvas, CD_CLIPAREA);
+ }
+}
+
+static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfcliparea(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+/******************************************************/
+
+static int cdwritemode(cdCtxCanvas *ctxcanvas, int write_mode)
+{
+ switch (write_mode)
+ {
+ case CD_REPLACE:
+ if(glIsEnabled(GL_COLOR_LOGIC_OP))
+ glDisable(GL_COLOR_LOGIC_OP);
+ break;
+ case CD_XOR:
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_XOR);
+ break;
+ case CD_NOT_XOR:
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_EQUIV);
+ break;
+ }
+
+ (void)ctxcanvas;
+ return write_mode;
+}
+
+static int cdhatch(cdCtxCanvas *ctxcanvas, int hatch_style)
+{
+ GLubyte pattern[128];
+ int x, y, pos = 0;
+
+ glEnable(GL_POLYGON_STIPPLE);
+
+ for (y = 0; y < 128; y+=8)
+ {
+ for (x = 0; x < 8; x++)
+ pattern[x+y] = hatches[hatch_style][pos];
+ pos++;
+
+ if(pos > 7) /* repeat the pattern */
+ pos = 0;
+ }
+ glPolygonStipple(pattern);
+
+ (void)ctxcanvas;
+ return hatch_style;
+}
+
+static int cdinteriorstyle(cdCtxCanvas *ctxcanvas, int style)
+{
+ switch (style)
+ {
+ case CD_HOLLOW:
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ break;
+ case CD_SOLID:
+ case CD_HATCH :
+ case CD_STIPPLE:
+ case CD_PATTERN:
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ break;
+ }
+
+ switch (style)
+ {
+ case CD_STIPPLE:
+ case CD_PATTERN:
+ case CD_HOLLOW:
+ case CD_SOLID:
+ if(glIsEnabled(GL_POLYGON_STIPPLE))
+ glDisable(GL_POLYGON_STIPPLE);
+ break;
+ case CD_HATCH:
+ cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
+ break;
+ }
+
+ return style;
+}
+
+static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *pattern)
+{
+ (void)pattern;
+ (void)m;
+ (void)n;
+ cdinteriorstyle(ctxcanvas, CD_SOLID);
+}
+
+static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple)
+{
+ (void)stipple;
+ (void)m;
+ (void)n;
+ cdinteriorstyle(ctxcanvas, CD_SOLID);
+}
+
+static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
+{
+ switch (style)
+ {
+ case CD_CONTINUOUS:
+ if(glIsEnabled(GL_LINE_STIPPLE))
+ glDisable(GL_LINE_STIPPLE);
+ return style;
+ break;
+ case CD_DASHED:
+ case CD_DOTTED:
+ case CD_DASH_DOT:
+ case CD_DASH_DOT_DOT:
+ case CD_CUSTOM:
+ glEnable(GL_LINE_STIPPLE);
+ break;
+ }
+
+ switch (style)
+ {
+ case CD_DASHED:
+ glLineStipple(1, 0x3F);
+ break;
+ case CD_DOTTED:
+ glLineStipple(1, 0x33);
+ break;
+ case CD_DASH_DOT:
+ glLineStipple(1, 0x33F);
+ break;
+ case CD_DASH_DOT_DOT:
+ glLineStipple(1, 0x333F);
+ break;
+ case CD_CUSTOM:
+ /* style patterns more than 16 bits are not drawn completely */
+ glLineStipple(1, (GLushort)*ctxcanvas->canvas->line_dashes);
+ break;
+ }
+
+ return style;
+}
+
+static int cdlinewidth(cdCtxCanvas *ctxcanvas, int width)
+{
+ if (width == 0)
+ width = 1;
+
+ glLineWidth((GLfloat)width);
+
+ (void)ctxcanvas;
+ return width;
+}
+
+/***********************************************************************************/
+/* Functions to get the font name path */
+/* Base source = https://www.h3dapi.org:8090/H3DAPI/trunk/H3DAPI/src/FontStyle.cpp */
+/***********************************************************************************/
+#ifdef WIN32
+static LONG cdglWGetNextNameValue(HKEY key, LPCTSTR subkey, LPTSTR szName, LPTSTR szData)
+{
+ static HKEY hkey = NULL;
+ static DWORD dwIndex = 0;
+ LONG retval;
+
+ if (subkey == NULL && szName == NULL && szData == NULL)
+ {
+ if (hkey)
+ RegCloseKey(hkey);
+
+ hkey = NULL;
+ dwIndex = 0;
+ return ERROR_SUCCESS;
+ }
+
+ if (subkey && subkey[0] != 0)
+ {
+ retval = RegOpenKeyEx(key, subkey, 0, KEY_READ, &hkey);
+ if (retval != ERROR_SUCCESS)
+ return retval;
+
+ dwIndex = 0;
+ }
+ else
+ dwIndex++;
+
+ *szName = 0;
+ *szData = 0;
+
+ {
+ char szValueName[MAX_PATH];
+ DWORD dwValueNameSize = sizeof(szValueName)-1;
+ BYTE szValueData[MAX_PATH];
+ DWORD dwValueDataSize = sizeof(szValueData)-1;
+ DWORD dwType = 0;
+
+ retval = RegEnumValue(hkey, dwIndex, szValueName, &dwValueNameSize, NULL, &dwType, szValueData, &dwValueDataSize);
+ if (retval == ERROR_SUCCESS)
+ {
+ lstrcpy(szName, (char *)szValueName);
+ lstrcpy(szData, (char *)szValueData);
+ }
+ }
+
+ return retval;
+}
+
+static int sReadStringKey(HKEY base_key, char* key_name, char* value_name, char* value)
+{
+ HKEY key;
+ DWORD max_size = 512;
+
+ if (RegOpenKeyEx(base_key, key_name, 0, KEY_READ, &key) != ERROR_SUCCESS)
+ return 0;
+
+ if (RegQueryValueEx(key, value_name, NULL, NULL, (LPBYTE)value, &max_size) != ERROR_SUCCESS)
+ {
+ RegCloseKey(key);
+ return 0;
+ }
+
+ RegCloseKey(key);
+ return 1;
+}
+
+static char* sGetFontDir(void)
+{
+ static char font_dir[1024];
+ if (!sReadStringKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Fonts", font_dir))
+ return "";
+ else
+ return font_dir;
+}
+
+static int sGetFontFileName(const char *font_name, int bold, int italic, char* fileName)
+{
+ TCHAR szName[2 * MAX_PATH];
+ TCHAR szData[2 * MAX_PATH];
+ LPCTSTR strFont = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
+ char localFontName[256];
+ int bResult = 0;
+
+ if (cdStrEqualNoCase(font_name, "Courier") || cdStrEqualNoCase(font_name, "Monospace"))
+ font_name = "Courier New";
+ else if (cdStrEqualNoCase(font_name, "Times") || cdStrEqualNoCase(font_name, "Serif"))
+ font_name = "Times New Roman";
+ else if (cdStrEqualNoCase(font_name, "Helvetica") || cdStrEqualNoCase(font_name, "Sans"))
+ font_name = "Arial";
+
+ strcpy(localFontName, font_name);
+
+ if (bold)
+ strcat(localFontName, " Bold");
+
+ if (italic)
+ strcat(localFontName, " Italic");
+
+ while (cdglWGetNextNameValue(HKEY_LOCAL_MACHINE, strFont, szName, szData) == ERROR_SUCCESS)
+ {
+ if (cdStrEqualNoCasePartial(szName, localFontName))
+ {
+ //"%s/%s.ttf"
+ sprintf(fileName, "%s\\%s", sGetFontDir(), szData);
+ bResult = 1;
+ break;
+ }
+ strFont = NULL;
+ }
+
+ /* close the registry key */
+ cdglWGetNextNameValue(HKEY_LOCAL_MACHINE, NULL, NULL, NULL);
+
+ return bResult;
+}
+#else
+#ifndef NO_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+
+static int sGetFontFileName(const char *font_name, int bold, int italic, char* fileName)
+{
+ char styles[4][20];
+ int style_size;
+ FcObjectSet *os = 0;
+ FcFontSet *fs;
+ FcPattern *pat;
+ int bResult = 0;
+
+ if (cdStrEqualNoCase(font_name, "Courier") || cdStrEqualNoCase(font_name, "Courier New") || cdStrEqualNoCase(font_name, "Monospace"))
+ font_name = "freemono";
+ else if (cdStrEqualNoCase(font_name, "Times") || cdStrEqualNoCase(font_name, "Times New Roman")|| cdStrEqualNoCase(font_name, "Serif"))
+ font_name = "freeserif";
+ else if (cdStrEqualNoCase(font_name, "Helvetica") || cdStrEqualNoCase(font_name, "Arial") || cdStrEqualNoCase(font_name, "Sans"))
+ font_name = "freesans";
+
+ if( bold && italic )
+ {
+ strcpy(styles[0], "BoldItalic");
+ strcpy(styles[1], "Bold Italic");
+ strcpy(styles[2], "Bold Oblique");
+ strcpy(styles[3], "BoldOblique");
+ style_size = 4;
+ }
+ else if( bold )
+ {
+ strcpy(styles[0], "Bold");
+ style_size = 1;
+ }
+ else if( italic )
+ {
+ strcpy(styles[0], "Italic");
+ strcpy(styles[1], "Oblique");
+ style_size = 2;
+ }
+ else
+ {
+ strcpy(styles[0], "Regular");
+ strcpy(styles[1], "Normal");
+ strcpy(styles[2], "Medium");
+ style_size = 3;
+ }
+
+ pat = FcPatternCreate();
+ os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_STYLE, NULL);
+ fs = FcFontList(NULL, pat, os);
+ if (pat)
+ FcPatternDestroy(pat);
+
+ if(fs)
+ {
+ int j, s;
+
+ for (j = 0; j < fs->nfont; j++)
+ {
+ FcChar8 *file;
+ FcChar8 *style;
+ FcChar8 *family;
+
+ FcPatternGetString(fs->fonts[j], FC_FILE, 0, &file);
+ FcPatternGetString(fs->fonts[j], FC_STYLE, 0, &style );
+ FcPatternGetString(fs->fonts[j], FC_FAMILY, 0, &family );
+
+ if (cdStrEqualNoCasePartial((char*)family, font_name))
+ {
+ /* check if the font is of the correct type. */
+ for(s = 0; s < style_size; s++ )
+ {
+ if (cdStrEqualNoCase(styles[s], (char*)style))
+ {
+ strcpy(fileName, (char*)file);
+ bResult = 1;
+ FcFontSetDestroy (fs);
+ return bResult;
+ }
+
+ /* set value to use if no more correct font of same family is found. */
+ strcpy(fileName, (char*)file);
+ bResult = 1;
+ }
+ }
+ }
+ FcFontSetDestroy (fs);
+ }
+
+ return bResult;
+}
+#else
+static int sGetFontFileName(const char *font_name, int bold, int italic, char* fileName)
+{
+ (void)font_name;
+ (void)bold;
+ (void)italic;
+ (void)fileName;
+ return 0;
+}
+#endif
+#endif
+
+static int cdfont(cdCtxCanvas *ctxcanvas, const char *typeface, int style, int size)
+{
+ int is_italic = 0, is_bold = 0; /* default is CD_PLAIN */
+ char strFontFileName[10240];
+
+ if (style & CD_BOLD)
+ is_bold = 1;
+
+ if (style & CD_ITALIC)
+ is_italic = 1;
+
+ /* search for the font in the system */
+ if (!sGetFontFileName(typeface, is_bold, is_italic, strFontFileName))
+ {
+ /* try typeface as a file title, compose to get a filename */
+ if (!cdGetFontFileName(typeface, strFontFileName))
+ {
+ /* try the same configuration of the simulation driver */
+ static char * cd_ttf_font_style[4] = {
+ "",
+ "bd",
+ "i",
+ "bi"};
+ char* face = NULL;
+
+ /* check for the pre-defined names */
+ if (cdStrEqualNoCase(typeface, "System"))
+ face = "cour";
+ else if (cdStrEqualNoCase(typeface, "Courier"))
+ face = "cour";
+ else if (cdStrEqualNoCase(typeface, "Times"))
+ face = "times";
+ else if (cdStrEqualNoCase(typeface, "Helvetica"))
+ face = "arial";
+
+ if (face)
+ {
+ /* create a shortname for the file title */
+ char shorname[100];
+ sprintf(shorname, "%s%s", face, cd_ttf_font_style[style&3]);
+ if (!cdGetFontFileName(shorname, strFontFileName))
+ strcpy(strFontFileName, typeface); /* try the typeface as file name */
+ }
+ else
+ strcpy(strFontFileName, typeface); /* try the typeface as file name */
+ }
+ }
+
+ ctxcanvas->font = ftglCreateBufferFont(strFontFileName);
+ if (!ctxcanvas->font)
+ return 0;
+
+ if (size < 0)
+ size = cdGetFontSizePoints(ctxcanvas->canvas, size);
+
+ ftglSetFontFaceSize(ctxcanvas->font, size, 72);
+ ftglSetFontCharMap(ctxcanvas->font, ft_encoding_unicode);
+
+ return 1;
+}
+
+static void cdgetfontdim(cdCtxCanvas *ctxcanvas, int *max_width, int *height, int *ascent, int *descent)
+{
+ if(!ctxcanvas->font)
+ return;
+
+ if (max_width) *max_width = (int)ftglGetFontAdvance(ctxcanvas->font, "W");
+ if (height) *height = (int)ftglGetFontLineHeight(ctxcanvas->font);
+ if (ascent) *ascent = (int)ftglGetFontAscender(ctxcanvas->font);
+ if (descent) *descent = (int)ftglGetFontDescender(ctxcanvas->font);
+}
+
+static long int cdforeground(cdCtxCanvas *ctxcanvas, long int color)
+{
+ unsigned char r, g, b;
+ (void)ctxcanvas;
+
+ cdDecodeColor(color, &r, &g, &b);
+ glColor4ub(r, g, b, cdDecodeAlpha(color));
+
+ return color;
+}
+
+static void cdclear(cdCtxCanvas* ctxcanvas)
+{
+ unsigned char r, g, b;
+ cdDecodeColor(ctxcanvas->canvas->background, &r, &g, &b);
+ glClearColor((GLclampf)((double)r/255.0), (GLclampf)((double)g/255.0), (GLclampf)((double)b/255.0), 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
+{
+ glBegin(GL_LINES);
+ glVertex2d(x1, y1);
+ glVertex2d(x2, y2);
+ glEnd();
+
+ (void)ctxcanvas;
+}
+
+static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
+{
+ cdfline(ctxcanvas, (double)x1, (double)y1, (double)x2, (double)y2);
+}
+
+static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ glBegin(GL_LINE_LOOP);
+ glVertex2d(xmin, ymin);
+ glVertex2d(xmax, ymin);
+ glVertex2d(xmax, ymax);
+ glVertex2d(xmin, ymax);
+ glEnd();
+
+ (void)ctxcanvas;
+}
+
+static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfrect(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ if(ctxcanvas->canvas->back_opacity == CD_OPAQUE && glIsEnabled(GL_POLYGON_STIPPLE))
+ {
+ /* draw twice, one with background color only, and one with foreground color */
+ glDisable(GL_POLYGON_STIPPLE);
+ glColor4ub(cdRed(ctxcanvas->canvas->background), cdGreen(ctxcanvas->canvas->background), cdBlue(ctxcanvas->canvas->background), cdAlpha(ctxcanvas->canvas->background));
+
+ glBegin(GL_QUADS);
+ glVertex2d(xmin, ymin);
+ glVertex2d(xmax, ymin);
+ glVertex2d(xmax, ymax);
+ glVertex2d(xmin, ymax);
+ glEnd();
+
+ glColor4ub(cdRed(ctxcanvas->canvas->foreground), cdGreen(ctxcanvas->canvas->foreground), cdBlue(ctxcanvas->canvas->foreground), cdAlpha(ctxcanvas->canvas->foreground));
+ glEnable(GL_POLYGON_STIPPLE);
+ }
+
+ glBegin(GL_QUADS);
+ glVertex2d(xmin, ymin);
+ glVertex2d(xmax, ymin);
+ glVertex2d(xmax, ymax);
+ glVertex2d(xmin, ymax);
+ glEnd();
+
+ (void)ctxcanvas;
+}
+
+static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+{
+ cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
+}
+
+static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, int len)
+{
+ int stipple = 0;
+ float bounds[6];
+ int w, h, descent, baseline;
+ double x_origin = x;
+ double y_origin = y;
+
+ if (!ctxcanvas->font)
+ return;
+
+ s = cdglStrConvertToUTF8(ctxcanvas, s, len);
+ ftglGetFontBBox(ctxcanvas->font, s, len, bounds);
+
+ descent = (int)ftglGetFontDescender(ctxcanvas->font);
+ w = (int)ceil(bounds[3] - bounds[0]);
+ h = (int)ceil(bounds[4] - bounds[1]);
+ baseline = (int)ftglGetFontLineHeight(ctxcanvas->font) - (int)ftglGetFontAscender(ctxcanvas->font);
+
+ switch (ctxcanvas->canvas->text_alignment)
+ {
+ case CD_BASE_RIGHT:
+ case CD_NORTH_EAST:
+ case CD_EAST:
+ case CD_SOUTH_EAST:
+ x = x - w;
+ break;
+ case CD_BASE_CENTER:
+ case CD_CENTER:
+ case CD_NORTH:
+ case CD_SOUTH:
+ x = x - w/2;
+ break;
+ case CD_BASE_LEFT:
+ case CD_NORTH_WEST:
+ case CD_WEST:
+ case CD_SOUTH_WEST:
+ x = x;
+ break;
+ }
+
+ switch (ctxcanvas->canvas->text_alignment)
+ {
+ case CD_BASE_LEFT:
+ case CD_BASE_CENTER:
+ case CD_BASE_RIGHT:
+ y = y;
+ break;
+ case CD_SOUTH_EAST:
+ case CD_SOUTH_WEST:
+ case CD_SOUTH:
+ y = y - descent;
+ break;
+ case CD_NORTH_EAST:
+ case CD_NORTH:
+ case CD_NORTH_WEST:
+ y = y - h/2 - baseline;
+ break;
+ case CD_CENTER:
+ case CD_EAST:
+ case CD_WEST:
+ y = y - baseline;
+ break;
+ }
+
+ if (ctxcanvas->canvas->text_orientation != 0)
+ {
+ double angle = CD_DEG2RAD * ctxcanvas->canvas->text_orientation;
+ double cos_angle = cos(angle);
+ double sin_angle = sin(angle);
+ cdfRotatePoint(ctxcanvas->canvas, x, y, x_origin, y_origin, &x, &y, sin_angle, cos_angle);
+ }
+
+ if(glIsEnabled(GL_POLYGON_STIPPLE))
+ {
+ stipple = 1;
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+
+ glPushMatrix();
+ glTranslated(x, y, 0.0);
+ glRotated(ctxcanvas->canvas->text_orientation, 0, 0, 1);
+ ftglRenderFont(ctxcanvas->font, s, FTGL_RENDER_ALL);
+ glPopMatrix();
+
+ if(stipple)
+ glEnable(GL_POLYGON_STIPPLE);
+}
+
+static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
+{
+ cdftext(ctxcanvas, (double)x, (double)y, s, len);
+}
+
+static void cdgettextsize(cdCtxCanvas *ctxcanvas, const char *s, int len, int *width, int *height)
+{
+ float bounds[6];
+
+ if (!ctxcanvas->font)
+ return;
+
+ s = cdglStrConvertToUTF8(ctxcanvas, s, len);
+ ftglGetFontBBox(ctxcanvas->font, s, len, bounds);
+
+ if (width) *width = (int)ceil(bounds[3] - bounds[0]);
+ if (height) *height = (int)ceil(bounds[4] - bounds[1]);
+}
+
+static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
+{
+ int i;
+
+ if (mode == CD_CLIP)
+ return;
+
+ if (mode == CD_BEZIER)
+ {
+ int i, prec = 100;
+ float (*points)[3] = malloc(n * sizeof(*points));
+
+ for(i = 0; i < n; i++)
+ {
+ points[i][0] = (float)poly[i].x;
+ points[i][1] = (float)poly[i].y;
+ points[i][2] = 0;
+ }
+
+ glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, n, &points[0][0]);
+ glEnable(GL_MAP1_VERTEX_3);
+ glMapGrid1f(prec, 0.0, 1.0);
+ glEvalMesh1(GL_LINE, 0, prec);
+ glDisable(GL_MAP1_VERTEX_3);
+
+ free(points);
+ return;
+ }
+
+ if (mode == CD_PATH)
+ {
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
+ switch (mode)
+ {
+ case CD_CLOSED_LINES :
+ glBegin(GL_LINE_LOOP);
+ break;
+ case CD_OPEN_LINES :
+ glBegin(GL_LINE_STRIP);
+ break;
+ case CD_FILL :
+ if(ctxcanvas->canvas->back_opacity == CD_OPAQUE && glIsEnabled(GL_POLYGON_STIPPLE))
+ {
+ /* draw twice, one with background color only, and one with foreground color */
+ glDisable(GL_POLYGON_STIPPLE);
+ glColor4ub(cdRed(ctxcanvas->canvas->background), cdGreen(ctxcanvas->canvas->background), cdBlue(ctxcanvas->canvas->background), cdAlpha(ctxcanvas->canvas->background));
+
+ glBegin(GL_POLYGON);
+ for(i = 0; i < n; i++)
+ glVertex2i(poly[i].x, poly[i].y);
+ glEnd();
+
+ glColor4ub(cdRed(ctxcanvas->canvas->foreground), cdGreen(ctxcanvas->canvas->foreground), cdBlue(ctxcanvas->canvas->foreground), cdAlpha(ctxcanvas->canvas->foreground));
+ glEnable(GL_POLYGON_STIPPLE);
+ }
+
+ glBegin(GL_POLYGON);
+ break;
+ }
+
+ for(i = 0; i < n; i++)
+ glVertex2i(poly[i].x, poly[i].y);
+ glEnd();
+
+ (void)ctxcanvas;
+}
+
+static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
+{
+ int i;
+
+ if (mode == CD_CLIP)
+ return;
+
+ if (mode == CD_BEZIER)
+ {
+ int i, prec = 100;
+ double (*points)[3] = malloc(n * sizeof(*points));
+
+ for(i = 0; i < n; i++)
+ {
+ points[i][0] = poly[i].x;
+ points[i][1] = poly[i].y;
+ points[i][2] = 0;
+ }
+
+ glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, n, &points[0][0]);
+ glEnable(GL_MAP1_VERTEX_3);
+ glMapGrid1d(prec, 0.0, 1.0);
+ glEvalMesh1(GL_LINE, 0, prec);
+ glDisable(GL_MAP1_VERTEX_3);
+
+ free(points);
+ return;
+ }
+
+ if (mode == CD_PATH)
+ {
+ cdfSimPolyPath(ctxcanvas->canvas, poly, n);
+ return;
+ }
+
+ switch (mode)
+ {
+ case CD_CLOSED_LINES :
+ glBegin(GL_LINE_LOOP);
+ break;
+ case CD_OPEN_LINES :
+ glBegin(GL_LINE_STRIP);
+ break;
+ case CD_FILL :
+ if(ctxcanvas->canvas->back_opacity == CD_OPAQUE && glIsEnabled(GL_POLYGON_STIPPLE))
+ {
+ glDisable(GL_POLYGON_STIPPLE);
+ glColor4ub(cdRed(ctxcanvas->canvas->background), cdGreen(ctxcanvas->canvas->background), cdBlue(ctxcanvas->canvas->background), cdAlpha(ctxcanvas->canvas->background));
+
+ glBegin(GL_POLYGON);
+ for(i = 0; i < n; i++)
+ glVertex2d(poly[i].x, poly[i].y);
+ glEnd();
+
+ glColor4ub(cdRed(ctxcanvas->canvas->foreground), cdGreen(ctxcanvas->canvas->foreground), cdBlue(ctxcanvas->canvas->foreground), cdAlpha(ctxcanvas->canvas->foreground));
+ glEnable(GL_POLYGON_STIPPLE);
+ }
+
+ glBegin(GL_POLYGON);
+ break;
+ }
+
+ for(i = 0; i < n; i++)
+ glVertex2d(poly[i].x, poly[i].y);
+ glEnd();
+
+ (void)ctxcanvas;
+}
+
+/******************************************************/
+
+static void cdglGetImageData(GLubyte* glImage, unsigned char *r, unsigned char *g, unsigned char *b, int w, int h)
+{
+ int y, x;
+ unsigned char *pixline_data;
+ int rowstride, channels = 3;
+
+ rowstride = w * channels;
+
+ /* planes are separated in image data */
+ for (y = 0; y < h; y++)
+ {
+ int lineoffset = y * w;
+ pixline_data = (unsigned char*)glImage + y * rowstride;
+ for(x = 0; x < w; x++)
+ {
+ int pos = x*channels;
+ r[lineoffset+x] = pixline_data[pos];
+ g[lineoffset+x] = pixline_data[pos+1];
+ b[lineoffset+x] = pixline_data[pos+2];
+ }
+ }
+}
+
+static GLubyte* cdglCreateImageRGBA(int width, int height, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int image_width)
+{
+ GLubyte* pixline_data;
+ GLubyte* glImage;
+ int x, y;
+ int channels = a ? 4 : 3;
+ int rowstride = width * channels;
+ int lineoffset;
+
+ glImage = (GLubyte*)malloc(rowstride * height);
+
+ /* planes are separated in image data */
+ for (y = 0; y < height; y++)
+ {
+ lineoffset = y * image_width;
+ pixline_data = glImage + y * rowstride;
+
+ for(x=0;x<width;x++)
+ {
+ int pos = x*channels;
+ pixline_data[pos] = r[lineoffset+x];
+ pixline_data[pos+1] = g[lineoffset+x];
+ pixline_data[pos+2] = b[lineoffset+x];
+
+ if (a)
+ pixline_data[pos+3] = a[lineoffset+x];
+ }
+ }
+
+ return glImage;
+}
+
+static GLubyte* cdglCreateImageMap(int width, int height, const long* colors, const unsigned char *map, int image_width)
+{
+ const GLubyte *line_data;
+ GLubyte *pixline_data;
+ GLubyte *glImage;
+ int x, y, channels = 3;
+ int rowstride = width * channels;
+
+ glImage = (GLubyte*)malloc(rowstride * height);
+
+ for (y = 0; y < height; y++)
+ {
+ pixline_data = glImage + y * rowstride;
+ line_data = map + y * image_width;
+
+ for (x=0; x<width; x++)
+ {
+ GLubyte index = line_data[x];
+ long c = colors[index];
+ GLubyte *r = &pixline_data[channels*x],
+ *g = r+1,
+ *b = g+1;
+
+ *r = cdRed(c);
+ *g = cdGreen(c);
+ *b = cdBlue(c);
+ }
+ }
+
+ return glImage;
+}
+
+static void cdgetimagergb(cdCtxCanvas *ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)
+{
+ GLubyte* glImage = (GLubyte*)malloc((w*3)*h); /* each pixel uses 3 bytes (RGB) */
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, glImage);
+ if (!glImage)
+ return;
+
+ cdglGetImageData(glImage, r, g, b, w, h);
+
+ (void)ctxcanvas;
+
+ free(glImage);
+}
+
+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)
+{
+ /* Images are bitmaps, and cannot be directly rotated or scaled */
+ GLubyte* glImage;
+ int rw = xmax-xmin+1;
+ int rh = ymax-ymin+1;
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ glImage = cdglCreateImageRGBA(rw, rh, r, g, b, NULL, iw);
+ if (!glImage)
+ return;
+
+ /* adjusts when the initial position (x,y) are less than 0 */
+ if(x < 0)
+ {
+ w -= x;
+ x = 0;
+ }
+
+ if(y < 0)
+ {
+ h -= y;
+ y = 0;
+ }
+
+ if (w != rw || w != rh)
+ glPixelZoom((GLfloat)w/rw, (GLfloat)h/rh);
+
+ glRasterPos2i(x, y);
+ glDrawPixels(rw, rh, GL_RGB, GL_UNSIGNED_BYTE, glImage);
+
+ (void)ih;
+ (void)ctxcanvas;
+
+ free(glImage);
+}
+
+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)
+{
+ /* Images are bitmaps, and cannot be directly rotated or scaled */
+ int blend = 1;
+ GLubyte* glImage;
+ int rw = xmax-xmin+1;
+ int rh = ymax-ymin+1;
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ glImage = cdglCreateImageRGBA(rw, rh, r, g, b, a, iw);
+ if (!glImage)
+ return;
+
+ /* adjusts when the initial position (x,y) are less than 0 */
+ if(x < 0)
+ {
+ w -= x;
+ x = 0;
+ }
+
+ if(y < 0)
+ {
+ h -= y;
+ y = 0;
+ }
+
+ if (w != rw || h != rh)
+ glPixelZoom((GLfloat)w/rw, (GLfloat)h/rh);
+
+ if (!glIsEnabled(GL_BLEND))
+ {
+ blend = 0;
+ glEnable(GL_BLEND);
+ }
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glRasterPos2i(x, y);
+ glDrawPixels(rw, rh, GL_RGBA, GL_UNSIGNED_BYTE, glImage);
+
+ if (!blend)
+ glDisable(GL_BLEND);
+
+ (void)ih;
+ (void)ctxcanvas;
+
+ free(glImage);
+}
+
+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)
+{
+ /* Images are bitmaps, and cannot be directly rotated or scaled */
+ GLubyte* glImage;
+ int rw = xmax-xmin+1;
+ int rh = ymax-ymin+1;
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ glImage = cdglCreateImageMap(rw, rh, colors, index, iw);
+ if (!glImage)
+ return;
+
+ /* adjusts when the initial position (x,y) are less than 0 */
+ if(x < 0)
+ {
+ w -= x;
+ x = 0;
+ }
+
+ if(y < 0)
+ {
+ h -= y;
+ y = 0;
+ }
+
+ if (w != rw || h != rh)
+ glPixelZoom((GLfloat)w/rw, (GLfloat)h/rh);
+
+ glRasterPos2i(x, y);
+ glDrawPixels(rw, rh, GL_RGB, GL_UNSIGNED_BYTE, glImage);
+
+ (void)ih;
+ (void)ctxcanvas;
+
+ free(glImage);
+}
+
+static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color)
+{
+ glColor4ub(cdRed(color), cdGreen(color), cdBlue(color), cdAlpha(color));
+
+ /* Draw pixel */
+ glPointSize(1);
+ glBegin(GL_POINTS);
+ glVertex2i(x, y);
+ glEnd();
+
+ /* restore the foreground color */
+ glColor4ub(cdRed(ctxcanvas->canvas->foreground), cdGreen(ctxcanvas->canvas->foreground), cdBlue(ctxcanvas->canvas->foreground), cdAlpha(ctxcanvas->canvas->foreground));
+
+ (void)ctxcanvas;
+}
+
+static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)
+{
+ cdCtxImage *ctximage = (cdCtxImage *)malloc(sizeof(cdCtxImage));
+
+ ctximage->w = w;
+ ctximage->h = h;
+ ctximage->depth = ctxcanvas->canvas->bpp;
+
+ ctximage->img = (GLubyte*)malloc(w*h*4); /* each pixel uses 4 bytes (RGBA) */
+
+ if (!ctximage->img)
+ {
+ free(ctximage);
+ return (void*)0;
+ }
+
+ return (void*)ctximage;
+}
+
+static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y)
+{
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ glReadPixels(x, y - ctximage->h+1, ctximage->w, ctximage->h, GL_RGBA, GL_UNSIGNED_BYTE, ctximage->img);
+
+ (void)ctxcanvas;
+}
+
+static void cdputimagerect (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y, int xmin, int xmax, int ymin, int ymax)
+{
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ glRasterPos2i(x, y);
+ glDrawPixels(xmax-xmin+1, ymax-ymin+1, GL_RGBA, GL_UNSIGNED_BYTE, ctximage->img);
+
+ (void)ctxcanvas;
+}
+
+static void cdkillimage (cdCtxImage *ctximage)
+{
+ free(ctximage->img);
+ free(ctximage);
+}
+
+static void cdscrollarea (cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax, int dx, int dy)
+{
+ glRasterPos2i(xmin+dx, ymin+dy);
+ glCopyPixels(xmin, ymin, xmax-xmin+1, ymax-ymin+1, GL_RGBA);
+
+ (void)ctxcanvas;
+}
+
+static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
+{
+ if (matrix)
+ {
+ GLdouble transformMTX[4][4];
+
+ transformMTX[0][0] = matrix[0]; transformMTX[0][1] = matrix[1]; transformMTX[0][2] = 0.0; transformMTX[0][3] = 0.0;
+ transformMTX[1][0] = matrix[2]; transformMTX[1][1] = matrix[3]; transformMTX[1][2] = 0.0; transformMTX[1][3] = 0.0;
+ transformMTX[2][0] = 0.0; transformMTX[2][1] = 0.0; transformMTX[2][2] = 1.0; transformMTX[2][3] = 0.0;
+ transformMTX[3][0] = matrix[4]; transformMTX[3][1] = matrix[5]; transformMTX[3][2] = 0.0; transformMTX[3][3] = 1.0;
+
+ glLoadIdentity();
+ glMultMatrixd(&transformMTX[0][0]);
+ }
+ else
+ glLoadIdentity();
+
+ (void)ctxcanvas;
+}
+
+/******************************************************************/
+static void set_alpha_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (!data || data[0] == '0')
+ {
+ glDisable(GL_BLEND);
+ }
+ else
+ {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ (void)ctxcanvas;
+}
+
+static char* get_alpha_attrib(cdCtxCanvas* ctxcanvas)
+{
+ (void)ctxcanvas;
+
+ if (glIsEnabled(GL_BLEND))
+ return "1";
+ else
+ return "0";
+}
+
+static cdAttribute alpha_attrib =
+{
+ "ALPHA",
+ set_alpha_attrib,
+ get_alpha_attrib
+};
+
+static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (!data || data[0] == '0')
+ {
+ glDisable(GL_POINT_SMOOTH);
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_POLYGON_SMOOTH);
+ }
+ else
+ {
+ glEnable(GL_POINT_SMOOTH);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_POLYGON_SMOOTH);
+
+ glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+ }
+
+ (void)ctxcanvas;
+}
+
+static char* get_aa_attrib(cdCtxCanvas* ctxcanvas)
+{
+ (void)ctxcanvas;
+
+ if (glIsEnabled(GL_LINE_SMOOTH))
+ return "1";
+ else
+ return "0";
+}
+
+static cdAttribute aa_attrib =
+{
+ "ANTIALIAS",
+ set_aa_attrib,
+ get_aa_attrib
+};
+
+static void set_poly_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ int hole;
+
+ if (data == NULL)
+ {
+ ctxcanvas->holes = 0;
+ return;
+ }
+
+ sscanf(data, "%d", &hole);
+ ctxcanvas->poly_holes[ctxcanvas->holes] = hole;
+ ctxcanvas->holes++;
+}
+
+static char* get_poly_attrib(cdCtxCanvas *ctxcanvas)
+{
+ static char holes[10];
+ sprintf(holes, "%d", ctxcanvas->holes);
+ return holes;
+}
+
+static cdAttribute poly_attrib =
+{
+ "POLYHOLE",
+ set_poly_attrib,
+ get_poly_attrib
+};
+
+static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (data)
+ {
+ sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
+ &ctxcanvas->rotate_center_x,
+ &ctxcanvas->rotate_center_y);
+
+ cdCanvasTransformTranslate(ctxcanvas->canvas, ctxcanvas->rotate_center_x, ctxcanvas->rotate_center_y);
+ cdCanvasTransformRotate(ctxcanvas->canvas, ctxcanvas->rotate_angle);
+ cdCanvasTransformTranslate(ctxcanvas->canvas, -ctxcanvas->rotate_center_x, -ctxcanvas->rotate_center_y);
+ }
+ else
+ {
+ ctxcanvas->rotate_angle = 0;
+ ctxcanvas->rotate_center_x = 0;
+ ctxcanvas->rotate_center_y = 0;
+
+ cdCanvasTransform(ctxcanvas->canvas, NULL);
+ }
+}
+
+static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
+{
+ static char data[100];
+
+ if (!ctxcanvas->rotate_angle)
+ return NULL;
+
+ sprintf(data, "%g %d %d", (double)ctxcanvas->rotate_angle,
+ ctxcanvas->rotate_center_x,
+ ctxcanvas->rotate_center_y);
+
+ return data;
+}
+
+static cdAttribute rotate_attrib =
+{
+ "ROTATE",
+ set_rotate_attrib,
+ get_rotate_attrib
+};
+
+static void set_size_attrib(cdCtxCanvas* ctxcanvas, char* data)
+{
+ if (data)
+ {
+ cdCanvas* canvas = ctxcanvas->canvas;
+ float res = (float)canvas->xres;
+ sscanf(data, "%dx%d %g", &canvas->w, &canvas->h, &res);
+ canvas->yres = canvas->xres = res;
+ canvas->w_mm = ((double)canvas->w) / canvas->xres;
+ canvas->h_mm = ((double)canvas->h) / canvas->yres;
+ }
+}
+
+static cdAttribute size_attrib =
+{
+ "SIZE",
+ set_size_attrib,
+ NULL
+};
+
+static char* get_version_attrib(cdCtxCanvas* ctxcanvas)
+{
+ (void)ctxcanvas;
+ return (char*)glGetString(GL_VERSION);
+}
+
+static cdAttribute version_attrib =
+{
+ "GLVERSION",
+ NULL,
+ get_version_attrib
+};
+
+static void cdcreatecanvas(cdCanvas* canvas, void *data)
+{
+ cdCtxCanvas* ctxcanvas;
+ int w = 0, h = 0;
+ float res = (float)3.78;
+ char* str_data = (char*)data;
+
+ sscanf(str_data, "%dx%d %g", &w, &h, &res);
+
+ if (w == 0 || h == 0)
+ return;
+
+ ctxcanvas = (cdCtxCanvas *)malloc(sizeof(cdCtxCanvas));
+ memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
+
+ canvas->xres = res;
+ canvas->yres = res;
+
+ canvas->w_mm = ((double)canvas->w) / canvas->xres;
+ canvas->h_mm = ((double)canvas->h) / canvas->yres;
+
+ ctxcanvas->canvas = canvas;
+ canvas->ctxcanvas = ctxcanvas;
+
+ ctxcanvas->glLastConvertUTF8 = NULL;
+
+ cdRegisterAttribute(canvas, &rotate_attrib);
+ cdRegisterAttribute(canvas, &version_attrib);
+ cdRegisterAttribute(canvas, &poly_attrib);
+ cdRegisterAttribute(canvas, &size_attrib);
+ cdRegisterAttribute(canvas, &alpha_attrib);
+ cdRegisterAttribute(canvas, &aa_attrib);
+
+ cdCanvasSetAttribute(canvas, "ALPHA", "1");
+ cdCanvasSetAttribute(canvas, "ANTIALIAS", "1");
+}
+
+static void cdinittable(cdCanvas* canvas)
+{
+ canvas->cxFlush = cdflush;
+ canvas->cxClear = cdclear;
+
+ canvas->cxPixel = cdpixel;
+ canvas->cxLine = cdline;
+ canvas->cxPoly = cdpoly;
+ canvas->cxRect = cdrect;
+ canvas->cxBox = cdbox;
+ canvas->cxArc = cdSimArc;
+ canvas->cxSector = cdSimSector;
+ canvas->cxChord = cdSimChord;
+
+ canvas->cxText = cdtext;
+ canvas->cxFont = cdfont;
+ canvas->cxGetFontDim = cdgetfontdim;
+ canvas->cxGetTextSize = cdgettextsize;
+
+ canvas->cxClip = cdclip;
+ canvas->cxClipArea = cdcliparea;
+ canvas->cxWriteMode = cdwritemode;
+ canvas->cxLineStyle = cdlinestyle;
+ canvas->cxLineWidth = cdlinewidth;
+ canvas->cxInteriorStyle = cdinteriorstyle;
+ canvas->cxHatch = cdhatch;
+ canvas->cxStipple = cdstipple;
+ canvas->cxPattern = cdpattern;
+ canvas->cxForeground = cdforeground;
+ canvas->cxTransform = cdtransform;
+
+ canvas->cxFLine = cdfline;
+ canvas->cxFPoly = cdfpoly;
+ canvas->cxFRect = cdfrect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfSimArc;
+ canvas->cxFSector = cdfSimSector;
+ canvas->cxFChord = cdfSimChord;
+ canvas->cxFText = cdftext;
+ canvas->cxFClipArea = cdfcliparea;
+
+ canvas->cxScrollArea = cdscrollarea;
+ canvas->cxCreateImage = cdcreateimage;
+ canvas->cxGetImage = cdgetimage;
+ canvas->cxPutImageRect = cdputimagerect;
+ canvas->cxKillImage = cdkillimage;
+
+ canvas->cxGetImageRGB = cdgetimagergb;
+ canvas->cxPutImageRectRGB = cdputimagerectrgb;
+ canvas->cxPutImageRectMap = cdputimagerectmap;
+ canvas->cxPutImageRectRGBA = cdputimagerectrgba;
+
+ canvas->cxKillCanvas = cdkillcanvas;
+}
+
+static cdContext cdGLContext =
+{
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_PALETTE | CD_CAP_LINEJOIN | CD_CAP_LINECAP |
+ CD_CAP_REGION | CD_CAP_STIPPLE | CD_CAP_PATTERN),
+ 0,
+ cdcreatecanvas,
+ cdinittable,
+ NULL,
+ NULL,
+};
+
+cdContext* cdContextGL(void)
+{
+ return &cdGLContext;
+}
diff --git a/cd/src/drv/cdirgb.c b/cd/src/drv/cdirgb.c
index 433a684..0c2913f 100755
--- a/cd/src/drv/cdirgb.c
+++ b/cd/src/drv/cdirgb.c
@@ -275,7 +275,7 @@ static void sCombineRGBALine(cdCtxCanvas* ctxcanvas, int offset, const unsigned
}
}
-static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax)
+static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax, long color)
{
int x;
unsigned long offset = y * canvas->w;
@@ -292,7 +292,7 @@ static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax)
xmax = (canvas->w-1);
for (x = xmin; x <= xmax; x++)
- sCombineRGBColor(canvas->ctxcanvas, offset + x, canvas->foreground);
+ sCombineRGBColor(canvas->ctxcanvas, offset + x, color);
}
static void irgbPatternLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const long *pattern)
@@ -506,7 +506,7 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
memcpy(t_poly, poly, sizeof(cdPoint)*n);
poly = t_poly;
- for(i = 0; i < n; i++)
+ for(i = 0; i < n; i++) /* must duplicate because clip poly is stored */
cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
}
@@ -568,79 +568,6 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
irgPostProcessIntersect(ctxcanvas->clip_region, ctxcanvas->canvas->w * ctxcanvas->canvas->h);
}
-static void irgbClipElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2, int sector)
-{
- float c, s, sx, sy, x, y, prev_x, prev_y;
- double da;
- int i, p;
- cdPoint* poly;
-
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(ctxcanvas->canvas, xc, yc, width, height);
-
- /* number of segments for the arc */
- n = cdRound((fabs(angle2-angle1)*n)/360);
- if (n < 1) n = 1;
-
- poly = (cdPoint*)malloc(sizeof(cdPoint)*(n+2+1)); /* n+1 points +1 center */
-
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
-
- /* generates arc points at origin with axis x and y */
-
- da = (angle2-angle1)/n;
- c = (float)cos(da);
- s = (float)sin(da);
- sx = -(width*s)/height;
- sy = (height*s)/width;
-
- x = xc + (width/2.0f)*(float)cos(angle1);
- y = yc + (height/2.0f)*(float)sin(angle1);
- poly[0].x = _cdRound(x);
- poly[0].y = _cdRound(y);
- prev_x = x;
- prev_y = y;
- p = 1;
-
- for (i = 1; i < n+1; i++) /* n+1 points */
- {
- x = xc + c*(prev_x-xc) + sx*(prev_y-yc);
- y = yc + sy*(prev_x-xc) + c*(prev_y-yc);
-
- poly[p].x = _cdRound(x);
- poly[p].y = _cdRound(y);
-
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
-
- prev_x = x;
- prev_y = y;
- }
-
- if (poly[p-1].x != poly[0].x || poly[p-1].y != poly[0].y)
- {
- if (sector) /* cdSector */
- {
- /* add center */
- poly[p].x = xc;
- poly[p].y = yc;
- }
- else /* cdChord */
- {
- /* add initial point */
- poly[p].x = poly[0].x;
- poly[p].y = poly[0].y;
- }
- p++;
- }
-
- irgbClipPoly(ctxcanvas, ctxcanvas->clip_region, poly, p, ctxcanvas->canvas->combine_mode);
-
- free(poly);
-}
-
static void irgbClipBox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
int combine_mode = ctxcanvas->canvas->combine_mode;
@@ -858,39 +785,31 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
{
if (ctxcanvas->canvas->new_region)
{
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipBox(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
- cdboxSIM(ctxcanvas, xmin, xmax, ymin, ymax);
-}
-
-static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 1);
- return;
- }
-
- cdsectorSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
}
-static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
+static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
if (ctxcanvas->canvas->new_region)
{
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 0);
+ /* matrix transformation is done inside irgbClip* if necessary */
+ irgbClipBox(ctxcanvas, _cdRound(xmin), _cdRound(xmax), _cdRound(ymin), _cdRound(ymax));
return;
}
- cdchordSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdfSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
}
static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
if (ctxcanvas->canvas->new_region)
{
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipPoly(ctxcanvas, ctxcanvas->clip_region, poly, n, ctxcanvas->canvas->combine_mode);
return;
}
@@ -898,11 +817,15 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
if (mode == CD_CLIP)
{
/* set directly to clip */
- memset(ctxcanvas->clip, 1, ctxcanvas->canvas->w * ctxcanvas->canvas->h); /* CD_CLIPOFF */
+
+ /* CD_CLIPOFF */
+ memset(ctxcanvas->clip, 1, ctxcanvas->canvas->w * ctxcanvas->canvas->h);
+
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipPoly(ctxcanvas, ctxcanvas->clip, poly, n, CD_UNION);
}
else
- cdpolySIM(ctxcanvas, mode, poly, n);
+ cdSimPoly(ctxcanvas, mode, poly, n);
}
static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)
@@ -952,20 +875,27 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *r, unsigned cha
}
}
+static void sFixImageY(int *topdown, int *y, int *h)
+{
+ if (*h < 0)
+ {
+ *h = -(*h);
+ *y -= (*h - 1); /* y is at top-left, move it to bottom-left */
+ *topdown = 1; /* image pointer will start at top-left */
+ }
+ else
+ *topdown = 0;
+}
+
static void cdputimagerectrgba_matrix(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 t_xmin, t_xmax, t_ymin, t_ymax,
- t_x, t_y, img_topdown = 0, dst_offset;
+ t_x, t_y, topdown, dst_offset;
float i_x, i_y, xfactor, yfactor;
unsigned char sr, sg, sb, sa = 255;
double inv_matrix[6];
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* calculate the destination limits */
cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, NULL);
@@ -984,7 +914,7 @@ static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, co
if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1)
{
- if (img_topdown) /* image is top-bottom */
+ if (topdown) /* image is top-bottom */
i_y = ih-1 - i_y;
if (t_x == 350 && t_y == 383)
@@ -1007,17 +937,12 @@ static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, co
static void cdputimagerectmap_matrix(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 t_xmin, t_xmax, t_ymin, t_ymax,
- t_x, t_y, img_topdown = 0, dst_offset;
+ t_x, t_y, topdown, dst_offset;
float i_x, i_y, xfactor, yfactor;
unsigned char si;
double inv_matrix[6];
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left (undocumented feature) */
- }
+ sFixImageY(&topdown, &y, &h);
/* calculate the destination limits */
cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, NULL);
@@ -1036,7 +961,7 @@ static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, con
if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1)
{
- if (img_topdown) /* image is top-bottom */
+ if (topdown) /* image is top-bottom */
i_y = ih-1 - i_y;
si = cdZeroOrderInterpolation(iw, ih, index, i_x, i_y);
@@ -1048,7 +973,7 @@ static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, con
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, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rh, rw, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rh, rw, topdown;
const unsigned char *src_red, *src_green, *src_blue;
if (ctxcanvas->canvas->use_matrix)
@@ -1057,12 +982,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1090,7 +1010,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1117,7 +1037,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1132,7 +1052,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
{
r -= iw;
g -= iw;
@@ -1150,7 +1070,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
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, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, topdown;
const unsigned char *src_red, *src_green, *src_blue, *src_alpha;
if (ctxcanvas->canvas->use_matrix)
@@ -1159,12 +1079,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1192,7 +1107,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1220,7 +1135,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1236,7 +1151,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
{
r -= iw;
g -= iw;
@@ -1256,7 +1171,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
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 l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, pal_size, idx, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, idx, topdown;
const unsigned char *src_index;
if (ctxcanvas->canvas->use_matrix)
@@ -1265,12 +1180,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1286,22 +1196,6 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
rw = xmax-xmin+1;
rh = ymax-ymin+1;
- /* Como nao sabemos o tamanho da palette a priori,
- teremos que ver qual o maior indice usado na imagem. */
- pal_size = 0;
-
- for (l=0; l<ih; l++)
- {
- for (c=0; c<iw; c++)
- {
- idx = index[l*iw + c];
- if (idx > pal_size)
- pal_size = idx;
- }
- }
-
- pal_size++;
-
/* testa se tem que fazer zoom */
if (rw != w || rh != h)
{
@@ -1314,7 +1208,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1340,7 +1234,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1357,7 +1251,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
index -= iw;
else
index += iw;
@@ -1696,6 +1590,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
if (data)
{
+ /* use this configuration when there is NO native tranformation support */
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
@@ -1859,15 +1754,23 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxClear = cdclear;
canvas->cxPixel = cdpixel;
- canvas->cxLine = cdlineSIM;
- canvas->cxRect = cdrectSIM;
+ canvas->cxLine = cdSimLine;
+ canvas->cxRect = cdSimRect;
canvas->cxBox = cdbox;
- canvas->cxArc = cdarcSIM;
- canvas->cxSector = cdsector;
- canvas->cxChord = cdchord;
+ canvas->cxArc = cdSimArc;
+ canvas->cxSector = cdSimSector;
+ canvas->cxChord = cdSimChord;
canvas->cxPoly = cdpoly;
canvas->cxText = NULL;
+ canvas->cxFLine = cdfSimLine;
+ canvas->cxFRect = cdfSimRect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfSimArc;
+ canvas->cxFSector = cdfSimSector;
+ canvas->cxFChord = cdfSimChord;
+ canvas->cxFPoly = cdfSimPoly;
+
canvas->cxKillCanvas = cdkillcanvas;
/* use simulation */
@@ -1885,9 +1788,9 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageRGBContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY |
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvas,
cdinittable,
@@ -2003,9 +1906,9 @@ static void cdinittableDB(cdCanvas* canvas)
static cdContext cdDBufferRGBContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_ALL & ~(CD_CAP_PLAY |
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvasDB,
cdinittableDB,
diff --git a/cd/src/drv/cdmf.c b/cd/src/drv/cdmf.c
index 727fcac..ddb109c 100755
--- a/cd/src/drv/cdmf.c
+++ b/cd/src/drv/cdmf.c
@@ -96,7 +96,8 @@ enum
CDMF_FCHORD, /* 72 */
CDMF_FCLIPAREA, /* 73 */
CDMF_FONT, /* 74 */
- CDMF_RESETMATRIX /* 75 */
+ CDMF_RESETMATRIX, /* 75 */
+ CDMF_PATHSET /* 76 */
};
struct _cdCtxCanvas
@@ -242,8 +243,49 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%d %d\n", CDMF_PATHSET, ctxcanvas->canvas->path[p]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%d\n", CDMF_END);
}
@@ -260,8 +302,49 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode);
- for(i = 0; i<n; i++)
- fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ fprintf(ctxcanvas->file, "%d %d\n", CDMF_PATHSET, ctxcanvas->canvas->path[p]);
+
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_MOVETO:
+ case CD_PATH_LINETO:
+ if (i+1 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_CURVETO:
+ case CD_PATH_ARC:
+ {
+ if (i+3 > n)
+ {
+ fprintf(ctxcanvas->file, "ERROR: not enough points in path\n");
+ return;
+ }
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i+1].x, poly[i+1].y);
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y);
+ }
fprintf(ctxcanvas->file, "%d\n", CDMF_END);
}
diff --git a/cd/src/drv/cdpdf.c b/cd/src/drv/cdpdf.c
index a5d91d4..3211cba 100755
--- a/cd/src/drv/cdpdf.c
+++ b/cd/src/drv/cdpdf.c
@@ -56,36 +56,6 @@ struct _cdCtxCanvas
/*
-%F Ajusta o tamanho do papel em points.
-*/
-static void setpdfpapersize(cdCtxCanvas* ctxcanvas, int size)
-{
- static struct
- {
- int width;
- int height;
- } paper[] =
- {
- { 2393, 3391 }, /* A0 */
- { 1689, 2393 }, /* A1 */
- { 1192, 1689 }, /* A2 */
- { 842, 1192 }, /* A3 */
- { 595, 842 }, /* A4 */
- { 420, 595 }, /* A5 */
- { 612, 792 }, /* LETTER */
- { 612, 1008 } /* LEGAL */
- };
-
- if (size<CD_A0 || size>CD_LEGAL)
- return;
-
- ctxcanvas->width_pt = paper[size].width;
- ctxcanvas->height_pt = paper[size].height;
- ctxcanvas->width_mm = ctxcanvas->width_pt/CD_MM2PT;
- ctxcanvas->height_mm = ctxcanvas->height_pt/CD_MM2PT;
-}
-
-/*
%F Registra os valores default para impressao.
*/
static void setpdfdefaultvalues(cdCtxCanvas* ctxcanvas)
@@ -93,7 +63,9 @@ static void setpdfdefaultvalues(cdCtxCanvas* ctxcanvas)
int i;
/* all the other values are set to 0 */
- setpdfpapersize(ctxcanvas, CD_A4);
+ cdSetPaperSize(CD_A4, &ctxcanvas->width_pt, &ctxcanvas->height_pt);
+ ctxcanvas->width_mm = ctxcanvas->width_pt/CD_MM2PT;
+ ctxcanvas->height_mm = ctxcanvas->height_pt/CD_MM2PT;
ctxcanvas->res = 300;
ctxcanvas->hatchboxsize = 8;
ctxcanvas->opacity = 255; /* full opaque */
@@ -139,18 +111,16 @@ static void begin_page(cdCtxCanvas *ctxcanvas)
static void init_pdf(cdCtxCanvas *ctxcanvas)
{
ctxcanvas->scale = 72.0/ctxcanvas->res;
+ ctxcanvas->canvas->xres = ctxcanvas->res/25.4;
+ ctxcanvas->canvas->yres = ctxcanvas->canvas->xres;
- /* Converte p/ unidades do usuario */
- ctxcanvas->canvas->w = (int)(ctxcanvas->width_pt/ctxcanvas->scale + 0.5);
- ctxcanvas->canvas->h = (int)(ctxcanvas->height_pt/ctxcanvas->scale + 0.5);
-
- /* Passa o valor em milimetros para o canvas CD */
ctxcanvas->canvas->w_mm = ctxcanvas->width_mm;
ctxcanvas->canvas->h_mm = ctxcanvas->height_mm;
+ ctxcanvas->canvas->w = cdRound(ctxcanvas->canvas->xres*ctxcanvas->canvas->w_mm);
+ ctxcanvas->canvas->h = cdRound(ctxcanvas->canvas->yres*ctxcanvas->canvas->h_mm);
+
ctxcanvas->canvas->bpp = 24;
- ctxcanvas->canvas->xres = ctxcanvas->canvas->w / ctxcanvas->canvas->w_mm;
- ctxcanvas->canvas->yres = ctxcanvas->canvas->h / ctxcanvas->canvas->h_mm;
begin_page(ctxcanvas);
}
@@ -166,7 +136,7 @@ static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
free(ctxcanvas);
}
-static void update_fill(cdCtxCanvas *ctxcanvas, int fill)
+static void sUpdateFill(cdCtxCanvas *ctxcanvas, int fill)
{
if (fill == 0)
{
@@ -311,7 +281,7 @@ static int cdclip(cdCtxCanvas *ctxcanvas, int mode)
static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
PDF_moveto(ctxcanvas->pdf, x1, y1);
PDF_lineto(ctxcanvas->pdf, x2, y2);
@@ -325,7 +295,7 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
PDF_rect(ctxcanvas->pdf, xmin, ymin, xmax-xmin, ymax-ymin);
PDF_stroke(ctxcanvas->pdf);
@@ -338,7 +308,7 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma
static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
PDF_moveto(ctxcanvas->pdf, xmin, ymin);
PDF_lineto(ctxcanvas->pdf, xmax, ymin);
@@ -354,14 +324,16 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
+
+ /* angles in degrees counterclockwise, same as CD */
if (w==h)
{
PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
PDF_stroke(ctxcanvas->pdf);
}
- else /* Elipse: mudar a escala p/ criar a partir do circulo */
+ else /* Ellipse: change the scale to create from the circle */
{
PDF_save(ctxcanvas->pdf); /* save to use the local transform */
@@ -383,12 +355,12 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h)
{
PDF_moveto(ctxcanvas->pdf, xc, yc);
- PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
PDF_fill(ctxcanvas->pdf);
}
else /* Elipse: mudar a escala p/ criar a partir do circulo */
@@ -401,15 +373,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
PDF_moveto(ctxcanvas->pdf, xc, yc);
PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
-
- if (ctxcanvas->canvas->interior_style == CD_SOLID ||
- ctxcanvas->canvas->interior_style == CD_PATTERN)
- PDF_fill(ctxcanvas->pdf);
- else
- {
- PDF_lineto(ctxcanvas->pdf, xc, yc);
- PDF_stroke(ctxcanvas->pdf);
- }
+ PDF_fill(ctxcanvas->pdf);
PDF_restore(ctxcanvas->pdf); /* restore from local */
}
@@ -422,12 +386,12 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h)
{
- PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
- PDF_fill_stroke(ctxcanvas->pdf);
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
+ PDF_fill(ctxcanvas->pdf);
}
else /* Elipse: mudar a escala p/ criar a partir do circulo */
{
@@ -435,10 +399,11 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
/* local transform */
PDF_translate(ctxcanvas->pdf, xc, yc);
- PDF_scale(ctxcanvas->pdf, 1, w/h);
+ PDF_scale(ctxcanvas->pdf, w/h, 1);
+ PDF_translate(ctxcanvas->pdf, -xc, -yc);
- PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
- PDF_fill_stroke(ctxcanvas->pdf);
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);
+ PDF_fill(ctxcanvas->pdf);
PDF_restore(ctxcanvas->pdf); /* restore from local */
}
@@ -487,8 +452,8 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, i
char temp[200], options[200];
PDF_setcolor(ctxcanvas->pdf, "fill", "rgb", get_red(ctxcanvas->canvas->foreground),
- get_green(ctxcanvas->canvas->foreground),
- get_blue(ctxcanvas->canvas->foreground), 0);
+ get_green(ctxcanvas->canvas->foreground),
+ get_blue(ctxcanvas->canvas->foreground), 0);
strcpy(options, "");
@@ -572,13 +537,121 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
if (mode == CD_CLIP)
return;
+ if (mode == CD_PATH)
+ {
+ int p, fill = 0;
+
+ /* if there is any current path, remove it */
+ /* Don't use PDF_endpath because here usually there will be no path scope */
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_FILL ||
+ ctxcanvas->canvas->path[p] == CD_PATH_FILLSTROKE)
+ {
+ fill = 1;
+ break;
+ }
+ }
+
+ /* must be set before starting path scope */
+ sUpdateFill(ctxcanvas, 0); /* set always */
+ if (fill)
+ {
+ PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
+ sUpdateFill(ctxcanvas, fill);
+ }
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ /* Don't use PDF_endpath because here usually there will be no path scope */
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ PDF_moveto(ctxcanvas->pdf, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ PDF_lineto(ctxcanvas->pdf, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPathF(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (w==h)
+ {
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ /* NOT SUPPORTED IN PATH SCOPE!!!!
+ PDF_save(ctxcanvas->pdf);
+
+ PDF_translate(ctxcanvas->pdf, xc, yc);
+ PDF_scale(ctxcanvas->pdf, w/h, 1);
+ PDF_translate(ctxcanvas->pdf, -xc, -yc); */
+ double s = h;
+ if (w > h)
+ s = w;
+
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*s, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*s, a1, a2);
+
+ /* PDF_restore(ctxcanvas->pdf); */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ PDF_curveto(ctxcanvas->pdf, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ PDF_closepath(ctxcanvas->pdf);
+ break;
+ case CD_PATH_FILL:
+ PDF_fill(ctxcanvas->pdf);
+ break;
+ case CD_PATH_STROKE:
+ PDF_stroke(ctxcanvas->pdf);
+ break;
+ case CD_PATH_FILLSTROKE:
+ PDF_fill_stroke(ctxcanvas->pdf);
+ break;
+ case CD_PATH_CLIP:
+ PDF_clip(ctxcanvas->pdf);
+ break;
+ }
+ }
+ return;
+ }
+
if (mode == CD_FILL)
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
else
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
if (mode==CD_FILL)
{
+ /* must be set before starting path scope */
if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
PDF_set_parameter(ctxcanvas->pdf, "fillrule", "evenodd");
else
@@ -634,13 +707,121 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
if (mode == CD_CLIP)
return;
+ if (mode == CD_PATH)
+ {
+ int p, fill = 0;
+
+ /* if there is any current path, remove it */
+ /* Don't use PDF_endpath because here usually there will be no path scope */
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_FILL ||
+ ctxcanvas->canvas->path[p] == CD_PATH_FILLSTROKE)
+ {
+ fill = 1;
+ break;
+ }
+ }
+
+ /* must be set before starting path scope */
+ sUpdateFill(ctxcanvas, 0); /* set always */
+ if (fill)
+ {
+ PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
+ sUpdateFill(ctxcanvas, fill);
+ }
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ /* Don't use PDF_endpath because here usually there will be no path scope */
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ PDF_moveto(ctxcanvas->pdf, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ PDF_lineto(ctxcanvas->pdf, poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+
+ if (i+3 > n) return;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (w==h)
+ {
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2);
+ }
+ else /* Ellipse: change the scale to create from the circle */
+ {
+ /* NOT SUPPORTED IN PATH SCOPE!!!!
+ PDF_save(ctxcanvas->pdf);
+
+ PDF_translate(ctxcanvas->pdf, xc, yc);
+ PDF_scale(ctxcanvas->pdf, w/h, 1);
+ PDF_translate(ctxcanvas->pdf, -xc, -yc); */
+ double s = h;
+ if (w > h)
+ s = w;
+
+ if ((a2-a1)<0)
+ PDF_arcn(ctxcanvas->pdf, xc, yc, 0.5*s, a1, a2);
+ else
+ PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*s, a1, a2);
+
+ /* PDF_restore(ctxcanvas->pdf); */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ PDF_curveto(ctxcanvas->pdf, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ PDF_closepath(ctxcanvas->pdf);
+ break;
+ case CD_PATH_FILL:
+ PDF_fill(ctxcanvas->pdf);
+ break;
+ case CD_PATH_STROKE:
+ PDF_stroke(ctxcanvas->pdf);
+ break;
+ case CD_PATH_FILLSTROKE:
+ PDF_fill_stroke(ctxcanvas->pdf);
+ break;
+ case CD_PATH_CLIP:
+ PDF_clip(ctxcanvas->pdf);
+ break;
+ }
+ }
+ return;
+ }
+
if (mode == CD_FILL)
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
else
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
if (mode==CD_FILL)
{
+ /* must be set before starting path scope */
if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
PDF_set_parameter(ctxcanvas->pdf, "fillrule", "evenodd");
else
@@ -695,8 +876,8 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
{
- double mm = (72.0/25.4) / ctxcanvas->scale;
- char options[80];
+ double mm = ctxcanvas->canvas->xres;
+ char options[200];
switch (style)
{
@@ -720,12 +901,12 @@ static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
case CD_CUSTOM :
{
int i;
-
+ /* size here is in pixels, do not use mm */
strcpy(options, "dasharray={");
for (i = 0; i < ctxcanvas->canvas->line_dashes_count; i++)
{
char tmp[80];
- sprintf(tmp, "%g ", ctxcanvas->canvas->line_dashes[i]*mm);
+ sprintf(tmp, "%g ", (double)ctxcanvas->canvas->line_dashes[i]);
strcat(options, tmp);
}
strcat(options, "}");
@@ -768,7 +949,6 @@ static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (
PDF_suspend_page(ctxcanvas->pdf, "");
ctxcanvas->pattern = PDF_begin_pattern(ctxcanvas->pdf, n, m,
((double)n)*ctxcanvas->scale, ((double)m)*ctxcanvas->scale, 1);
-
PDF_scale(ctxcanvas->pdf, ctxcanvas->scale, ctxcanvas->scale);
for (j=0; j<m; j++)
@@ -802,21 +982,18 @@ static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *patt
static int uchar2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b)
{
- int ret = 1;
unsigned char* uchar_data = (unsigned char*)data;
if (uchar_data[j*n+i])
- {
cdDecodeColor(ctxcanvas->canvas->foreground, r, g, b);
- ret = 1;
- }
else
{
- cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
if (ctxcanvas->canvas->back_opacity==CD_TRANSPARENT)
- ret = -1;
+ return -1;
+ else
+ cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
}
- return ret;
+ return 1;
}
static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple)
@@ -824,14 +1001,14 @@ static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char
make_pattern(ctxcanvas, n, m, (void*)stipple, uchar2rgb);
}
-static void make_hatch(cdCtxCanvas *ctxcanvas, int style)
+static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
{
unsigned char r, g, b;
int hsize = ctxcanvas->hatchboxsize - 1;
int hhalf = hsize / 2;
PDF_suspend_page(ctxcanvas->pdf, "");
- ctxcanvas->pattern = PDF_begin_pattern(ctxcanvas->pdf, hsize + 1, hsize + 1,
+ ctxcanvas->pattern = PDF_begin_pattern(ctxcanvas->pdf, hsize, hsize,
((double)hsize)*ctxcanvas->scale, ((double)hsize)*ctxcanvas->scale, 1);
PDF_scale(ctxcanvas->pdf, ctxcanvas->scale, ctxcanvas->scale);
@@ -883,11 +1060,6 @@ static void make_hatch(cdCtxCanvas *ctxcanvas, int style)
PDF_end_pattern(ctxcanvas->pdf);
PDF_resume_page(ctxcanvas->pdf, "");
-}
-
-static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
-{
- make_hatch(ctxcanvas, style);
return style;
}
@@ -976,6 +1148,7 @@ static int cdfont(cdCtxCanvas *ctxcanvas, const char *type_face, int style, int
static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
{
+ /* reset to identity */
PDF_setmatrix(ctxcanvas->pdf, 1, 0, 0, 1, 0, 0);
/* default coordinate system is in points, change it to pixels. */
@@ -1000,7 +1173,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
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 i, j, d, image, rw, rh, rgb_size;
+ int i, j, d, image, rw, rh, rgb_size, pos;
char options[80];
unsigned char* rgb_data;
@@ -1017,9 +1190,10 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
for (i=ymax; i>=ymin; i--)
for (j=xmin; j<=xmax; j++)
{
- rgb_data[d] = r[i*iw+j]; d++;
- rgb_data[d] = g[i*iw+j]; d++;
- rgb_data[d] = b[i*iw+j]; d++;
+ pos = i*iw+j;
+ rgb_data[d] = r[pos]; d++;
+ rgb_data[d] = g[pos]; d++;
+ rgb_data[d] = b[pos]; d++;
}
PDF_create_pvf(ctxcanvas->pdf, "cd_raw_rgb", 0, rgb_data, rgb_size, "");
@@ -1036,7 +1210,7 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
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 i, j, d, image, image_mask, rw, rh, alpha_size, rgb_size;
+ int i, j, d, image, image_mask, rw, rh, alpha_size, rgb_size, pos;
char options[80];
unsigned char *rgb_data, *alpha_data;
@@ -1053,9 +1227,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
for (i=ymax; i>=ymin; i--)
for (j=xmin; j<=xmax; j++)
{
- rgb_data[d] = r[i*iw+j]; d++;
- rgb_data[d] = g[i*iw+j]; d++;
- rgb_data[d] = b[i*iw+j]; d++;
+ pos = i*iw+j;
+ rgb_data[d] = r[pos]; d++;
+ rgb_data[d] = g[pos]; d++;
+ rgb_data[d] = b[pos]; d++;
}
alpha_size = rw*rh;
@@ -1066,7 +1241,8 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
for (i=ymax; i>=ymin; i--)
for (j=xmin; j<=xmax; j++)
{
- alpha_data[d] = a[i*iw+j]; d++;
+ pos = i*iw+j;
+ alpha_data[d] = a[pos]; d++;
}
PDF_create_pvf(ctxcanvas->pdf, "cd_raw_rgb", 0, rgb_data, rgb_size, "");
@@ -1089,9 +1265,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
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 i, j, d, rw, rh, image, rgb_size;
+ int i, j, d, rw, rh, image, rgb_size, pos;
char options[80];
unsigned char* rgb_data;
+ unsigned char r, g, b;
if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;
@@ -1106,8 +1283,8 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
for (i=ymax; i>=ymin; i--)
for (j=xmin; j<=xmax; j++)
{
- unsigned char r, g, b;
- cdDecodeColor(colors[index[i*iw+j]], &r, &g, &b);
+ pos = i*iw+j;
+ cdDecodeColor(colors[index[pos]], &r, &g, &b);
rgb_data[d] = r; d++;
rgb_data[d] = g; d++;
rgb_data[d] = b; d++;
@@ -1202,7 +1379,8 @@ static cdAttribute hatchboxsize_attrib =
static void set_rotate_attrib(cdCtxCanvas *ctxcanvas, char* data)
{
- /* ignore ROTATE if transform is set */
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
if (ctxcanvas->canvas->use_matrix)
return;
@@ -1219,15 +1397,7 @@ static void set_rotate_attrib(cdCtxCanvas *ctxcanvas, char* data)
ctxcanvas->rotate_center_y = 0;
}
- PDF_setmatrix(ctxcanvas->pdf, 1, 0, 0, 1, 0, 0);
-
- if (ctxcanvas->rotate_angle)
- {
- /* rotation = translate to point + rotation + translate back */
- PDF_translate(ctxcanvas->pdf, ctxcanvas->rotate_center_x, ctxcanvas->rotate_center_y);
- PDF_rotate(ctxcanvas->pdf, (double)ctxcanvas->rotate_angle);
- PDF_translate(ctxcanvas->pdf, -ctxcanvas->rotate_center_x, -ctxcanvas->rotate_center_y);
- }
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas *ctxcanvas)
@@ -1469,7 +1639,9 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
{
int paper;
sscanf(line, "%d", &paper);
- setpdfpapersize(ctxcanvas, paper);
+ cdSetPaperSize(paper, &ctxcanvas->width_pt, &ctxcanvas->height_pt);
+ ctxcanvas->width_mm = ctxcanvas->width_pt/CD_MM2PT;
+ ctxcanvas->height_mm = ctxcanvas->height_pt/CD_MM2PT;
break;
}
case 'w':
@@ -1501,7 +1673,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
/* update canvas context */
canvas->ctxcanvas = ctxcanvas;
- if (ctxcanvas->landscape == 1)
+ if (ctxcanvas->landscape)
{
_cdSwapDouble(ctxcanvas->width_pt, ctxcanvas->height_pt);
_cdSwapDouble(ctxcanvas->width_mm, ctxcanvas->height_mm);
@@ -1513,7 +1685,9 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
static void cdinittable(cdCanvas* canvas)
{
canvas->cxFlush = cdflush;
+
canvas->cxPixel = cdpixel;
+
canvas->cxLine = cdline;
canvas->cxPoly = cdpoly;
canvas->cxRect = cdrect;
@@ -1522,6 +1696,7 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxSector = cdsector;
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+
canvas->cxFLine = cdfline;
canvas->cxFPoly = cdfpoly;
canvas->cxFRect = cdfrect;
@@ -1530,6 +1705,7 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFSector = cdfsector;
canvas->cxFChord = cdfchord;
canvas->cxFText = cdftext;
+
canvas->cxGetFontDim = cdgetfontdim;
canvas->cxGetTextSize = cdgettextsize;
canvas->cxPutImageRectRGB = cdputimagerectrgb;
@@ -1556,8 +1732,7 @@ static cdContext cdPDFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PALETTE |
CD_CAP_REGION | CD_CAP_IMAGESRV | CD_CAP_TEXTSIZE |
- CD_CAP_BACKGROUND | CD_CAP_BACKOPACITY | CD_CAP_WRITEMODE |
- CD_CAP_GETIMAGERGB),
+ CD_CAP_WRITEMODE | CD_CAP_GETIMAGERGB),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/drv/cdpicture.c b/cd/src/drv/cdpicture.c
index a5533b2..8cd586e 100755
--- a/cd/src/drv/cdpicture.c
+++ b/cd/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;
@@ -486,7 +508,7 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width);
picUpdateBBox(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width);
}
@@ -503,7 +525,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, ctxcanvas->canvas->line_width);
picUpdateBBox(ctxcanvas, xmax, ymax, ctxcanvas->canvas->line_width);
}
@@ -520,7 +542,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
picUpdateBBox(ctxcanvas, xc, yc, 0);
@@ -538,7 +560,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
picUpdateBBox(ctxcanvas, _cdRound(xc), _cdRound(yc), 0);
@@ -556,7 +578,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
prim->param.arcsectorchord.angle1 = a1;
prim->param.arcsectorchord.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
}
@@ -573,7 +595,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
prim->param.arcsectorchordf.angle1 = a1;
prim->param.arcsectorchordf.angle2 = a2;
picAddPrim(ctxcanvas, prim);
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
picUpdateBBox(ctxcanvas, xmin, ymin, 0);
picUpdateBBox(ctxcanvas, xmax, ymax, 0);
}
@@ -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,19 +711,75 @@ 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;
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(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 +977,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 +1083,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;
@@ -1043,6 +1243,72 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void
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; 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, 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; 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, 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;
diff --git a/cd/src/drv/cdps.c b/cd/src/drv/cdps.c
index ef77c4d..08d6ba7 100755
--- a/cd/src/drv/cdps.c
+++ b/cd/src/drv/cdps.c
@@ -49,11 +49,11 @@ struct _cdCtxCanvas
{
cdCanvas* canvas;
- FILE *file; /* Arquivo PS */
+ FILE *file; /* Arquivo PS */
int res; /* Resolucao */
int pages; /* Numero total de paginas */
- double width; /* Largura do papel (points) */
- double height; /* Altura do papel (points) */
+ double width_pt; /* Largura do papel (points) */
+ double height_pt; /* Altura do papel (points) */
double xmin, ymin; /* Definem as margens esquerda e inferior (points) */
double xmax, ymax; /* Definem as margens direita e superior (points) */
double bbxmin, bbymin; /* Definem a bounding box */
@@ -64,6 +64,7 @@ struct _cdCtxCanvas
int level1; /* if true generates level 1 only function calls */
int landscape; /* page orientation */
int debug; /* print debug strings in the file */
+
float rotate_angle;
int rotate_center_x,
rotate_center_y;
@@ -73,45 +74,16 @@ struct _cdCtxCanvas
int poly_holes[500];
int holes;
-
};
-
-/*
-%F Ajusta o tamanho do papel em points.
-*/
-static void setpspapersize(cdCtxCanvas *ctxcanvas, int size)
-{
- static struct
- {
- int width;
- int height;
- } paper[] =
- {
- { 2393, 3391 }, /* A0 */
- { 1689, 2393 }, /* A1 */
- { 1192, 1689 }, /* A2 */
- { 842, 1192 }, /* A3 */
- { 595, 842 }, /* A4 */
- { 420, 595 }, /* A5 */
- { 612, 792 }, /* LETTER */
- { 612, 1008 } /* LEGAL */
- };
-
- if (size<CD_A0 || size>CD_LEGAL)
- return;
-
- ctxcanvas->width = (double)paper[size].width;
- ctxcanvas->height = (double)paper[size].height;
-}
-
/*
%F Registra os valores default para impressao.
*/
static void setpsdefaultvalues(cdCtxCanvas *ctxcanvas)
{
/* all the other values are set to 0 */
- setpspapersize(ctxcanvas, CD_A4);
+ cdSetPaperSize(CD_A4, &ctxcanvas->width_pt, &ctxcanvas->height_pt);
+
ctxcanvas->xmin = 25.4; /* ainda em mm, sera' convertido para points na init_ps */
ctxcanvas->xmax = 25.4;
ctxcanvas->ymin = 25.4;
@@ -278,8 +250,10 @@ static void set_default_matrix(cdCtxCanvas *ctxcanvas)
fprintf(ctxcanvas->file, "setmatrix\n");
}
- /* margin and scale */
+ /* margin */
fprintf(ctxcanvas->file, "%g %g translate\n", ctxcanvas->xmin, ctxcanvas->ymin);
+
+ /* default coordinate system is in points, change it to pixels. */
fprintf(ctxcanvas->file, "%g %g scale\n", ctxcanvas->scale, ctxcanvas->scale);
}
@@ -288,15 +262,15 @@ static void set_default_matrix(cdCtxCanvas *ctxcanvas)
*/
static void init_ps(cdCtxCanvas *ctxcanvas)
{
- double w, h;
+ double w_pt, h_pt;
time_t now = time(NULL);
- ctxcanvas->scale = 72.0/ctxcanvas->res;
+ /* convert margin values to actual limits */
ctxcanvas->xmin = mm2pt(ctxcanvas->xmin);
- ctxcanvas->xmax = ctxcanvas->width - mm2pt(ctxcanvas->xmax);
+ ctxcanvas->xmax = ctxcanvas->width_pt - mm2pt(ctxcanvas->xmax);
ctxcanvas->ymin = mm2pt(ctxcanvas->ymin);
- ctxcanvas->ymax = ctxcanvas->height - mm2pt(ctxcanvas->ymax);
+ ctxcanvas->ymax = ctxcanvas->height_pt - mm2pt(ctxcanvas->ymax);
ctxcanvas->bbmargin = mm2pt(ctxcanvas->bbmargin);
fprintf(ctxcanvas->file, "%%!PS-Adobe-3.0 %s\n", ctxcanvas->eps ? "EPSF-3.0":"");
@@ -338,9 +312,10 @@ static void init_ps(cdCtxCanvas *ctxcanvas)
if (!ctxcanvas->eps && !ctxcanvas->level1)
{
+ /* setpagedevice not allowed in EPS */
fprintf(ctxcanvas->file, "%%%%IncludeFeature: *Resolution %d\n", ctxcanvas->res);
fprintf(ctxcanvas->file, "%%%%BeginFeature: *PageSize\n");
- fprintf(ctxcanvas->file, "<< /PageSize [%g %g] >> setpagedevice\n", ctxcanvas->width, ctxcanvas->height); /* setpagedevice not allowed in EPS */
+ fprintf(ctxcanvas->file, "<< /PageSize [%g %g] >> setpagedevice\n", ctxcanvas->width_pt, ctxcanvas->height_pt);
fprintf(ctxcanvas->file, "%%%%EndFeature\n");
}
@@ -350,16 +325,20 @@ static void init_ps(cdCtxCanvas *ctxcanvas)
fputs(change_font, ctxcanvas->file);
fputs(re_encode, ctxcanvas->file);
- w = ctxcanvas->xmax - ctxcanvas->xmin;
- h = ctxcanvas->ymax - ctxcanvas->ymin;
+ ctxcanvas->scale = 72.0/ctxcanvas->res;
+ ctxcanvas->canvas->xres = ctxcanvas->res/25.4;
+ ctxcanvas->canvas->yres = ctxcanvas->canvas->xres;
+
+ w_pt = ctxcanvas->xmax - ctxcanvas->xmin;
+ h_pt = ctxcanvas->ymax - ctxcanvas->ymin;
+
+ ctxcanvas->canvas->w_mm = w_pt/CD_MM2PT; /* Converte p/ milimetros */
+ ctxcanvas->canvas->h_mm = h_pt/CD_MM2PT; /* Converte p/ milimetros */
+
+ ctxcanvas->canvas->w = cdRound(ctxcanvas->canvas->xres*ctxcanvas->canvas->w_mm);
+ ctxcanvas->canvas->h = cdRound(ctxcanvas->canvas->yres*ctxcanvas->canvas->h_mm);
- ctxcanvas->canvas->w = (int)(w/ctxcanvas->scale + 0.5); /* Converte p/ unidades do usuario */
- ctxcanvas->canvas->h = (int)(h/ctxcanvas->scale + 0.5); /* Converte p/ unidades do usuario */
- ctxcanvas->canvas->w_mm = w/CD_MM2PT; /* Converte p/ milimetros */
- ctxcanvas->canvas->h_mm = h/CD_MM2PT; /* Converte p/ milimetros */
ctxcanvas->canvas->bpp = 24;
- ctxcanvas->canvas->xres = ctxcanvas->canvas->w / ctxcanvas->canvas->w_mm;
- ctxcanvas->canvas->yres = ctxcanvas->canvas->h / ctxcanvas->canvas->h_mm;
fprintf(ctxcanvas->file, "%%%%Page: 1 1\n");
ctxcanvas->pages = 1;
@@ -425,7 +404,7 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style);
static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple);
static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *pattern);
-static void update_fill(cdCtxCanvas *ctxcanvas, int fill)
+static void sUpdateFill(cdCtxCanvas *ctxcanvas, int fill)
{
if (fill == 0)
{
@@ -533,7 +512,7 @@ static int cdclip(cdCtxCanvas *ctxcanvas, int mode)
static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
fprintf(ctxcanvas->file, "N %d %d %d %d LL\n", x1, y1, x2, y2);
@@ -546,7 +525,7 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
fprintf(ctxcanvas->file, "N %g %g %g %g LL\n", x1, y1, x2, y2);
@@ -559,7 +538,7 @@ static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, dou
static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
if (ctxcanvas->level1)
{
@@ -582,7 +561,7 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma
static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
if (ctxcanvas->level1)
{
@@ -605,7 +584,7 @@ static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymi
static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->level1)
{
@@ -628,7 +607,7 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->level1)
{
@@ -651,7 +630,9 @@ static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin
static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
+
+ /* angles in degrees counterclockwise, same as CD */
if (w==h) /* Circulo: PS implementa direto */
{
@@ -675,7 +656,7 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -683,7 +664,7 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
if (w==h) /* Circulo: PS implementa direto */
{
@@ -707,7 +688,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -715,7 +696,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl
static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h) /* Circulo: PS implementa direto */
{
@@ -747,7 +728,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
bbox(ctxcanvas, xc, yc);
@@ -756,7 +737,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h) /* Circulo: PS implementa direto */
{
@@ -788,7 +769,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
fbbox(ctxcanvas, xc, yc);
@@ -797,7 +778,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do
static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h) /* Circulo: PS implementa direto */
{
@@ -827,7 +808,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(xc, yc, w, h, a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -835,7 +816,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
if (w==h) /* Circulo: PS implementa direto */
{
@@ -865,7 +846,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou
if (ctxcanvas->eps)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetEllipseBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasGetArcBox(_cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), a1, a2, &xmin, &xmax, &ymin, &ymax);
bbox(ctxcanvas, xmin, ymin);
bbox(ctxcanvas, xmax, ymax);
}
@@ -878,7 +859,7 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
int i;
int ascent, height, baseline;
- update_fill(ctxcanvas, 0);
+ sUpdateFill(ctxcanvas, 0);
cdCanvasGetFontDim(ctxcanvas->canvas, NULL, &height, &ascent, NULL);
baseline = height - ascent;
@@ -989,30 +970,242 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
if (ctxcanvas->debug) fprintf(ctxcanvas->file, "%%cdTextEnd\n");
}
+static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, int len)
+{
+ int i;
+ int ascent, height, baseline;
+
+ sUpdateFill(ctxcanvas, 0);
+
+ cdCanvasGetFontDim(ctxcanvas->canvas, NULL, &height, &ascent, NULL);
+ baseline = height - ascent;
+
+ if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdText Begin\n");
+
+ if (ctxcanvas->canvas->use_matrix || ctxcanvas->rotate_angle)
+ set_default_matrix(ctxcanvas);
+
+ fprintf(ctxcanvas->file, "N 0 0 M\n");
+ putc('(', ctxcanvas->file);
+
+ for (i=0; i<len; i++)
+ {
+ if (s[i]=='(' || s[i]==')')
+ putc('\\', ctxcanvas->file);
+ putc(s[i], ctxcanvas->file);
+ }
+
+ fprintf(ctxcanvas->file, ")\n");
+ fprintf(ctxcanvas->file, "dup true charpath\n");
+ fprintf(ctxcanvas->file, "flattenpath\n");
+ fprintf(ctxcanvas->file, "pathbbox\n"); /* bbox na pilha: llx lly urx ury */
+ fprintf(ctxcanvas->file, "exch\n"); /* troca o topo: llx lly ury urx */
+ fprintf(ctxcanvas->file, "4 1 roll\n"); /* roda: urx llx lly ury */
+ fprintf(ctxcanvas->file, "exch\n"); /* troca o topo: urx llx ury lly */
+ fprintf(ctxcanvas->file, "sub\n"); /* subtrai: urx llx h */
+ fprintf(ctxcanvas->file, "3 1 roll\n"); /* roda: h urx llx */
+ fprintf(ctxcanvas->file, "sub\n"); /* subtrai: h w */
+ fprintf(ctxcanvas->file, "0 0\n"); /* empilha: h w 0 0 */
+ fprintf(ctxcanvas->file, "4 -1 roll\n"); /* roda: w 0 0 h */
+
+ if (ctxcanvas->canvas->use_matrix || ctxcanvas->rotate_angle)
+ cdtransform(ctxcanvas, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL);
+
+ fprintf(ctxcanvas->file, "gsave\n"); /* save to use local transform */
+ fprintf(ctxcanvas->file, "%g %g translate\n", x, y);
+
+ if (ctxcanvas->canvas->text_orientation != 0)
+ fprintf(ctxcanvas->file, "%g rotate\n", ctxcanvas->canvas->text_orientation);
+
+ switch (ctxcanvas->canvas->text_alignment) /* Operacao em Y. topo da pilha: w x y h */
+ {
+ case CD_NORTH:
+ case CD_NORTH_EAST:
+ case CD_NORTH_WEST:
+ fprintf(ctxcanvas->file, "%d sub sub\n", baseline); /* empilha, subtrai, subtrai: w x y-(h-baseline) */
+ break;
+ case CD_EAST:
+ case CD_WEST:
+ case CD_CENTER:
+ fprintf(ctxcanvas->file, "2 div %d sub sub\n", baseline); /* empilha, divide, empilha, subtrai, subtrai: w x y-(h/2-baseline) */
+ break;
+ case CD_SOUTH_EAST:
+ case CD_SOUTH:
+ case CD_SOUTH_WEST:
+ fprintf(ctxcanvas->file, "pop %d add\n", baseline); /* desempilha, empilha, adiciona: w x y+baseline */
+ break;
+ case CD_BASE_RIGHT:
+ case CD_BASE_CENTER:
+ case CD_BASE_LEFT:
+ fprintf(ctxcanvas->file, "pop\n"); /* desempilha h: w x y */
+ break;
+ }
+
+ fprintf(ctxcanvas->file, "3 1 roll\n"); /* roda: y' w x */
+ fprintf(ctxcanvas->file, "exch\n"); /* inverte: y' x w */
+
+ switch (ctxcanvas->canvas->text_alignment) /* Operacao em X, topo da pilha: x w */
+ {
+ case CD_NORTH:
+ case CD_SOUTH:
+ case CD_CENTER:
+ case CD_BASE_CENTER:
+ fprintf(ctxcanvas->file, "2 div sub\n"); /* empilha, divide, subtrai: y' x-w/2 */
+ break;
+ case CD_NORTH_EAST:
+ case CD_EAST:
+ case CD_SOUTH_EAST:
+ case CD_BASE_RIGHT:
+ fprintf(ctxcanvas->file, "sub\n"); /* subtrai: y' x-w */
+ break;
+ case CD_SOUTH_WEST:
+ case CD_WEST:
+ case CD_NORTH_WEST:
+ case CD_BASE_LEFT:
+ fprintf(ctxcanvas->file, "pop\n"); /* desempilha: y' x */
+ break;
+ }
+
+ fprintf(ctxcanvas->file, "exch\n"); /* inverte: x' y' */
+ fprintf(ctxcanvas->file, "M\n"); /* moveto */
+
+ fprintf(ctxcanvas->file, "show\n");
+
+ if (ctxcanvas->eps)
+ {
+ int xmin, xmax, ymin, ymax;
+ s = cdStrDupN(s, len);
+ cdCanvasGetTextBox(ctxcanvas->canvas, (int)x, (int)y, s, &xmin, &xmax, &ymin, &ymax);
+ free((char*)s);
+ fbbox(ctxcanvas, (double)xmin, (double)ymin);
+ fbbox(ctxcanvas, (double)xmax, (double)ymax);
+ }
+
+ fprintf(ctxcanvas->file, "grestore\n");
+
+ if (ctxcanvas->debug) fprintf(ctxcanvas->file, "%%cdTextEnd\n");
+}
+
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
int i;
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ /* if there is any current path, remove it */
+ fprintf(ctxcanvas->file, "newpath\n");
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ fprintf(ctxcanvas->file, "newpath\n");
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "%d %d M\n", poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "%d %d L\n", poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+ char* arc = "arc";
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if ((a2-a1)<0)
+ arc = "arcn";
+
+ if (w==h) /* Circulo: PS implementa direto */
+ {
+ fprintf(ctxcanvas->file, "%d %d %g %g %g %s\n", xc, yc, 0.5*w, a1, a2, arc);
+ }
+ else /* Elipse: mudar a escala p/ criar a partir do circulo */
+ {
+ fprintf(ctxcanvas->file, "[0 0 0 0 0 0] currentmatrix\n"); /* fill new matrix from CTM */
+ fprintf(ctxcanvas->file, "%d %d translate\n", xc, yc);
+ fprintf(ctxcanvas->file, "1 %g scale\n", ((double)h)/w);
+ fprintf(ctxcanvas->file, "0 0 %g %g %g %s\n", 0.5*w, a1, a2, arc);
+ fprintf(ctxcanvas->file, "setmatrix\n"); /* back to CTM */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "%d %d %d %d %d %d B\n", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "closepath\n");
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "eofill\n");
+ else
+ fprintf(ctxcanvas->file, "fill\n");
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ fprintf(ctxcanvas->file, "stroke\n");
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ fprintf(ctxcanvas->file, "gsave\n");
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "eofill\n");
+ else
+ fprintf(ctxcanvas->file, "fill\n");
+ fprintf(ctxcanvas->file, "grestore\n");
+ sUpdateFill(ctxcanvas, 0);
+ fprintf(ctxcanvas->file, "stroke\n");
+ break;
+ case CD_PATH_CLIP:
+ if (ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "closepath eoclip\n");
+ else
+ fprintf(ctxcanvas->file, "closepath clip\n");
+ break;
+ }
+ }
+ return;
+ }
+
if (mode == CD_CLIP)
{
if (ctxcanvas->eps) /* initclip not allowed in EPS */
return;
- if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdPoly %d Begin\n", mode);
-
fprintf(ctxcanvas->file, "/clip_polygon {\n");
fprintf(ctxcanvas->file, "initclip\n");
}
else
{
if (mode == CD_FILL)
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
else
- update_fill(ctxcanvas, 0);
-
- if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdPoly %d Begin\n", mode);
+ sUpdateFill(ctxcanvas, 0);
}
+ if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdPoly %d Begin\n", mode);
+
fprintf(ctxcanvas->file, "N\n");
fprintf(ctxcanvas->file, "%d %d M\n", poly[0].x, poly[0].y);
@@ -1090,26 +1283,121 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
int i, hole_index = 0;
+ if (mode == CD_PATH)
+ {
+ int p;
+
+ /* if there is any current path, remove it */
+ fprintf(ctxcanvas->file, "newpath\n");
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ fprintf(ctxcanvas->file, "newpath\n");
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "%g %g M\n", poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "%g %g L\n", poly[i].x, poly[i].y);
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+ char* arc = "arc";
+
+ if (i+3 > n) return;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if ((a2-a1)<0)
+ arc = "arcn";
+
+ if (w==h) /* Circulo: PS implementa direto */
+ {
+ fprintf(ctxcanvas->file, "%g %g %g %g %g %s\n", xc, yc, 0.5*w, a1, a2, arc);
+ }
+ else /* Elipse: mudar a escala p/ criar a partir do circulo */
+ {
+ fprintf(ctxcanvas->file, "[0 0 0 0 0 0] currentmatrix\n"); /* fill new matrix from CTM */
+ fprintf(ctxcanvas->file, "%g %g translate\n", xc, yc);
+ fprintf(ctxcanvas->file, "1 %g scale\n", ((double)h)/w);
+ fprintf(ctxcanvas->file, "0 0 %g %g %g %s\n", 0.5*w, a1, a2, arc);
+ fprintf(ctxcanvas->file, "setmatrix\n"); /* back to CTM */
+ }
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "%g %g %g %g %g %g B\n", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "closepath\n");
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "eofill\n");
+ else
+ fprintf(ctxcanvas->file, "fill\n");
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ fprintf(ctxcanvas->file, "stroke\n");
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ fprintf(ctxcanvas->file, "gsave\n");
+ if (ctxcanvas->holes || ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "eofill\n");
+ else
+ fprintf(ctxcanvas->file, "fill\n");
+ fprintf(ctxcanvas->file, "grestore\n");
+ sUpdateFill(ctxcanvas, 0);
+ fprintf(ctxcanvas->file, "stroke\n");
+ break;
+ case CD_PATH_CLIP:
+ if (ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ fprintf(ctxcanvas->file, "C eoclip\n");
+ else
+ fprintf(ctxcanvas->file, "C clip\n");
+ break;
+ }
+ }
+ return;
+ }
+
if (mode == CD_CLIP)
{
if (ctxcanvas->eps) /* initclip not allowed in EPS */
return;
- if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdfPoly %d Begin\n", mode);
-
fprintf(ctxcanvas->file, "/clip_polygon {\n");
fprintf(ctxcanvas->file, "initclip\n");
}
else
{
if (mode == CD_FILL)
- update_fill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 1);
else
- update_fill(ctxcanvas, 0);
-
- if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdfPoly %d Begin\n", mode);
+ sUpdateFill(ctxcanvas, 0);
}
+ if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdfPoly %d Begin\n", mode);
+
fprintf(ctxcanvas->file, "N\n");
fprintf(ctxcanvas->file, "%g %g M\n", poly[0].x, poly[0].y);
@@ -1166,7 +1454,7 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
{
- double mm = (72.0/25.4) / ctxcanvas->scale;
+ double mm = ctxcanvas->canvas->xres;
if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdLineStyle %d Begin\n", style);
@@ -1191,9 +1479,9 @@ static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
break;
case CD_CUSTOM :
{
- int i;
+ int i; /* size here is in pixels, do not use mm */
for (i = 0; i < ctxcanvas->canvas->line_dashes_count; i++)
- fprintf(ctxcanvas->file, "%g ", ctxcanvas->canvas->line_dashes[i]*mm);
+ fprintf(ctxcanvas->file, "%g ", (double)ctxcanvas->canvas->line_dashes[i]);
}
break;
}
@@ -1379,6 +1667,7 @@ static int cdfont(cdCtxCanvas *ctxcanvas, const char *type_face, int style, int
static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
{
+ /* reset to identity */
set_default_matrix(ctxcanvas);
if (matrix)
@@ -1568,7 +1857,8 @@ static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color)
static void set_rotate_attrib(cdCtxCanvas *ctxcanvas, char* data)
{
- /* ignore ROTATE if transform is set */
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
if (ctxcanvas->canvas->use_matrix)
return;
@@ -1585,15 +1875,7 @@ static void set_rotate_attrib(cdCtxCanvas *ctxcanvas, char* data)
ctxcanvas->rotate_center_y = 0;
}
- set_default_matrix(ctxcanvas);
-
- if (ctxcanvas->rotate_angle)
- {
- /* rotation = translate to point + rotation + translate back */
- fprintf(ctxcanvas->file, "%d %d translate\n", ctxcanvas->rotate_center_x, ctxcanvas->rotate_center_y);
- fprintf(ctxcanvas->file, "%g rotate\n", (double)ctxcanvas->rotate_angle);
- fprintf(ctxcanvas->file, "%d %d translate\n", -ctxcanvas->rotate_center_x, -ctxcanvas->rotate_center_y);
- }
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas *ctxcanvas)
@@ -1619,7 +1901,7 @@ static cdAttribute rotate_attrib =
static void set_cmd_attrib(cdCtxCanvas *ctxcanvas, char* data)
{
- fprintf(ctxcanvas->file, data);
+ fprintf(ctxcanvas->file, "%s", data);
}
static cdAttribute cmd_attrib =
@@ -1715,16 +1997,16 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
{
int paper;
sscanf(line, "%d", &paper);
- setpspapersize(ctxcanvas, paper);
+ cdSetPaperSize(paper, &ctxcanvas->width_pt, &ctxcanvas->height_pt);
break;
}
case 'w':
sscanf(line, "%g", &num);
- ctxcanvas->width = mm2pt(num);
+ ctxcanvas->width_pt = mm2pt(num);
break;
case 'h':
sscanf(line, "%g", &num);
- ctxcanvas->height = mm2pt(num);
+ ctxcanvas->height_pt = mm2pt(num);
break;
case 'l':
sscanf(line, "%g", &num);
@@ -1774,9 +2056,9 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
/* update canvas context */
canvas->ctxcanvas = ctxcanvas;
- if (ctxcanvas->landscape == 1)
+ if (ctxcanvas->landscape)
{
- _cdSwapDouble(ctxcanvas->width, ctxcanvas->height);
+ _cdSwapDouble(ctxcanvas->width_pt, ctxcanvas->height_pt);
_cdSwapDouble(ctxcanvas->xmin, ctxcanvas->ymin);
_cdSwapDouble(ctxcanvas->xmax, ctxcanvas->ymax);
}
@@ -1787,7 +2069,9 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
static void cdinittable(cdCanvas* canvas)
{
canvas->cxFlush = cdflush;
+
canvas->cxPixel = cdpixel;
+
canvas->cxLine = cdline;
canvas->cxPoly = cdpoly;
canvas->cxRect = cdrect;
@@ -1796,8 +2080,10 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxSector = cdsector;
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+
canvas->cxPutImageRectRGB = cdputimagerectrgb;
canvas->cxPutImageRectMap = cdputimagerectmap;
+
canvas->cxFLine = cdfline;
canvas->cxFPoly = cdfpoly;
canvas->cxFRect = cdfrect;
@@ -1805,6 +2091,8 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFArc = cdfarc;
canvas->cxFSector = cdfsector;
canvas->cxFChord = cdfchord;
+ canvas->cxFText = cdftext;
+
canvas->cxClip = cdclip;
canvas->cxFClipArea = cdfcliparea;
canvas->cxLineStyle = cdlinestyle;
diff --git a/cd/src/drv/cgm.c b/cd/src/drv/cgm.c
index e86baaf..ea4d930 100755
--- a/cd/src/drv/cgm.c
+++ b/cd/src/drv/cgm.c
@@ -743,7 +743,7 @@ static void cgmb_s ( CGM *cgm, const char *s, int len )
else
cgmb_putu8(cgm,l);
- for ( i=0; i<len; s++ )
+ for ( i=0; i<l; i++, s++ )
{
if ( (i + bc) == 32766 )
{
@@ -756,7 +756,7 @@ static void cgmb_s ( CGM *cgm, const char *s, int len )
else
cgmb_putu16 ( cgm, l );
}
- cgmb_putc ( cgm, s[i] );
+ cgmb_putc ( cgm, *s );
}
}
diff --git a/cd/src/gdiplus/cdwclpp.cpp b/cd/src/gdiplus/cdwclpp.cpp
index 719713f..0e3c5ea 100755
--- a/cd/src/gdiplus/cdwclpp.cpp
+++ b/cd/src/gdiplus/cdwclpp.cpp
@@ -187,10 +187,8 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS |
- CD_CAP_PLAY |
- CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS | CD_CAP_PLAY |
+ CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdiplus/cdwdbufp.cpp b/cd/src/gdiplus/cdwdbufp.cpp
index 95cfe2e..68bc7b8 100755
--- a/cd/src/gdiplus/cdwdbufp.cpp
+++ b/cd/src/gdiplus/cdwdbufp.cpp
@@ -120,7 +120,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
bitmap->SetResolution((REAL)(canvas_dbuffer->xres*25.4), (REAL)(canvas_dbuffer->yres*25.4));
Graphics imggraphics(bitmap);
- imggraphics.Clear(Color::White);
+ imggraphics.Clear(Color((ARGB)Color::White));
Graphics* graphics = new Graphics(bitmap);
@@ -147,8 +147,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdiplus/cdwemfp.cpp b/cd/src/gdiplus/cdwemfp.cpp
index 38b4200..23ae02d 100755
--- a/cd/src/gdiplus/cdwemfp.cpp
+++ b/cd/src/gdiplus/cdwemfp.cpp
@@ -58,7 +58,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void* data)
Rect frameRect(0, 0, (int)(100 * w / canvas->xres), (int)(100 * h / canvas->yres));
metafile = new Metafile(cdwpString2Unicode(filename, strlen(filename)),
- ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL);
+ ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL);
ReleaseDC(NULL, ScreenDC);
}
@@ -86,7 +86,6 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdEMFContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_FLUSH | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES |
CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV),
1,
cdcreatecanvas,
diff --git a/cd/src/gdiplus/cdwimgp.cpp b/cd/src/gdiplus/cdwimgp.cpp
index 697ff40..5dd8b96 100755
--- a/cd/src/gdiplus/cdwimgp.cpp
+++ b/cd/src/gdiplus/cdwimgp.cpp
@@ -48,8 +48,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdiplus/cdwinp.cpp b/cd/src/gdiplus/cdwinp.cpp
index 1cbed3c..013cc9a 100755
--- a/cd/src/gdiplus/cdwinp.cpp
+++ b/cd/src/gdiplus/cdwinp.cpp
@@ -51,10 +51,10 @@ void cdwpShowStatus(const char* title, Status status)
void cdwpKillCanvas(cdCtxCanvas* ctxcanvas)
{
if (ctxcanvas->clip_poly) delete[] ctxcanvas->clip_poly;
+ if (ctxcanvas->clip_fpoly) delete[] ctxcanvas->clip_fpoly;
if (ctxcanvas->clip_region) delete ctxcanvas->clip_region;
if (ctxcanvas->new_region) delete ctxcanvas->new_region;
if (ctxcanvas->font) delete ctxcanvas->font;
- if (ctxcanvas->wdpoly) delete ctxcanvas->wdpoly;
delete ctxcanvas->fillBrush;
delete ctxcanvas->lineBrush;
@@ -65,13 +65,14 @@ void cdwpKillCanvas(cdCtxCanvas* ctxcanvas)
/* ctxcanvas e´ liberado em cada driver */
}
-static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
+static int sAddTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
{
if (matrix)
{
// configure a bottom-up coordinate system
Matrix Matrix1((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
transformMatrix.Multiply(&Matrix1);
+
// add the global transform
Matrix Matrix2((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
transformMatrix.Multiply(&Matrix2);
@@ -89,11 +90,11 @@ static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, con
return 0;
}
-static void cdwpUpdateTransform(cdCtxCanvas* ctxcanvas)
+static void sUpdateTransform(cdCtxCanvas* ctxcanvas)
{
Matrix transformMatrix;
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (cdwpSetTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
+ if (sAddTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -245,7 +246,10 @@ static void sClipPoly(cdCtxCanvas* ctxcanvas)
GraphicsPath path;
path.SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
- path.AddPolygon(ctxcanvas->clip_poly, ctxcanvas->clip_poly_n);
+ if (ctxcanvas->clip_fpoly)
+ path.AddPolygon(ctxcanvas->clip_fpoly, ctxcanvas->clip_poly_n);
+ else
+ path.AddPolygon(ctxcanvas->clip_poly, ctxcanvas->clip_poly_n);
ctxcanvas->clip_region = new Region(&path);
ctxcanvas->graphics->SetClip(ctxcanvas->clip_region);
@@ -523,6 +527,7 @@ static void cdpattern(cdCtxCanvas* ctxcanvas, int w, int h, const long int *colo
{
int line_offset_colors;
int line_offset = j*stride;
+ /* internal transform, affects also pattern orientation */
if (ctxcanvas->canvas->invert_yaxis)
line_offset_colors = ((h - 1) - j)*w; // Fix up side down
else
@@ -551,6 +556,7 @@ static int cdinteriorstyle(cdCtxCanvas* ctxcanvas, int style)
delete ctxcanvas->fillBrush;
ctxcanvas->fillBrush = new SolidBrush(ctxcanvas->fg);
break;
+ /* the remaining styles must recreate the current brush */
case CD_HATCH:
cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
break;
@@ -571,6 +577,12 @@ static void cdline(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
ctxcanvas->dirty = 1;
}
+static void cdfline(cdCtxCanvas* ctxcanvas, double x1, double y1, double x2, double y2)
+{
+ ctxcanvas->graphics->DrawLine(ctxcanvas->linePen, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2);
+ ctxcanvas->dirty = 1;
+}
+
static void cdrect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
Rect rect(xmin, ymin, xmax-xmin, ymax-ymin); // in this case Size = Max - Min
@@ -578,6 +590,13 @@ static void cdrect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int yma
ctxcanvas->dirty = 1;
}
+static void cdfrect(cdCtxCanvas* ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ RectF rect((REAL)xmin, (REAL)ymin, (REAL)(xmax-xmin), (REAL)(ymax-ymin)); // in this case Size = Max - Min
+ ctxcanvas->graphics->DrawRectangle(ctxcanvas->linePen, rect);
+ ctxcanvas->dirty = 1;
+}
+
static void cdbox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
Rect rect(xmin, ymin, xmax-xmin+1, ymax-ymin+1);
@@ -593,13 +612,36 @@ static void cdbox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax
}
}
-static void cdwpFixAngles(cdCtxCanvas* ctxcanvas, double *angle1, double *angle2)
+static void cdfbox(cdCtxCanvas* ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- if (ctxcanvas->canvas->invert_yaxis)
+ RectF rect((REAL)xmin, (REAL)ymin, (REAL)(xmax-xmin+1), (REAL)(ymax-ymin+1));
+ if (ctxcanvas->canvas->new_region)
+ {
+ Region region(rect);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
{
- // GDI+ angle are clock-wise by default
- *angle1 *= -1;
- *angle2 *= -1;
+ ctxcanvas->graphics->FillRectangle(ctxcanvas->fillBrush, rect);
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2)
+{
+ // GDI+ angles are clock-wise by default, in degrees
+
+ /* if NOT inverted means a transformation is set,
+ so the angle will follow the transformation that includes the axis invertion,
+ then it is already counter-clockwise */
+
+ if (canvas->invert_yaxis)
+ {
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
+
+ /* no need to swap, because we will use (angle2-angle1) */
}
}
@@ -610,7 +652,20 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ ctxcanvas->dirty = 1;
+}
+
+static void cdfarc(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (angle1 == 0 && angle2 == 360)
+ ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
ctxcanvas->dirty = 1;
@@ -626,7 +681,7 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
}
Region region(&path);
@@ -644,7 +699,43 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
}
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void cdfsector(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path;
+ if (angle1==0 && angle2==360)
+ path.AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ {
+ // complete the remaining pixels using an Arc
+ Pen pen(ctxcanvas->fillBrush);
+
+ if (angle1==0 && angle2==360)
+ {
+ ctxcanvas->graphics->FillEllipse(ctxcanvas->fillBrush, rect);
+ ctxcanvas->graphics->DrawEllipse(&pen, rect);
+ }
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
@@ -662,7 +753,41 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ path.CloseFigure();
+ }
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ {
+ if (angle1==0 && angle2==360)
+ ctxcanvas->graphics->FillEllipse(ctxcanvas->fillBrush, rect);
+ else
+ {
+ GraphicsPath path;
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
+ }
+ Pen pen(ctxcanvas->fillBrush); // complete the remaining pixels using an Arc
+ ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void cdfchord(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path;
+ if (angle1==0 && angle2==360)
+ path.AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
path.CloseFigure();
}
@@ -676,7 +801,7 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
else
{
GraphicsPath path;
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
}
@@ -688,8 +813,118 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
- switch( mode )
+ switch (mode)
{
+ case CD_PATH:
+ {
+ int p, i, current_x = 0, current_y = 0, current_set = 0;
+ GraphicsPath* graphics_path;
+ PointF lastPoint;
+
+ /* starts a new path */
+ graphics_path = new GraphicsPath(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ graphics_path->Reset();
+ graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ if (current_set)
+ graphics_path->AddLine(current_x, current_y, poly[i].x, poly[i].y);
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (current_set)
+ {
+ int StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ cdCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
+ else
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
+
+ graphics_path->AddLine(current_x, current_y, StartX, StartY);
+ }
+
+ Rect rect(xc - w/2, yc - h/2, w, h);
+ if (a1 == 0 && a2 == 360)
+ graphics_path->AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
+ graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
+ }
+
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = (int)lastPoint.X;
+ current_y = (int)lastPoint.Y;
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
+ graphics_path->AddBezier(current_x, current_y, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = (int)lastPoint.X;
+ current_y = (int)lastPoint.Y;
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ graphics_path->CloseFigure();
+ break;
+ case CD_PATH_FILL:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ break;
+ case CD_PATH_STROKE:
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_FILLSTROKE:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_CLIP:
+ ctxcanvas->graphics->SetClip(graphics_path, CombineModeIntersect);
+ break;
+ }
+ }
+
+ delete graphics_path;
+ break;
+ }
case CD_BEZIER:
if (n < 4) return;
ctxcanvas->graphics->DrawBeziers(ctxcanvas->linePen, (Point*)poly, n);
@@ -748,6 +983,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
if (ctxcanvas->clip_poly)
delete[] ctxcanvas->clip_poly;
+ if (ctxcanvas->clip_fpoly)
+ {
+ delete[] ctxcanvas->clip_fpoly;
+ ctxcanvas->clip_fpoly = NULL;
+ }
ctxcanvas->clip_poly = new Point [n];
@@ -779,6 +1019,242 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
ctxcanvas->dirty = 1;
}
+static PointF* sPolyToFloat(cdfPoint* poly, int n)
+{
+ PointF* fpoly = new PointF[n+1];
+
+ for (int i = 0; i < n; i++)
+ {
+ fpoly[i].X = (REAL)poly[i].x;
+ fpoly[i].Y = (REAL)poly[i].y;
+ }
+
+ return fpoly;
+}
+
+static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
+{
+ PointF* fpoly = NULL;
+
+ switch (mode)
+ {
+ case CD_PATH:
+ {
+ int p, i, current_set = 0;
+ double current_x = 0, current_y = 0;
+ GraphicsPath* graphics_path;
+ PointF lastPoint;
+
+ /* starts a new path */
+ graphics_path = new GraphicsPath(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ graphics_path->Reset();
+ graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ if (current_set)
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y);
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (current_set)
+ {
+ double StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
+ else
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
+
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)StartX, (REAL)StartY);
+ }
+
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (a1 == 0 && a2 == 360)
+ graphics_path->AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
+ graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
+ }
+
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = lastPoint.X;
+ current_y = lastPoint.Y;
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
+ graphics_path->AddBezier((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y, (REAL)poly[i+1].x, (REAL)poly[i+1].y, (REAL)poly[i+2].x, (REAL)poly[i+2].y);
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = lastPoint.X;
+ current_y = lastPoint.Y;
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ graphics_path->CloseFigure();
+ break;
+ case CD_PATH_FILL:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ break;
+ case CD_PATH_STROKE:
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_FILLSTROKE:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_CLIP:
+ ctxcanvas->graphics->SetClip(graphics_path, CombineModeIntersect);
+ break;
+ }
+ }
+
+ delete graphics_path;
+ break;
+ }
+ case CD_BEZIER:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawBeziers(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_FILLSPLINE:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ path.AddClosedCurve((PointF*)fpoly, n);
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ ctxcanvas->graphics->FillClosedCurve(ctxcanvas->fillBrush, (PointF*)fpoly, n);
+ break;
+ case CD_SPLINE:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawClosedCurve(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_CLOSED_LINES:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+ /* continue */
+ case CD_OPEN_LINES:
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawLines(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_FILLGRADIENT:
+ {
+ int count = n;
+ PathGradientBrush* brush = new PathGradientBrush((PointF*)fpoly, n);
+ fpoly = sPolyToFloat(poly, n);
+ brush->SetSurroundColors(ctxcanvas->pathGradient, &count);
+ brush->SetCenterColor(ctxcanvas->pathGradient[n]);
+ ctxcanvas->graphics->FillPolygon(brush, (PointF*)fpoly, n, ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ delete brush;
+ }
+ break;
+ case CD_FILL:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+ fpoly = sPolyToFloat(poly, n);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ path.AddPolygon((PointF*)fpoly, n);
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ ctxcanvas->graphics->FillPolygon(ctxcanvas->fillBrush, (PointF*)fpoly, n, ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ break;
+ case CD_CLIP:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+
+ if (ctxcanvas->clip_fpoly)
+ delete[] ctxcanvas->clip_fpoly;
+ if (ctxcanvas->clip_poly)
+ {
+ delete[] ctxcanvas->clip_poly;
+ ctxcanvas->clip_poly = NULL;
+ }
+
+ ctxcanvas->clip_fpoly = new PointF [n];
+
+ cdfPoint* pnt = poly;
+ int t = n;
+ int nc = 1;
+
+ ctxcanvas->clip_fpoly[0].X = (REAL)pnt->x;
+ ctxcanvas->clip_fpoly[0].Y = (REAL)pnt->y;
+ pnt++;
+
+ for (int i = 1; i < t-1; i++, pnt++)
+ {
+ if (!(((REAL)pnt->x == ctxcanvas->clip_fpoly[nc-1].X && pnt->x == (pnt + 1)->x) ||
+ ((REAL)pnt->y == ctxcanvas->clip_fpoly[nc-1].Y && pnt->y == (pnt + 1)->y)))
+ {
+ ctxcanvas->clip_fpoly[nc].X = (REAL)pnt->x;
+ ctxcanvas->clip_fpoly[nc].Y = (REAL)pnt->y;
+ nc++;
+ }
+ }
+
+ ctxcanvas->clip_poly_n = nc;
+
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ sClipPoly(ctxcanvas);
+
+ break;
+ }
+
+ if (fpoly)
+ delete[] fpoly;
+
+ ctxcanvas->dirty = 1;
+}
+
WCHAR* cdwpString2Unicode(const char* s, int len)
{
static WCHAR wstr[10240] = L"";
@@ -829,7 +1305,7 @@ static void sTextBox(cdCtxCanvas* ctxcanvas, WCHAR *ws, int len, int x, int y, i
*ymin += ydir * (*h);
}
-static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
+static void sGetTransformTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
{
int xmin, xmax, ymin, ymax;
@@ -865,21 +1341,12 @@ static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h
*hbox = ymax-ymin+1;
}
-static void cdwpTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
+static void sAddTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
{
int hbox;
- double* matrix = ctxcanvas->canvas->matrix;
Matrix m1;
- cdwpCanvasGetTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
-
- // configure a bottom-up coordinate system
- m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
- transformMatrix.Multiply(&m1);
-
- // add the global transform
- m1.SetElements((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
- transformMatrix.Multiply(&m1);
+ sGetTransformTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
// move to (x,y) and remove a vertical offset since text reference point is top-left
m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)1, (REAL)*x, (REAL)(*y - (hbox-1)));
@@ -912,10 +1379,12 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
if (ctxcanvas->canvas->use_matrix)
{
- cdwpTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
+ double* matrix = ctxcanvas->canvas->matrix;
+ sAddTransform(ctxcanvas, transformMatrix, matrix);
+ sAddTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
use_transform = 1;
}
- else if (cdwpSetTransform(ctxcanvas, transformMatrix, NULL))
+ else if (sAddTransform(ctxcanvas, transformMatrix, NULL))
use_transform = 1;
if (ctxcanvas->canvas->new_region)
@@ -944,7 +1413,7 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
ctxcanvas->lineBrush);
if (use_transform)
- cdwpUpdateTransform(ctxcanvas); // reset transform
+ sUpdateTransform(ctxcanvas); // reset transform
ctxcanvas->dirty = 1;
}
@@ -1141,7 +1610,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
else
ctxcanvas->canvas->invert_yaxis = 1;
- if (cdwpSetTransform(ctxcanvas, transformMatrix, matrix))
+ if (sAddTransform(ctxcanvas, transformMatrix, matrix))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -1173,6 +1642,10 @@ static void sRGB2Bitmap(Bitmap& image, int width, int height, const unsigned cha
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1206,6 +1679,10 @@ static void sRGBA2Bitmap(Bitmap& image, int width, int height, const unsigned ch
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1237,6 +1714,10 @@ static void sAlpha2Bitmap(Bitmap& image, int width, int height, const unsigned c
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1279,6 +1760,10 @@ static void sMap2Bitmap(Bitmap& image, int width, int height, const unsigned cha
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1337,7 +1822,7 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *red, unsigned c
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
y = _cdInvertYAxis(ctxcanvas->canvas, y);
int yr = y - (h - 1); /* y starts at the bottom of the image */
@@ -1637,7 +2122,7 @@ static cdCtxImage *cdcreateimage(cdCtxCanvas* ctxcanvas, int width, int height)
ctximage->h_mm = ctximage->h / ctximage->yres;
Graphics imggraphics(ctximage->bitmap);
- imggraphics.Clear(Color::White);
+ imggraphics.Clear(Color((ARGB)Color::White));
return ctximage;
}
@@ -1649,10 +2134,11 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
y = _cdInvertYAxis(ctxcanvas->canvas, y);
- int yr = y - (ctximage->h - 1); /* y0 starts at the bottom of the image */
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
if (ctxcanvas->wtype == CDW_BMP)
{
@@ -1660,7 +2146,7 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
imggraphics.DrawImage(ctxcanvas->bitmap,
Rect(0, 0, ctximage->w,ctximage->h),
- x, yr, ctximage->w, ctximage->h, UnitPixel,
+ x, y, ctximage->w, ctximage->h, UnitPixel,
NULL, NULL, NULL);
}
else
@@ -1670,7 +2156,7 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
HDC hdc = ctxcanvas->graphics->GetHDC();
HDC img_hdc = imggraphics.GetHDC();
- BitBlt(img_hdc,0,0,ctximage->w,ctximage->h,hdc,x,yr,SRCCOPY);
+ BitBlt(img_hdc,0,0,ctximage->w,ctximage->h,hdc,x,y,SRCCOPY);
imggraphics.ReleaseHDC(img_hdc);
ctxcanvas->graphics->ReleaseHDC(hdc);
@@ -1740,7 +2226,7 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
{
dy = -dy;
ymin = _cdInvertYAxis(ctxcanvas->canvas, ymin);
@@ -1992,7 +2478,8 @@ static cdAttribute linecap_attrib =
static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
- /* ignore ROTATE if transform is set */
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
if (ctxcanvas->canvas->use_matrix)
return;
@@ -2009,7 +2496,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
ctxcanvas->rotate_center_y = 0;
}
- cdwpUpdateTransform(ctxcanvas);
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
@@ -2073,19 +2560,22 @@ static cdAttribute img_points_attrib =
get_img_points_attrib
};
-static BOOL Is_WinXP_or_Later(void)
+static BOOL Is_WinXP_or_WinSrv03(void)
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&osvi);
- BOOL bIsWindowsXPorLater =
+ BOOL bIsWindowsXP =
+ (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1));
+
+ BOOL bIsWindowsServer2003 =
(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
- ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) &&
- (osvi.dwMinorVersion >= 1)));
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2));
- return bIsWindowsXPorLater;
+ return bIsWindowsXP || bIsWindowsServer2003;
}
static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
@@ -2101,7 +2591,7 @@ static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
ctxcanvas->graphics->SetInterpolationMode(InterpolationModeBilinear);
ctxcanvas->graphics->SetSmoothingMode(SmoothingModeAntiAlias);
- if (Is_WinXP_or_Later())
+ if (Is_WinXP_or_WinSrv03())
ctxcanvas->graphics->SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
else
ctxcanvas->graphics->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
@@ -2198,7 +2688,7 @@ void cdwpUpdateCanvas(cdCtxCanvas* ctxcanvas)
else
set_aa_attrib(ctxcanvas, NULL);
- cdwpUpdateTransform(ctxcanvas);
+ sUpdateTransform(ctxcanvas);
}
/*
@@ -2229,6 +2719,7 @@ cdCtxCanvas *cdwpCreateCanvas(cdCanvas* canvas, Graphics* graphics, int wtype)
canvas->invert_yaxis = 1;
ctxcanvas->clip_poly = NULL;
+ ctxcanvas->clip_fpoly = NULL;
ctxcanvas->clip_poly_n = 0;
ctxcanvas->clip_region = NULL;
ctxcanvas->new_region = NULL;
@@ -2284,6 +2775,7 @@ void cdwpInitTable(cdCanvas* canvas)
canvas->cxFlush = cdflush;
canvas->cxPixel = cdpixel;
+
canvas->cxLine = cdline;
canvas->cxPoly = cdpoly;
canvas->cxRect = cdrect;
@@ -2293,6 +2785,14 @@ void cdwpInitTable(cdCanvas* canvas)
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+ canvas->cxFLine = cdfline;
+ canvas->cxFPoly = cdfpoly;
+ canvas->cxFRect = cdfrect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfarc;
+ canvas->cxFSector = cdfsector;
+ canvas->cxFChord = cdfchord;
+
canvas->cxNewRegion = cdnewregion;
canvas->cxIsPointInRegion = cdispointinregion;
canvas->cxOffsetRegion = cdoffsetregion;
diff --git a/cd/src/gdiplus/cdwinp.h b/cd/src/gdiplus/cdwinp.h
index 0c4ae55..b42dc9a 100755
--- a/cd/src/gdiplus/cdwinp.h
+++ b/cd/src/gdiplus/cdwinp.h
@@ -48,15 +48,12 @@ struct _cdCtxCanvas
} fontinfo;
Point *clip_poly; /* coordenadas do pixel no X,Y */
+ PointF *clip_fpoly; /* coordenadas do pixel no X,Y */
int clip_poly_n; /* numero de pontos correntes */
Region *clip_region;
Region *new_region;
- int max_points;
- PointF *wdpoly; // cache buffer for wdpoly
- Point *cdpoly; // alias to cache buffer (float=int)
-
int antialias;
Point gradient[2];
diff --git a/cd/src/gdiplus/cdwnativep.cpp b/cd/src/gdiplus/cdwnativep.cpp
index fffd044..80209af 100755
--- a/cd/src/gdiplus/cdwnativep.cpp
+++ b/cd/src/gdiplus/cdwnativep.cpp
@@ -121,8 +121,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdiplus/cdwprnp.cpp b/cd/src/gdiplus/cdwprnp.cpp
index 3d2b9f7..2eed9d9 100755
--- a/cd/src/gdiplus/cdwprnp.cpp
+++ b/cd/src/gdiplus/cdwprnp.cpp
@@ -140,7 +140,6 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdPrinterContext =
{
CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES |
CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV),
1,
cdcreatecanvas,
diff --git a/cd/src/gdk/cdgdk.c b/cd/src/gdk/cdgdk.c
index b0c8ea8..dfffef1 100644
--- a/cd/src/gdk/cdgdk.c
+++ b/cd/src/gdk/cdgdk.c
@@ -12,8 +12,6 @@
#include "cdgdk.h"
-#include <gdk/gdk.h>
-
#define NUM_HATCHES 6
#define HATCH_WIDTH 8
#define HATCH_HEIGHT 8
@@ -35,7 +33,7 @@ static char hatches[NUM_HATCHES][8] = {
/******************************************************/
-static int gdkStrIsAscii(const char* str)
+static int sStrIsAscii(const char* str)
{
while(*str)
{
@@ -47,12 +45,12 @@ static int gdkStrIsAscii(const char* str)
return 1;
}
-static char* gdkStrToUTF8(const char *str, const char* charset, int length)
+static char* sStrToUTF8(const char *str, const char* charset, int length)
{
return g_convert(str, length, "UTF-8", charset, NULL, NULL, NULL);
}
-char* cdgdkStrConvertToUTF8(cdCtxCanvas *ctxcanvas, const char* str, int length) /* From CD to GTK/GDK */
+static char* sStrConvertToUTF8(cdCtxCanvas *ctxcanvas, const char* str, int length) /* From CD to GDK */
{
const char *charset = NULL;
@@ -67,28 +65,28 @@ char* cdgdkStrConvertToUTF8(cdCtxCanvas *ctxcanvas, const char* str, int length)
}
else
{
- ctxcanvas->gdkLastConvertUTF8 = gdkStrToUTF8(str, "ISO8859-1", length); /* if string is not UTF-8, assume ISO8859-1 */
+ ctxcanvas->strLastConvertUTF8 = sStrToUTF8(str, "ISO8859-1", length); /* if string is not UTF-8, assume ISO8859-1 */
- if (!ctxcanvas->gdkLastConvertUTF8)
+ if (!ctxcanvas->strLastConvertUTF8)
return (char*)str;
- return ctxcanvas->gdkLastConvertUTF8;
+ return ctxcanvas->strLastConvertUTF8;
}
}
else
{
- if (gdkStrIsAscii(str) || !charset)
+ if (sStrIsAscii(str) || !charset)
{
return (char*)str;
}
else if (charset)
{
- ctxcanvas->gdkLastConvertUTF8 = gdkStrToUTF8(str, charset, length);
+ ctxcanvas->strLastConvertUTF8 = sStrToUTF8(str, charset, length);
- if (!ctxcanvas->gdkLastConvertUTF8)
+ if (!ctxcanvas->strLastConvertUTF8)
return (char*)str;
- return ctxcanvas->gdkLastConvertUTF8;
+ return ctxcanvas->strLastConvertUTF8;
}
}
return (char*)str;
@@ -136,6 +134,9 @@ void cdgdkKillCanvas(cdCtxCanvas *ctxcanvas)
g_object_unref(ctxcanvas->last_stipple);
}
+ if (ctxcanvas->strLastConvertUTF8)
+ g_free(ctxcanvas->strLastConvertUTF8);
+
g_object_unref(ctxcanvas->gc);
free(ctxcanvas);
@@ -532,23 +533,21 @@ static int cdfont(cdCtxCanvas *ctxcanvas, const char *typeface, int style, int s
if (style & CD_STRIKEOUT)
is_strikeout = 1;
- if (size < 0)
- {
- double res = ((double)gdk_screen_get_width(gdk_screen_get_default()) /
- (double)gdk_screen_get_width_mm(gdk_screen_get_default())); /* pixels/mm */
-
- /* 1 point = 1/72 inch 1 inch = 25.4 mm */
- /* pixel = ((point/72)*25.4)*pixel/mm */
- size = (int)((-size/res)*2.83464567 + 0.5); /* from pixels to points */
- }
+ size = cdGetFontSizePoints(ctxcanvas->canvas, size);
sprintf(font, "%s, %s%s%d", typeface, is_bold?"Bold ":"", is_italic?"Italic ":"", size);
+ if (ctxcanvas->fontdesc)
+ pango_font_description_free(ctxcanvas->fontdesc);
+
ctxcanvas->fontdesc = pango_font_description_from_string(font);
if (!ctxcanvas->fontdesc)
return 0;
+ if (ctxcanvas->fontlayout)
+ g_object_unref(ctxcanvas->fontlayout);
+
ctxcanvas->fontlayout = pango_layout_new(ctxcanvas->fontcontext);
pango_layout_set_font_description(ctxcanvas->fontlayout, ctxcanvas->fontdesc);
@@ -562,28 +561,6 @@ static int cdfont(cdCtxCanvas *ctxcanvas, const char *typeface, int style, int s
return 1;
}
-static int cdnativefont(cdCtxCanvas *ctxcanvas, const char* nativefont)
-{
- int size = 12, style = CD_PLAIN;
- char typeface[1024];
-
- /* parse the old Windows format first */
- if (!cdParseIupWinFont(nativefont, typeface, &style, &size))
- if (!cdParseXWinFont(nativefont, typeface, &style, &size))
- if (!cdParsePangoFont(nativefont, typeface, &style, &size))
- return 0;
-
- if (!cdfont(ctxcanvas, typeface, style, size))
- return 0;
-
- /* update cdfont parameters */
- ctxcanvas->canvas->font_style = style;
- ctxcanvas->canvas->font_size = size;
- strcpy(ctxcanvas->canvas->font_type_face, typeface);
-
- return 1;
-}
-
static void cdgetfontdim(cdCtxCanvas *ctxcanvas, int *max_width, int *height, int *ascent, int *descent)
{
PangoFontMetrics* metrics;
@@ -712,10 +689,12 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
{
if (ctxcanvas->canvas->use_matrix)
{
- cdarcSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimArc(ctxcanvas, xc, yc, w, h, a1, a2);
return;
}
+ /* angles in 1/64ths of degrees counterclockwise, similar to CD */
+
cdgdkCheckSolidStyle(ctxcanvas, 1);
gdk_draw_arc(ctxcanvas->wnd, ctxcanvas->gc, FALSE, xc-w/2, yc-h/2, w, h, cdRound(a1*64), cdRound((a2 - a1)*64));
cdgdkCheckSolidStyle(ctxcanvas, 0);
@@ -725,13 +704,13 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
{
if (ctxcanvas->canvas->use_matrix)
{
- cdsectorSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimSector(ctxcanvas, xc, yc, w, h, a1, a2);
return;
}
if (ctxcanvas->canvas->new_region)
{
- cdsectorSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimSector(ctxcanvas, xc, yc, w, h, a1, a2);
}
else
{
@@ -744,7 +723,7 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma
{
if (ctxcanvas->canvas->use_matrix)
{
- cdrectSIM(ctxcanvas, xmin, xmax, ymin, ymax);
+ cdSimRect(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
@@ -757,7 +736,7 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
{
if (ctxcanvas->canvas->use_matrix)
{
- cdboxSIM(ctxcanvas, xmin, xmax, ymin, ymax);
+ cdSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
@@ -782,8 +761,7 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
int w, h, desc, dir = -1;
int ox = x, oy = y;
- ctxcanvas->gdkLastConvertUTF8 = cdgdkStrConvertToUTF8(ctxcanvas, s, len);
- pango_layout_set_text(ctxcanvas->fontlayout, ctxcanvas->gdkLastConvertUTF8, -1);
+ pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), -1);
pango_layout_get_pixel_size(ctxcanvas->fontlayout, &w, &h);
metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext));
@@ -903,58 +881,61 @@ static void cdgettextsize(cdCtxCanvas *ctxcanvas, const char *s, int len, int *w
if (!ctxcanvas->fontlayout)
return;
- ctxcanvas->gdkLastConvertUTF8 = cdgdkStrConvertToUTF8(ctxcanvas, s, len);
- pango_layout_set_text(ctxcanvas->fontlayout, ctxcanvas->gdkLastConvertUTF8, -1);
+ pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), len);
pango_layout_get_pixel_size(ctxcanvas->fontlayout, width, height);
}
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
- int i;
+ int i;
- if (mode != CD_BEZIER)
- {
- for (i = 0; i < n; i++)
- {
- if (ctxcanvas->canvas->use_matrix)
- cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
- }
- }
-
- switch( mode )
- {
- case CD_FILL:
- if (ctxcanvas->canvas->new_region)
- {
- GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
- sCombineRegion(ctxcanvas, rgn);
- }
- else
- gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
- break;
-
- case CD_CLOSED_LINES:
- cdgdkCheckSolidStyle(ctxcanvas, 1);
- gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
- cdgdkCheckSolidStyle(ctxcanvas, 0);
- break;
-
- case CD_OPEN_LINES:
- cdgdkCheckSolidStyle(ctxcanvas, 1);
- gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
- cdgdkCheckSolidStyle(ctxcanvas, 0);
- break;
-
- case CD_CLIP:
- ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
- if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
- cdclip(ctxcanvas, CD_CLIPPOLYGON);
- break;
-
- case CD_BEZIER:
- cdSimPolyBezier(ctxcanvas->canvas, poly, n);
- break;
- }
+ if (mode != CD_BEZIER && mode != CD_PATH)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (ctxcanvas->canvas->use_matrix)
+ cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
+ }
+ }
+
+ switch( mode )
+ {
+ case CD_FILL:
+ if (ctxcanvas->canvas->new_region)
+ {
+ GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
+ sCombineRegion(ctxcanvas, rgn);
+ }
+ else
+ gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
+ break;
+
+ case CD_CLOSED_LINES:
+ cdgdkCheckSolidStyle(ctxcanvas, 1);
+ gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
+ cdgdkCheckSolidStyle(ctxcanvas, 0);
+ break;
+
+ case CD_OPEN_LINES:
+ cdgdkCheckSolidStyle(ctxcanvas, 1);
+ gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
+ cdgdkCheckSolidStyle(ctxcanvas, 0);
+ break;
+
+ case CD_CLIP:
+ ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ break;
+
+ case CD_BEZIER:
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ break;
+
+ case CD_PATH:
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
+ }
}
/******************************************************/
@@ -1076,10 +1057,7 @@ static void cdgetimagergb(cdCtxCanvas *ctxcanvas, unsigned char *r, unsigned cha
x, y-h+1,
0, 0, w, h);
if (!pixbuf)
- {
- fprintf(stderr, "CanvasDraw: error getting image\n");
return;
- }
cdgdkGetPixbufData(pixbuf, r, g, b);
}
@@ -1106,10 +1084,8 @@ static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, co
if (a) nc = 4;
dst_r = malloc(nc*size);
if (!dst_r)
- {
- fprintf(stderr, "CanvasDraw: no enough memory\n");
return;
- }
+
dst_g = dst_r + size;
dst_b = dst_g + size;
if (a) dst_a = dst_b + size;
@@ -1196,10 +1172,8 @@ static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, con
size = ew*eh;
dst_index = malloc(size);
if (!dst_index)
- {
- fprintf(stderr, "CanvasDraw: no enough memory\n");
return;
- }
+
memset(dst_index, 0, size);
/* for all pixels in the destiny area */
@@ -1353,7 +1327,7 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
rw = xmax-xmin+1;
rh = ymax-ymin+1;
- y -= (h - 1); /* GdkPixbuf origin is at top-left */
+ y -= (h - 1); /* GdkPixbuf image origin is at top-left */
if (!cdCalcZoom(ctxcanvas->canvas->w, x, w, &ex, &ew, xmin, rw, &bx, &bw, 1))
return;
@@ -1429,8 +1403,11 @@ static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)
static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y)
{
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
+
gdk_draw_drawable(ctximage->img, ctxcanvas->gc,
- ctxcanvas->wnd, x, y - ctximage->h+1, 0, 0,
+ ctxcanvas->wnd, x, y, 0, 0,
ctximage->w, ctximage->h);
}
@@ -1491,6 +1468,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
if (data)
{
+ /* use this configuration when there is NO native tranformation support */
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
@@ -1620,7 +1598,6 @@ cdCtxCanvas *cdgdkCreateCanvas(cdCanvas* canvas, GdkDrawable* wnd, GdkScreen* sc
ctxcanvas->fontcontext = gdk_pango_context_get();
pango_context_set_language(ctxcanvas->fontcontext, pango_language_get_default());
- ctxcanvas->gdkLastConvertUTF8 = NULL;
ctxcanvas->canvas = canvas;
canvas->ctxcanvas = ctxcanvas;
@@ -1667,7 +1644,7 @@ void cdgdkInitTable(cdCanvas* canvas)
canvas->cxBox = cdbox;
canvas->cxArc = cdarc;
canvas->cxSector = cdsector;
- canvas->cxChord = cdchordSIM;
+ canvas->cxChord = cdSimChord;
canvas->cxText = cdtext;
canvas->cxNewRegion = cdnewregion;
@@ -1687,7 +1664,6 @@ void cdgdkInitTable(cdCanvas* canvas)
canvas->cxStipple = cdstipple;
canvas->cxPattern = cdpattern;
canvas->cxFont = cdfont;
- canvas->cxNativeFont = cdnativefont;
canvas->cxGetFontDim = cdgetfontdim;
canvas->cxGetTextSize = cdgettextsize;
canvas->cxPalette = cdpalette;
diff --git a/cd/src/gdk/cdgdk.h b/cd/src/gdk/cdgdk.h
index af3cdc0..18eb288 100644
--- a/cd/src/gdk/cdgdk.h
+++ b/cd/src/gdk/cdgdk.h
@@ -59,7 +59,7 @@ struct _cdCtxCanvas {
PangoFontDescription *fontdesc;
PangoLayout *fontlayout;
PangoMatrix fontmatrix;
- char* gdkLastConvertUTF8;
+ char* strLastConvertUTF8;
cdImage* image_dbuffer; /* Used by double buffer driver */
cdCanvas* canvas_dbuffer;
diff --git a/cd/src/gdk/cdgdkclp.c b/cd/src/gdk/cdgdkclp.c
index 22e7690..3eabc54 100644
--- a/cd/src/gdk/cdgdkclp.c
+++ b/cd/src/gdk/cdgdkclp.c
@@ -115,7 +115,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE),
+ CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE ), /* same as CD_MF */
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdk/cdgdkdbuf.c b/cd/src/gdk/cdgdkdbuf.c
index aa8d587..b399cbe 100644
--- a/cd/src/gdk/cdgdkdbuf.c
+++ b/cd/src/gdk/cdgdkdbuf.c
@@ -147,8 +147,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_PATH | CD_CAP_BEZIER | CD_CAP_FPRIMTIVES ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdk/cdgdkimg.c b/cd/src/gdk/cdgdkimg.c
index 0c5e5dd..4b4475b 100644
--- a/cd/src/gdk/cdgdkimg.c
+++ b/cd/src/gdk/cdgdkimg.c
@@ -30,7 +30,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/gdk/cdgdknative.c b/cd/src/gdk/cdgdknative.c
index 9f0c5ed..8865d7e 100644
--- a/cd/src/gdk/cdgdknative.c
+++ b/cd/src/gdk/cdgdknative.c
@@ -95,7 +95,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeWindowContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/lua5/cdlua5.c b/cd/src/lua5/cdlua5.c
index cd7554f..9c981c3 100755
--- a/cd/src/lua5/cdlua5.c
+++ b/cd/src/lua5/cdlua5.c
@@ -87,7 +87,7 @@ static cdluaPalette* cdlua_rawcheckpalette(lua_State *L, int param)
}
}
}
- luaL_typerror(L, param, "cdPalette"); /* else error */
+ luaL_typeerror(L, param, "cdPalette"); /* else error */
return NULL; /* to avoid warnings */
}
@@ -1428,8 +1428,21 @@ static const struct cdlua5_constant cdlibconstant[] = {
{"CLIP" , CD_CLIP},
{"BEZIER" , CD_BEZIER},
{"REGION" , CD_REGION},
+ {"PATH" , CD_PATH},
{"POLYCUSTOM" , CD_POLYCUSTOM},
+ /* path actions */
+ {"PATH_NEW", CD_PATH_NEW},
+ {"PATH_MOVETO", CD_PATH_MOVETO},
+ {"PATH_LINETO", CD_PATH_LINETO},
+ {"PATH_ARC", CD_PATH_ARC},
+ {"PATH_CURVETO", CD_PATH_CURVETO},
+ {"PATH_CLOSE", CD_PATH_CLOSE},
+ {"PATH_FILL", CD_PATH_FILL},
+ {"PATH_STROKE", CD_PATH_STROKE},
+ {"PATH_FILLSTROKE", CD_PATH_FILLSTROKE},
+ {"PATH_CLIP", CD_PATH_CLIP},
+
/* fill mode */
{"EVENODD", CD_EVENODD},
{"WINDING", CD_WINDING},
@@ -1841,8 +1854,3 @@ int luaopen_cdlua(lua_State* L)
{
return cdlua_open(L);
}
-
-int luaopen_cdlua51(lua_State* L)
-{
- return cdlua_open(L);
-}
diff --git a/cd/src/lua5/cdlua5.def b/cd/src/lua5/cdlua5.def
index b4811b2..2a14843 100755
--- a/cd/src/lua5/cdlua5.def
+++ b/cd/src/lua5/cdlua5.def
@@ -8,6 +8,5 @@ EXPORTS
cdlua_checkcanvas
cdlua_pushcanvas
luaopen_cdlua
- luaopen_cdlua51
cdlua_pushbitmap
cdlua_checkbitmap \ No newline at end of file
diff --git a/cd/src/lua5/cdlua5_canvas.c b/cd/src/lua5/cdlua5_canvas.c
index f3b929d..c2f6008 100755
--- a/cd/src/lua5/cdlua5_canvas.c
+++ b/cd/src/lua5/cdlua5_canvas.c
@@ -1494,7 +1494,7 @@ static int wdlua5_gettextbox(lua_State *L)
}
/***************************************************************************************************************\
-* cd.GetTextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) *
+* cd.GetTextBounds(x, y: number, text: string) -> (rect: table) *
\***************************************************************************************************************/
static int cdlua5_gettextbounds(lua_State *L)
{
@@ -1502,21 +1502,20 @@ static int cdlua5_gettextbounds(lua_State *L)
int x = luaL_checkint(L, 2);
int y = luaL_checkint(L, 3);
const char* s = luaL_checkstring(L, 4);
+ int i;
cdCanvasGetTextBounds(cdlua_checkcanvas(L, 1), x, y, s, rect);
- lua_pushnumber(L, rect[0]);
- lua_pushnumber(L, rect[1]);
- lua_pushnumber(L, rect[2]);
- lua_pushnumber(L, rect[3]);
- lua_pushnumber(L, rect[4]);
- lua_pushnumber(L, rect[5]);
- lua_pushnumber(L, rect[6]);
- lua_pushnumber(L, rect[7]);
- return 4;
+ lua_newtable(L);
+ for (i=0; i < 8; i++)
+ {
+ lua_pushnumber(L, rect[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+ return 1;
}
/****************************************************************************************************************\
-* cd.wGetTextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) *
+* cd.wGetTextBounds(x, y: number, text: string) -> (rect: table) *
\****************************************************************************************************************/
static int wdlua5_gettextbounds(lua_State *L)
{
@@ -1524,17 +1523,16 @@ static int wdlua5_gettextbounds(lua_State *L)
double x = luaL_checknumber(L, 2);
double y = luaL_checknumber(L, 3);
const char* s = luaL_checkstring(L, 4);
+ int i;
wdCanvasGetTextBounds(cdlua_checkcanvas(L, 1), x, y, s, rect);
- lua_pushnumber(L, rect[0]);
- lua_pushnumber(L, rect[1]);
- lua_pushnumber(L, rect[2]);
- lua_pushnumber(L, rect[3]);
- lua_pushnumber(L, rect[4]);
- lua_pushnumber(L, rect[5]);
- lua_pushnumber(L, rect[6]);
- lua_pushnumber(L, rect[7]);
- return 4;
+ lua_newtable(L);
+ for (i=0; i < 8; i++)
+ {
+ lua_pushnumber(L, rect[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+ return 1;
}
@@ -2205,6 +2203,12 @@ static int cdlua5_vertex(lua_State *L)
return 0;
}
+static int cdlua5_pathset(lua_State *L)
+{
+ cdCanvasPathSet(cdlua_checkcanvas(L, 1), luaL_checkint(L, 2));
+ return 0;
+}
+
static int wdlua5_vertex(lua_State *L)
{
wdCanvasVertex(cdlua_checkcanvas(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3));
@@ -2429,6 +2433,7 @@ static const struct luaL_reg cdlib_canvas_meta[] = {
/* Polygon */
{"Begin" , cdlua5_begin},
+ {"PathSet" , cdlua5_pathset},
{"Vertex" , cdlua5_vertex},
{"wVertex" , wdlua5_vertex},
{"fVertex" , cdlua5_fvertex},
diff --git a/cd/src/lua5/cdlua5ctx.c b/cd/src/lua5/cdlua5ctx.c
index 4d97f3b..71f090d 100755
--- a/cd/src/lua5/cdlua5ctx.c
+++ b/cd/src/lua5/cdlua5ctx.c
@@ -1,5 +1,5 @@
/***************************************************************************\
-* $Id: cdlua5ctx.c,v 1.2 2009/12/02 20:31:02 scuri Exp $
+* $Id: cdlua5ctx.c,v 1.4 2010/06/11 17:28:56 scuri Exp $
* *
\***************************************************************************/
@@ -25,7 +25,9 @@
#include "cdps.h"
#include "cdsvg.h"
#include "cddbuf.h"
-#include "cdgdiplus.h"
+#include "cddebug.h"
+#include "cdpicture.h"
+
#include <lua.h>
#include <lauxlib.h>
@@ -321,6 +323,24 @@ static cdluaContext cdluadbufctx =
};
/***************************************************************************\
+* CD_DBUFFERRGB. *
+\***************************************************************************/
+static void *cddbufrgb_checkdata(lua_State * L, int param)
+{
+ return cdlua_checkcanvas(L, param);
+}
+
+static cdluaContext cdluadbufrgbctx =
+{
+ 0,
+ "DBUFFERRGB",
+ cdContextDBufferRGB,
+ cddbufrgb_checkdata,
+ NULL,
+ 0
+};
+
+/***************************************************************************\
* CD_IMAGE. *
\***************************************************************************/
static void *cdimage_checkdata(lua_State *L, int param)
@@ -377,7 +397,7 @@ static void *cdimagergb_checkdata(lua_State* L, int param)
int ret = cdlua_rawchecktype(L, param, "cdBitmap");
if (ret == 0)
- luaL_typerror(L, param, "cdBitmap"); /* not a user data and not a metatable */
+ luaL_typeerror(L, param, "cdBitmap"); /* not a user data and not a metatable */
if (ret == 1)
{
@@ -467,7 +487,7 @@ static void *cdimagergb_checkdata(lua_State* L, int param)
return data_s;
}
- luaL_typerror(L, param, "cdBitmap"); /* is a metatable but it is not one of the accepted */
+ luaL_typeerror(L, param, "cdBitmap"); /* is a metatable but it is not one of the accepted */
}
return data_s;
@@ -620,6 +640,42 @@ static int emf_sizecb(cdCanvas *canvas, int w, int h, double mm_w, double mm_h)
}
/***************************************************************************\
+* CD_PICTURE. *
+\***************************************************************************/
+static void *cdpicture_checkdata(lua_State *L,int param)
+{
+ return (void *)luaL_checkstring(L,param);
+}
+
+static cdluaContext cdluapicturectx =
+{
+ 0,
+ "PICTURE",
+ cdContextPicture,
+ cdpicture_checkdata,
+ NULL,
+ 0
+};
+
+/***************************************************************************\
+* CD_DEBUG. *
+\***************************************************************************/
+static void *cddebug_checkdata(lua_State *L,int param)
+{
+ return (void *)luaL_checkstring(L,param);
+}
+
+static cdluaContext cdluadebugctx =
+{
+ 0,
+ "DEBUG",
+ cdContextDebug,
+ cddebug_checkdata,
+ NULL,
+ 0
+};
+
+/***************************************************************************\
* CD_METAFILE. *
\***************************************************************************/
static void *cdmetafile_checkdata(lua_State *L,int param)
@@ -811,6 +867,8 @@ void cdlua_initdrivers(lua_State * L, cdluaLuaState* cdL)
cdlua_addcontext(L, cdL, &cdluadgnctx);
cdlua_addcontext(L, cdL, &cdluacgmctx);
cdlua_addcontext(L, cdL, &cdluamfctx);
+ cdlua_addcontext(L, cdL, &cdluadebugctx);
+ cdlua_addcontext(L, cdL, &cdluapicturectx);
cdlua_addcontext(L, cdL, &cdluapsctx);
cdlua_addcontext(L, cdL, &cdluasvgctx);
cdlua_addcontext(L, cdL, &cdluaclipboardctx);
@@ -819,4 +877,5 @@ void cdlua_initdrivers(lua_State * L, cdluaLuaState* cdL)
cdlua_addcontext(L, cdL, &cdluawmfctx);
cdlua_addcontext(L, cdL, &cdluaemfctx);
cdlua_addcontext(L, cdL, &cdluadbufctx);
+ cdlua_addcontext(L, cdL, &cdluadbufrgbctx);
}
diff --git a/cd/src/lua5/cdluacontextplus5.c b/cd/src/lua5/cdluacontextplus5.c
index de69167..aa19633 100755
--- a/cd/src/lua5/cdluacontextplus5.c
+++ b/cd/src/lua5/cdluacontextplus5.c
@@ -37,8 +37,3 @@ int luaopen_cdluacontextplus(lua_State* L)
{
return cdluacontextplus_open(L);
}
-
-int luaopen_cdluacontextplus51(lua_State* L)
-{
- return cdluacontextplus_open(L);
-}
diff --git a/cd/src/lua5/cdluacontextplus5.def b/cd/src/lua5/cdluacontextplus5.def
index 55e478b..69bdb2c 100755
--- a/cd/src/lua5/cdluacontextplus5.def
+++ b/cd/src/lua5/cdluacontextplus5.def
@@ -1,4 +1,3 @@
EXPORTS
luaopen_cdluacontextplus
- luaopen_cdluacontextplus51
\ No newline at end of file
diff --git a/cd/src/lua5/cdluaim5.c b/cd/src/lua5/cdluaim5.c
index 815cd0f..579c2c9 100755
--- a/cd/src/lua5/cdluaim5.c
+++ b/cd/src/lua5/cdluaim5.c
@@ -285,8 +285,3 @@ int luaopen_cdluaim(lua_State *L)
{
return cdluaim_open(L);
}
-
-int luaopen_cdluaim51(lua_State *L)
-{
- return cdluaim_open(L);
-}
diff --git a/cd/src/lua5/cdluaim5.def b/cd/src/lua5/cdluaim5.def
index 0b26928..df8d982 100755
--- a/cd/src/lua5/cdluaim5.def
+++ b/cd/src/lua5/cdluaim5.def
@@ -1,4 +1,3 @@
EXPORTS
cdluaim_open
luaopen_cdluaim
- luaopen_cdluaim51
diff --git a/cd/src/lua5/cdluapdf5.c b/cd/src/lua5/cdluapdf5.c
index eb3f221..7fd2ece 100755
--- a/cd/src/lua5/cdluapdf5.c
+++ b/cd/src/lua5/cdluapdf5.c
@@ -37,7 +37,11 @@ int cdluapdf_open (lua_State *L)
{
cdluaLuaState* cdL = cdlua_getstate(L);
lua_pushliteral(L, "cd");
+#if LUA_VERSION_NUM > 501
+ lua_pushglobaltable(L);
+#else
lua_gettable(L, LUA_GLOBALSINDEX); /* leave "cd" table at the top of the stack */
+#endif
cdlua_addcontext(L, cdL, &cdluapdfctx);
return 1;
}
@@ -47,7 +51,3 @@ int luaopen_cdluapdf(lua_State* L)
return cdluapdf_open(L);
}
-int luaopen_cdluapdf51(lua_State* L)
-{
- return cdluapdf_open(L);
-}
diff --git a/cd/src/lua5/cdluapdf5.def b/cd/src/lua5/cdluapdf5.def
index bfbc889..8555b36 100755
--- a/cd/src/lua5/cdluapdf5.def
+++ b/cd/src/lua5/cdluapdf5.def
@@ -1,4 +1,3 @@
EXPORTS
cdluapdf_open
luaopen_cdluapdf
- luaopen_cdluapdf51 \ No newline at end of file
diff --git a/cd/src/lua5/cdvoid5.c b/cd/src/lua5/cdvoid5.c
index 2424e1d..67c2c99 100755
--- a/cd/src/lua5/cdvoid5.c
+++ b/cd/src/lua5/cdvoid5.c
@@ -80,9 +80,9 @@ void cdinittable(cdCanvas* canvas)
canvas->cxArc = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
canvas->cxSector = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
canvas->cxChord = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
- canvas->cxText = (void (*)(cdCtxCanvas*, int ,int ,const char *))cdvoid_error;
+ canvas->cxText = (void (*)(cdCtxCanvas*, int ,int ,const char *, int))cdvoid_error;
canvas->cxGetFontDim = (void (*)(cdCtxCanvas*, int *,int *,int *,int *))cdvoid_error;
- canvas->cxGetTextSize = (void (*)(cdCtxCanvas*, const char *,int *,int *))cdvoid_error;
+ canvas->cxGetTextSize = (void (*)(cdCtxCanvas*, const char *,int,int *,int *))cdvoid_error;
canvas->cxPutImageRectRGB = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const unsigned char *,const unsigned char *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
canvas->cxPutImageRectRGBA = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
canvas->cxPutImageRectMap = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const long *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
@@ -93,7 +93,7 @@ void cdinittable(cdCanvas* canvas)
canvas->cxFBox = (void (*)(cdCtxCanvas*, double ,double ,double ,double ))cdvoid_error;
canvas->cxFArc = (void (*)(cdCtxCanvas*, double ,double ,double ,double ,double ,double ))cdvoid_error;
canvas->cxFSector = (void (*)(cdCtxCanvas*, double ,double ,double ,double ,double ,double ))cdvoid_error;
- canvas->cxFText = (void (*)(cdCtxCanvas*, double ,double ,const char *))cdvoid_error;
+ canvas->cxFText = (void (*)(cdCtxCanvas*, double ,double ,const char *,int))cdvoid_error;
canvas->cxStipple = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *))cdvoid_error;
canvas->cxPattern = (void (*)(cdCtxCanvas*, int ,int , const long *))cdvoid_error;
canvas->cxNativeFont = (int (*)(cdCtxCanvas*, const char*))cdvoid_error;
diff --git a/cd/src/make_uname b/cd/src/make_uname
deleted file mode 100755
index 8c2f35e..0000000
--- a/cd/src/make_uname
+++ /dev/null
@@ -1,17 +0,0 @@
-#This builds all the libraries of the folder for 1 uname
-
-tecmake $1 MF=cd_freetype $2 $3 $4 $5 $6 $7 $8
-tecmake $1 $2 $3 $4 $5 $6 $7 $8
-tecmake $1 USE_GDK=Yes $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cd_pdflib $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cdpdf $2 $3 $4 $5 $6 $7 $8
-#tecmake $1 MF=cdlua3 $2 $3 $4 $5 $6 $7 $8
-#tecmake $1 MF=cdluapdf3 $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cdlua5 $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cdluaim5 $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cdluapdf5 $2 $3 $4 $5 $6 $7 $8
-
-# XRender is NOT available in AIX, IRIX and SunOS
-# It is available in Linux, Darwin and FreeBSD
-tecmake $1 MF=cdcontextplus $2 $3 $4 $5 $6 $7 $8
-tecmake $1 MF=cdluacontextplus5 $2 $3 $4 $5 $6 $7 $8
diff --git a/cd/src/sim/sim.c b/cd/src/sim/sim.c
index 3e4ccf1..839e4ff 100755
--- a/cd/src/sim/sim.c
+++ b/cd/src/sim/sim.c
@@ -88,7 +88,7 @@ void simFillHorizLine(cdSimulation* simulation, int xmin, int y, int xmax)
switch(canvas->interior_style)
{
case CD_SOLID:
- simulation->SolidLine(canvas, xmin,y,xmax);
+ simulation->SolidLine(canvas, xmin,y,xmax, canvas->foreground);
break;
case CD_PATTERN:
simulation->PatternLine(canvas, xmin,xmax,y,canvas->pattern_w,
@@ -106,10 +106,20 @@ void simFillHorizLine(cdSimulation* simulation, int xmin, int y, int xmax)
}
}
-static void simSolidLine(cdCanvas* canvas, int xmin, int y, int xmax)
+void simFillHorizBox(cdSimulation* simulation, int xmin, int xmax, int ymin, int ymax)
{
- /* cdpolySIM and cdboxSIM will set line attributes so this can work */
- canvas->cxLine(canvas->ctxcanvas, xmin, y, xmax, y);
+ int y;
+ for(y=ymin;y<=ymax;y++)
+ simFillHorizLine(simulation, xmin, y, xmax);
+}
+
+static void simSolidLine(cdCanvas* canvas, int xmin, int y, int xmax, long color)
+{
+ int x;
+ for (x = xmin; x <= xmax; x++)
+ {
+ canvas->cxPixel(canvas->ctxcanvas, x,y,color);
+ }
}
static void simPatternLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const long *pattern)
@@ -117,12 +127,10 @@ static void simPatternLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
cdSimulation* simulation = canvas->simulation;
int x,i;
int xb;
- long curColor, old_color;
+ long curColor;
i = xmin % pw;
-
- old_color = canvas->foreground;
-
+
for (x = xmin; x <= xmax;)
{
if (i == pw)
@@ -142,13 +150,8 @@ static void simPatternLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
if(xb==x-1)
canvas->cxPixel(canvas->ctxcanvas, xb,y,curColor);
else
- {
- cdCanvasSetForeground(canvas, curColor);
- simulation->SolidLine(canvas, xb,y,x-1);
- }
+ simulation->SolidLine(canvas, xb,y,x-1, curColor);
}
-
- cdCanvasSetForeground(canvas, old_color);
}
static void simStippleLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const unsigned char *stipple)
@@ -165,7 +168,7 @@ static void simStippleLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
if(opacity==CD_OPAQUE)
{
bgColor=canvas->background;
- cdCanvasSetForeground(canvas, fgColor);
+
for (x = xmin, i=xmin%pw ; x <= xmax;)
{
if(i==pw)
@@ -184,10 +187,10 @@ static void simStippleLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
if(xb==x-1)
canvas->cxPixel(canvas->ctxcanvas, xb,y,fgColor);
else
- simulation->SolidLine(canvas, xb,y,x-1);
+ simulation->SolidLine(canvas, xb,y,x-1,fgColor);
}
}
- cdCanvasSetForeground(canvas, bgColor);
+
for (x = xmin, i=xmin%pw ; x <= xmax;)
{
if(i==pw)
@@ -206,13 +209,12 @@ static void simStippleLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
if(xb==x-1)
canvas->cxPixel(canvas->ctxcanvas, xb,y,bgColor);
else
- simulation->SolidLine(canvas, xb,y,x-1);
+ simulation->SolidLine(canvas, xb,y,x-1,bgColor);
}
}
}
else
{
- cdCanvasSetForeground(canvas, fgColor);
for (x = xmin,i=xmin%pw; x <= xmax;)
{
xb=x;
@@ -229,11 +231,10 @@ static void simStippleLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw,
if(xb==x-1)
canvas->cxPixel(canvas->ctxcanvas, xb,y,fgColor);
else
- simulation->SolidLine(canvas, xb,y,x-1);
+ simulation->SolidLine(canvas, xb,y,x-1,fgColor);
}
}
}
- cdCanvasSetForeground(canvas, fgColor);
}
static void simHatchLine(cdCanvas* canvas, int xmin, int xmax, int y, unsigned char hatch)
@@ -268,15 +269,11 @@ static void simHatchLine(cdCanvas* canvas, int xmin, int xmax, int y, unsigned c
if(xb==x)
canvas->cxPixel(canvas->ctxcanvas, xb,y,curColor);
else
- {
- cdCanvasSetForeground(canvas, curColor);
- simulation->SolidLine(canvas, xb,y,x);
- }
+ simulation->SolidLine(canvas, xb,y,x, curColor);
}
}
else
{
- cdCanvasSetForeground(canvas, fgColor);
for (x = xmin; x <= xmax; x++)
{
mask=(hatch&0x80)?1:0;
@@ -295,12 +292,10 @@ static void simHatchLine(cdCanvas* canvas, int xmin, int xmax, int y, unsigned c
if(xb==x)
canvas->cxPixel(canvas->ctxcanvas, xb,y,fgColor);
else
- simulation->SolidLine(canvas, xb,y,x);
+ simulation->SolidLine(canvas, xb,y,x,fgColor);
}
}
}
-
- cdCanvasSetForeground(canvas, fgColor);
}
cdSimulation* cdCreateSimulation(cdCanvas* canvas)
diff --git a/cd/src/sim/sim.h b/cd/src/sim/sim.h
index e98b030..2832391 100755
--- a/cd/src/sim/sim.h
+++ b/cd/src/sim/sim.h
@@ -18,7 +18,7 @@ struct _cdSimulation
int font_map_n;
/* horizontal line draw functions */
- void (*SolidLine)(cdCanvas* canvas, int xmin, int y, int xmax);
+ void (*SolidLine)(cdCanvas* canvas, int xmin, int y, int xmax, long color);
void (*PatternLine)(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const long *pattern);
void (*StippleLine)(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const unsigned char *stipple);
void (*HatchLine)(cdCanvas* canvas, int xmin, int xmax, int y, unsigned char hatch);
@@ -28,6 +28,7 @@ struct _cdSimulation
void simFillDrawAAPixel(cdCanvas *canvas, int x, int y, unsigned short alpha_weigth);
void simFillHorizLine(cdSimulation* simulation, int xmin, int y, int xmax);
+void simFillHorizBox(cdSimulation* simulation, int xmin, int xmax, int ymin, int ymax);
int simIsPointInPolyWind(cdPoint* poly, int n, int x, int y);
/* list of non-horizontal line segments */
@@ -49,10 +50,9 @@ void simPolyMakeSegments(simLineSegment *segments, int *n_seg, cdPoint* poly, in
void simPolyFill(cdSimulation* simulation, cdPoint* poly, int n);
void simLineThin(cdCanvas* canvas, int x1, int y1, int x2, int y2);
void simLineThick(cdCanvas* canvas, int x1, int y1, int x2, int y2);
+void simfLineThick(cdCanvas* canvas, double x1, double y1, double x2, double y2);
void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2, int *last_xi_a, int *last_yi_a, int *last_xi_b, int *last_yi_b);
extern int simLineStyleNoReset;
-int simCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height);
-
#endif
diff --git a/cd/src/sim/sim_linepolyfill.c b/cd/src/sim/sim_linepolyfill.c
index 2454a00..f73b26f 100755
--- a/cd/src/sim/sim_linepolyfill.c
+++ b/cd/src/sim/sim_linepolyfill.c
@@ -712,13 +712,67 @@ void simLineThick(cdCanvas* canvas, int x1, int y1, int x2, int y2)
cdCanvasLineStyle(canvas, style);
}
+void simfLineThick(cdCanvas* canvas, double x1, double y1, double x2, double y2)
+{
+ const int interior = canvas->interior_style;
+ const int width = canvas->line_width;
+ const int style = canvas->line_style;
+
+ const double dx = x2-x1;
+ const double dy = y2-y1;
+
+ const double len = hypot(dx,dy);
+
+ const double dnx = dx/len;
+ const double dny = dy/len;
+
+ const double w1 = width/2.0;
+ const double w2 = width-w1;
+
+ const double n1x = w1*dny;
+ const double n1y = -w1*dnx;
+
+ const double n2x = -w2*dny;
+ const double n2y = w2*dnx;
+
+ const double p1x = x1 + n1x;
+ const double p1y = y1 + n1y;
+ const double p2x = x1 + n2x;
+ const double p2y = y1 + n2y;
+ const double p3x = p2x + dx;
+ const double p3y = p2y + dy;
+ const double p4x = p1x + dx;
+ const double p4y = p1y + dy;
+
+ cdPoint poly[4];
+
+ cdCanvasLineWidth(canvas, 1);
+ cdCanvasInteriorStyle(canvas, CD_SOLID);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+
+ poly[0].x = _cdRound(p1x);
+ poly[0].y = _cdRound(p1y);
+ poly[1].x = _cdRound(p2x);
+ poly[1].y = _cdRound(p2y);
+ poly[2].x = _cdRound(p3x);
+ poly[2].y = _cdRound(p3y);
+ poly[3].x = _cdRound(p4x);
+ poly[3].y = _cdRound(p4y);
+
+ simPolyFill(canvas->simulation, poly, 4);
+
+ cdCanvasLineWidth(canvas, width);
+ cdCanvasInteriorStyle(canvas, interior);
+ cdCanvasLineStyle(canvas, style);
+}
+
void simLineThin(cdCanvas* canvas, int x1, int y1, int x2, int y2)
{
unsigned short ErrorInc, ErrorAcc;
unsigned short ErrorAccTemp, Weighting;
int DeltaX, DeltaY, XDir;
long aa_fgcolor;
- unsigned char alpha = cdAlpha(canvas->foreground), aa_alpha;
+ unsigned char alpha = cdAlpha(canvas->foreground), aa_alpha1, aa_alpha2;
int no_antialias = !(canvas->simulation->antialias);
unsigned short int ls;
long fgcolor = canvas->foreground;
@@ -840,11 +894,12 @@ void simLineThin(cdCanvas* canvas, int x1, int y1, int x2, int y2)
weighting for the paired pixel.
Combine the Weighting with the existing alpha,
When Weighting is zero alpha must be fully preserved. */
- aa_alpha = (unsigned char)(((255-Weighting) * alpha) / 255);
+ aa_alpha1 = (unsigned char)(((255-Weighting) * alpha) / 255);
+ aa_alpha2 = (unsigned char)((Weighting * alpha) / 255);
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, x1, y1, ls, aa_fgcolor);
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, x1 + XDir, y1, ls, aa_fgcolor);
ls = simRotateLineStyle(ls);
}
@@ -891,11 +946,12 @@ void simLineThin(cdCanvas* canvas, int x1, int y1, int x2, int y2)
weighting for the paired pixel.
Combine the Weighting with the existing alpha,
When Weighting is zero alpha must be fully preserved. */
- aa_alpha = (unsigned char)(((255-Weighting) * alpha) / 255);
+ aa_alpha1 = (unsigned char)(((255-Weighting) * alpha) / 255);
+ aa_alpha2 = (unsigned char)((Weighting * alpha) / 255);
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, x1, y1, ls, aa_fgcolor);
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, x1, y1+1, ls, aa_fgcolor);
ls = simRotateLineStyle(ls);
}
@@ -914,7 +970,7 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
{
double DeltaX, DeltaY, a, b;
long aa_fgcolor;
- unsigned char alpha = cdAlpha(canvas->foreground), aa_alpha;
+ unsigned char alpha = cdAlpha(canvas->foreground), aa_alpha1, aa_alpha2;
int no_antialias = !(canvas->simulation->antialias);
int yi, xi, update_a = 1, update_b = 1;
unsigned short int ls;
@@ -975,11 +1031,12 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
/* Combine the Weighting with the existing alpha,
When Weighting is zero alpha must be fully preserved. */
- aa_alpha = (unsigned char)((1.0-(x - xi)) * alpha);
+ aa_alpha1 = (unsigned char)((1.0-(x - xi)) * alpha);
+ aa_alpha2 = (unsigned char)((x - xi) * alpha);
if (no_antialias)
{
- if (aa_alpha > 128)
+ if (aa_alpha1 > 128)
_cdLineDrawPixel(canvas, xi, yi, ls, fgcolor)
else
_cdLineDrawPixel(canvas, xi+1, yi, ls, fgcolor)
@@ -999,7 +1056,7 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
if ((xi != *last_xi_a || yi != *last_yi_a) &&
(xi != *last_xi_b || yi != *last_yi_b))
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, xi, yi, ls, aa_fgcolor);
if (yi == yi_last) /* one pixel only */
@@ -1009,7 +1066,7 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
if ((xi+1 != *last_xi_a || yi != *last_yi_a) &&
(xi+1 != *last_xi_b || yi != *last_yi_b))
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, xi+1, yi, ls, aa_fgcolor);
if (yi == yi_last) /* one pixel only */
@@ -1018,9 +1075,9 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
}
else
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, xi, yi, ls, aa_fgcolor);
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, xi+1, yi, ls, aa_fgcolor);
}
}
@@ -1061,11 +1118,12 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
/* Combine the Weighting with the existing alpha,
When Weighting is zero alpha must be fully preserved. */
- aa_alpha = (unsigned char)((1.0-(y - yi)) * alpha);
+ aa_alpha1 = (unsigned char)((1.0-(y - yi)) * alpha);
+ aa_alpha2 = (unsigned char)((y - yi) * alpha);
if (no_antialias)
{
- if (aa_alpha > 128)
+ if (aa_alpha1 > 128)
_cdLineDrawPixel(canvas, xi, yi, ls, fgcolor)
else
_cdLineDrawPixel(canvas, xi, yi+1, ls, fgcolor)
@@ -1085,7 +1143,7 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
if ((xi != *last_xi_a || yi != *last_yi_a) &&
(xi != *last_xi_b || yi != *last_yi_b))
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, xi, yi, ls, aa_fgcolor);
if (xi == xi_last) /* one pixel only */
@@ -1095,7 +1153,7 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
if ((xi != *last_xi_a || yi+1 != *last_yi_a) &&
(xi != *last_xi_b || yi+1 != *last_yi_b))
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, xi, yi+1, ls, aa_fgcolor);
if (xi == xi_last) /* one pixel only */
@@ -1104,9 +1162,9 @@ void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2,
}
else
{
- aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha1);
_cdLineDrawPixel(canvas, xi, yi, ls, aa_fgcolor);
- aa_fgcolor = cdEncodeAlpha(fgcolor, 255-aa_alpha);
+ aa_fgcolor = cdEncodeAlpha(fgcolor, aa_alpha2);
_cdLineDrawPixel(canvas, xi, yi+1, ls, aa_fgcolor);
}
}
diff --git a/cd/src/sim/sim_other.c b/cd/src/sim/sim_other.c
deleted file mode 100755
index 0954406..0000000
--- a/cd/src/sim/sim_other.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/** \file
- * \brief Simulation that is independent of the Simulation Base Driver
- *
- * See Copyright Notice in cd.h
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <memory.h>
-
-#include "cd.h"
-#include "cd_private.h"
-
-
-void cdSimMark(cdCanvas* canvas, int x, int y)
-{
- int oldinteriorstyle = canvas->interior_style;
- int oldlinestyle = canvas->line_style;
- int oldlinewidth = canvas->line_width;
- int size = canvas->mark_size;
- int half_size = size/2;
- int bottom = y-half_size;
- int top = y+half_size;
- int left = x-half_size;
- int right = x+half_size;
-
- if (canvas->interior_style != CD_SOLID &&
- (canvas->mark_type == CD_CIRCLE ||
- canvas->mark_type == CD_BOX ||
- canvas->mark_type == CD_DIAMOND))
- cdCanvasInteriorStyle(canvas, CD_SOLID);
-
- if (canvas->line_style != CD_CONTINUOUS &&
- (canvas->mark_type == CD_STAR ||
- canvas->mark_type == CD_PLUS ||
- canvas->mark_type == CD_X ||
- canvas->mark_type == CD_HOLLOW_BOX ||
- canvas->mark_type == CD_HOLLOW_CIRCLE ||
- canvas->mark_type == CD_HOLLOW_DIAMOND))
- cdCanvasLineStyle(canvas, CD_CONTINUOUS);
-
- if (canvas->line_width != 1 &&
- (canvas->mark_type == CD_STAR ||
- canvas->mark_type == CD_PLUS ||
- canvas->mark_type == CD_X ||
- canvas->mark_type == CD_HOLLOW_BOX ||
- canvas->mark_type == CD_HOLLOW_CIRCLE ||
- canvas->mark_type == CD_HOLLOW_DIAMOND))
- cdCanvasLineWidth(canvas, 1);
-
- switch (canvas->mark_type)
- {
- case CD_STAR:
- canvas->cxLine(canvas->ctxcanvas, left, bottom, right, top);
- canvas->cxLine(canvas->ctxcanvas, left, top, right, bottom);
- /* continue */
- case CD_PLUS:
- canvas->cxLine(canvas->ctxcanvas, left, y, right, y);
- canvas->cxLine(canvas->ctxcanvas, x, bottom, x, top);
- break;
- case CD_HOLLOW_CIRCLE:
- canvas->cxArc(canvas->ctxcanvas, x, y, size, size, 0, 360);
- break;
- case CD_HOLLOW_BOX:
- canvas->cxRect(canvas->ctxcanvas, left, right, bottom, top);
- break;
- case CD_HOLLOW_DIAMOND:
- canvas->cxLine(canvas->ctxcanvas, left, y, x, top);
- canvas->cxLine(canvas->ctxcanvas, x, top, right, y);
- canvas->cxLine(canvas->ctxcanvas, right, y, x, bottom);
- canvas->cxLine(canvas->ctxcanvas, x, bottom, left, y);
- break;
- case CD_X:
- canvas->cxLine(canvas->ctxcanvas, left, bottom, right, top);
- canvas->cxLine(canvas->ctxcanvas, left, top, right, bottom);
- break;
- case CD_CIRCLE:
- canvas->cxSector(canvas->ctxcanvas, x, y, size, size, 0, 360);
- break;
- case CD_BOX:
- canvas->cxBox(canvas->ctxcanvas, left, right, bottom, top);
- break;
- case CD_DIAMOND:
- {
- cdPoint poly[5];
- poly[0].x = left;
- poly[0].y = y;
- poly[1].x = x;
- poly[1].y = top;
- poly[2].x = right;
- poly[2].y = y;
- poly[3].x = x;
- poly[3].y = bottom;
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
- }
- break;
- }
-
- if (canvas->interior_style != oldinteriorstyle &&
- (canvas->mark_type == CD_CIRCLE ||
- canvas->mark_type == CD_BOX ||
- canvas->mark_type == CD_DIAMOND))
- cdCanvasInteriorStyle(canvas, oldinteriorstyle);
-
- if (canvas->line_style != oldlinestyle &&
- (canvas->mark_type == CD_STAR ||
- canvas->mark_type == CD_PLUS ||
- canvas->mark_type == CD_X ||
- canvas->mark_type == CD_HOLLOW_BOX ||
- canvas->mark_type == CD_HOLLOW_CIRCLE ||
- canvas->mark_type == CD_HOLLOW_DIAMOND))
- cdCanvasLineStyle(canvas, oldlinestyle);
-
- if (canvas->line_width != oldlinewidth &&
- (canvas->mark_type == CD_STAR ||
- canvas->mark_type == CD_PLUS ||
- canvas->mark_type == CD_X ||
- canvas->mark_type == CD_HOLLOW_BOX ||
- canvas->mark_type == CD_HOLLOW_CIRCLE ||
- canvas->mark_type == CD_HOLLOW_DIAMOND))
- cdCanvasLineWidth(canvas, oldlinewidth);
-}
-
-/* Setup Bezier coefficient array once for each control polygon.
- */
-static void BezierForm(const cdPoint* p, cdfPoint* c)
-{
- int k;
- static int choose[4] = {1, 3, 3, 1};
- for (k = 0; k < 4; k++)
- {
- c[k].x = p[k].x * choose[k];
- c[k].y = p[k].y * choose[k];
- }
-}
-
-static void fBezierForm(const cdfPoint* p, cdfPoint* c)
-{
- int k;
- static int choose[4] = {1, 3, 3, 1};
- for (k = 0; k < 4; k++)
- {
- c[k].x = p[k].x * choose[k];
- c[k].y = p[k].y * choose[k];
- }
-}
-
-/* Return Point pt(t), t <= 0 <= 1 from C.
- * BezierForm must be called once for any given control polygon.
- */
-static void BezierCurve(const cdfPoint* c, cdfPoint *pt, double t)
-{
- int k;
- double t1, tt, u;
- cdfPoint b[4];
-
- u = t;
-
- b[0].x = c[0].x;
- b[0].y = c[0].y;
- for(k = 1; k < 4; k++)
- {
- b[k].x = c[k].x * u;
- b[k].y = c[k].y * u;
- u =u*t;
- }
-
- pt->x = b[3].x;
- pt->y = b[3].y;
- t1 = 1-t;
- tt = t1;
- for(k = 2; k >= 0; k--)
- {
- pt->x += b[k].x * tt;
- pt->y += b[k].y * tt;
- tt =tt*t1;
- }
-}
-
-static int BezierNumSegments(cdCanvas* canvas, const cdPoint* p)
-{
- int i, K, dx, dy, d,
- xmax = p[0].x,
- ymax = p[0].y,
- xmin = p[0].x,
- ymin = p[0].y;
-
- for (i = 1; i < 4; i++)
- {
- if (p[i].x > xmax)
- xmax = p[i].x;
- if (p[i].y > ymax)
- ymax = p[i].y;
- if (p[i].x < xmin)
- xmin = p[i].x;
- if (p[i].y < ymin)
- ymin = p[i].y;
- }
-
- if (canvas->use_matrix)
- {
- cdMatrixTransformPoint(canvas->matrix, xmin, ymin, &xmin, &ymin);
- cdMatrixTransformPoint(canvas->matrix, xmax, ymax, &xmax, &ymax);
- }
-
- /* diagonal of the bouding box */
- dx = (xmax-xmin);
- dy = (ymax-ymin);
- d = (int)(sqrt(dx*dx + dy*dy));
- K = d / 8;
- if (K < 8) K = 8;
- return K;
-}
-
-static int fBezierNumSegments(cdCanvas* canvas, const cdfPoint* p)
-{
- int i, K, d;
- double dx, dy,
- xmax = p[0].x,
- ymax = p[0].y,
- xmin = p[0].x,
- ymin = p[0].y;
-
- for (i = 1; i < 4; i++)
- {
- if (p[i].x > xmax)
- xmax = p[i].x;
- if (p[i].y > ymax)
- ymax = p[i].y;
- if (p[i].x < xmin)
- xmin = p[i].x;
- if (p[i].y < ymin)
- ymin = p[i].y;
- }
-
- /* diagonal of the bouding box */
- dx = (xmax-xmin);
- dy = (ymax-ymin);
- d = (int)(sqrt(dx*dx + dy*dy));
- K = d / 8;
- if (K < 8) K = 8;
- return K;
-}
-
-/* from sim.h */
-void simfLineThin(cdCanvas* canvas, double x1, double y1, double x2, double y2, int *last_xi_a, int *last_yi_a, int *last_xi_b, int *last_yi_b);
-
-/* Quick and Simple Bezier Curve Drawing --- Robert D. Miller
- * Graphics GEMS V */
-void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n)
-{
- int i = 0, k, K, poly_max = 0;
- cdfPoint pt, prev_pt;
- cdfPoint bezier_control[4];
- cdPoint* poly = NULL;
- int use_poly = 0,
- last_xi_a = -65535,
- last_yi_a = -65535,
- last_xi_b = -65535,
- last_yi_b = -65535;
-
- /* Use special floating point anti-alias line draw when
- line_width==1, and NOT using cdlineSIM. */
- if (canvas->line_width > 1 || canvas->cxLine != cdlineSIM)
- use_poly = 1;
-
- n--; /* first n is 4 */
- while (n >= 3)
- {
- BezierForm(points+i, bezier_control);
- K = BezierNumSegments(canvas, points+i);
-
- if (use_poly && poly_max < K+1)
- {
- poly = realloc(poly, sizeof(cdPoint)*(K+1)); /* K+1 points */
- if (!poly) return;
- poly_max = K+1;
- }
-
- /* first segment */
- BezierCurve(bezier_control, &pt, 0);
- if (use_poly)
- {
- poly[0].x = _cdRound(pt.x);
- poly[0].y = _cdRound(pt.y);
- }
- else
- prev_pt = pt;
-
- for(k = 1; k < K+1; k++)
- {
- BezierCurve(bezier_control, &pt, (double)k/(double)K);
-
- if (use_poly)
- {
- poly[k].x = _cdRound(pt.x);
- poly[k].y = _cdRound(pt.y);
- }
- else
- {
- int old_use_matrix = canvas->use_matrix;
- double x1 = prev_pt.x,
- y1 = prev_pt.y,
- x2 = pt.x,
- y2 = pt.y;
-
- if (canvas->use_matrix && !canvas->invert_yaxis)
- {
- cdfMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
- cdfMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
- }
-
- /* must disable transformation here, because line simulation use cxPixel */
- canvas->use_matrix = 0;
-
- simfLineThin(canvas, x1, y1, x2, y2, &last_xi_a, &last_yi_a, &last_xi_b, &last_yi_b);
-
- canvas->use_matrix = old_use_matrix;
- prev_pt = pt;
- }
- }
-
- if (use_poly)
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, k);
-
- n -= 3; i += 3;
- }
-
- if (poly) free(poly);
-}
-
-void cdfSimPolyBezier(cdCanvas* canvas, const cdfPoint* points, int n)
-{
- int i = 0, k, K, poly_max = 0;
- cdfPoint pt;
- cdfPoint bezier_control[4];
- cdfPoint* poly = NULL;
-
- n--; /* first n is 4 */
- while (n >= 3)
- {
- fBezierForm(points+i, bezier_control);
- K = fBezierNumSegments(canvas, points+i);
-
- if (poly_max < K+1)
- {
- poly = realloc(poly, sizeof(cdfPoint)*(K+1)); /* K+1 points */
- if (!poly) return;
- poly_max = K+1;
- }
-
- /* first segment */
- BezierCurve(bezier_control, &pt, 0);
- poly[0].x = _cdRound(pt.x);
- poly[0].y = _cdRound(pt.y);
-
- for(k = 1; k < K+1; k++)
- {
- BezierCurve(bezier_control, &pt, (double)k/(double)K);
-
- poly[k].x = _cdRound(pt.x);
- poly[k].y = _cdRound(pt.y);
- }
-
- canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, k);
- n -= 3; i += 3;
- }
-
- if (poly) free(poly);
-}
-
-void cdSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
-{
- int size, i, j, dst, src, *fx, *fy, rw, rh;
- unsigned char *ar, *ag, *ab, al;
-
- size = w * h;
- ar = (unsigned char*)malloc(size*3);
- if (!ar) return;
- ag = ar + size;
- ab = ag + size;
-
- canvas->cxGetImageRGB(canvas->ctxcanvas, ar, ag, ab, x, y, w, h);
-
- rw = xmax-xmin+1;
- rh = ymax-ymin+1;
-
- fx = cdGetZoomTable(w, rw, xmin);
- fy = cdGetZoomTable(h, rh, ymin);
-
- for (j = 0; j < h; j++)
- {
- for (i = 0; i < w; i++)
- {
- dst = j * w + i;
- src = fy[j] * iw + fx[i];
- al = a[src];
- ar[dst] = CD_ALPHA_BLEND(r[src], ar[dst], al);
- ag[dst] = CD_ALPHA_BLEND(g[src], ag[dst], al);
- ab[dst] = CD_ALPHA_BLEND(b[src], ab[dst], al);
- }
- }
-
- canvas->cxPutImageRectRGB(canvas->ctxcanvas, w, h, ar, ag, ab, x, y, w, h, 0, 0, 0, 0);
-
- free(ar);
-
- free(fx);
- free(fy);
-}
diff --git a/cd/src/sim/sim_primitives.c b/cd/src/sim/sim_primitives.c
index dc991f8..2040c66 100755
--- a/cd/src/sim/sim_primitives.c
+++ b/cd/src/sim/sim_primitives.c
@@ -11,96 +11,75 @@
#include "cd.h"
#include "cd_private.h"
-#include "sim.h"
-void cdlineSIM(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
+
+void cdSimLine(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- int old_use_matrix = canvas->use_matrix;
-
- if (canvas->use_matrix && !canvas->invert_yaxis)
- {
- cdMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
- cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
- }
-
- /* must disable transformation here, because line simulation use cxPixel */
- canvas->use_matrix = 0;
-
- if(canvas->line_width > 1)
- simLineThick(canvas, x1, y1, x2, y2);
- else
- simLineThin(canvas, x1, y1, x2, y2);
+ cdPoint poly[2];
+ poly[0].x = x1; poly[0].y = y1;
+ poly[1].x = x2; poly[1].y = y2;
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, 2);
+}
- canvas->use_matrix = old_use_matrix;
+void cdfSimLine(cdCtxCanvas* ctxcanvas, double x1, double y1, double x2, double y2)
+{
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+ cdfPoint poly[2];
+ poly[0].x = x1; poly[0].y = y1;
+ poly[1].x = x2; poly[1].y = y2;
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, 2);
}
-void cdrectSIM(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+void cdSimRect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- cdPoint poly[5]; /* leave room of one more point */
+ cdPoint poly[5]; /* leave room for one more point */
poly[0].x = xmin; poly[0].y = ymin;
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 cdboxSIM(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
+void cdfSimRect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
+ /* can be used only by drivers that implement cxFPoly */
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
-
- if (canvas->use_matrix)
- {
- cdPoint poly[5]; /* leave room of one more point */
- poly[0].x = xmin; poly[0].y = ymin;
- 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);
- }
- else
- {
- cdSimulation* simulation = canvas->simulation;
- int y;
-
- /* must set line attributes here, because fill simulation use cxLine and cxPixel */
- int old_line_style = cdCanvasLineStyle(canvas, CD_CONTINUOUS);
- int old_line_width = cdCanvasLineWidth(canvas, 1);
-
- for(y=ymin;y<=ymax;y++)
- simFillHorizLine(simulation, xmin, y, xmax);
-
- cdCanvasLineStyle(canvas, old_line_style);
- cdCanvasLineWidth(canvas, old_line_width);
- }
+ cdfPoint poly[5]; /* leave room for one more point */
+ poly[0].x = xmin; poly[0].y = ymin;
+ 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->cxFPoly(canvas->ctxcanvas, CD_CLOSED_LINES, poly, 4);
}
-void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+void cdSimBox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- cdfPoint poly[5]; /* leave room of one more point */
+ cdPoint poly[5]; /* leave room for one more point */
poly[0].x = xmin; poly[0].y = ymin;
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->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
+ cdCanvasPoly(canvas, CD_FILL, poly, 4);
}
-void cdfSimRect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+void cdfSimBox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
+ /* can be used only by drivers that implement cxFPoly */
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- cdfPoint poly[5]; /* leave room of one more point */
+ cdfPoint poly[5]; /* leave room for one more point */
poly[0].x = xmin; poly[0].y = ymin;
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->cxFPoly(canvas->ctxcanvas, CD_CLOSED_LINES, poly, 4);
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, 4);
}
-int simCalcEllipseNumSegments(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,
@@ -114,6 +93,8 @@ int simCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int h
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);
@@ -125,51 +106,61 @@ int simCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int h
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;
+
- return n;
+ /* finally, calculate the number of segments for the arc */
+ K = cdRound((fabs(angle2-angle1)*K)/(360*CD_DEG2RAD));
+ if (K < 1) K = 1;
+
+ return K;
}
-void cdarcSIM(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2)
{
- cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- double c, s, sx, sy, x, y, prev_x, prev_y;
- double da;
- int i, yc2 = 2*yc, p = 0,
- last_xi_a = -65535,
- last_yi_a = -65535,
- last_xi_b = -65535,
- last_yi_b = -65535;
- cdPoint* poly = NULL;
+ /* computation in PolyAddArc is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(canvas, xc, yc, width, height);
-
- /* Use special floating point anti-alias line draw when
- line_width==1, and NOT using cdlineSIM. */
- if (canvas->line_width > 1 || canvas->cxLine != cdlineSIM)
+ if (canvas->invert_yaxis)
{
- poly = (cdPoint*)malloc(sizeof(cdPoint)*(n+1)); /* n+1 points */
- if (!poly) return;
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
+
+ /* no need to swap, because we will use (angle2-angle1) */
}
+ /* convert to radians */
+ *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)
+{
+ double c, s, sx, sy, x, y, prev_x, prev_y;
+ double da;
+ int i, K, k, p, new_n;
+ cdPoint* old_poly = poly;
+
+ sFixAngles(canvas, &angle1, &angle2);
+
/* number of segments for the arc */
- n = cdRound((fabs(angle2-angle1)*n)/360);
- if (n < 1) n = 1;
+ K = sCalcEllipseNumSegments(canvas, xc, yc, width, height, angle1, angle2);
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
+ 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 */
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
/* generates arc points at origin with axis x and y */
- da = (angle2-angle1)/n;
+ da = (angle2-angle1)/K;
c = cos(da);
s = sin(da);
sx = -(width*s)/height;
@@ -179,100 +170,56 @@ void cdarcSIM(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, dou
y = (height/2.0f)*sin(angle1);
prev_x = x;
prev_y = y;
- if (poly)
- {
- poly[0].x = _cdRound(x)+xc;
- poly[0].y = _cdRound(y)+yc;
-
- if (canvas->invert_yaxis) /* must invert because of the angle orientation */
- poly[0].y = yc2 - poly[0].y;
- p = 1;
+ if (current)
+ {
+ poly[i] = *current;
+ i++;
+ new_n++; /* no need to reallocate */
}
- else
- simLineStyleNoReset = 1;
- for (i = 1; i < n+1; i++) /* n+1 points */
+ poly[i].x = _cdRound(x)+xc;
+ poly[i].y = _cdRound(y)+yc;
+
+ p = i+1;
+ for (k = 1; k < K+1; k++)
{
x = c*prev_x + sx*prev_y;
y = sy*prev_x + c*prev_y;
- if (poly)
- {
- poly[p].x = _cdRound(x)+xc;
- poly[p].y = _cdRound(y)+yc;
-
- if (canvas->invert_yaxis) /* must invert because of the angle orientation */
- poly[p].y = yc2 - poly[p].y;
-
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
- }
- else
- {
- int old_use_matrix = canvas->use_matrix;
- double x1 = prev_x+xc,
- y1 = prev_y+yc,
- x2 = x+xc,
- y2 = y+yc;
-
- if (canvas->use_matrix && !canvas->invert_yaxis)
- {
- cdfMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
- cdfMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
- }
-
- /* must disable transformation here, because line simulation use cxPixel */
- canvas->use_matrix = 0;
-
- if (canvas->invert_yaxis) /* must invert because of the angle orientation */
- {
- y1 = yc2 - y1;
- y2 = yc2 - y2;
- }
-
- simfLineThin(canvas, x1, y1, x2, y2, &last_xi_a, &last_yi_a, &last_xi_b, &last_yi_b);
+ poly[p].x = _cdRound(x)+xc;
+ poly[p].y = _cdRound(y)+yc;
- canvas->use_matrix = old_use_matrix;
- }
+ if (poly[p-1].x != poly[p].x ||
+ poly[p-1].y != poly[p].y)
+ p++;
prev_x = x;
prev_y = y;
}
- if (poly)
- {
- canvas->cxPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, p);
- free(poly);
- }
- else
- simLineStyleNoReset = 0;
+ *n = new_n;
+ return poly;
}
-void cdfSimArc(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2)
+static cdfPoint* sfPolyAddArc(cdCanvas* canvas, cdfPoint* poly, int *n, double xc, double yc, double width, double height, double angle1, double angle2, cdfPoint* current)
{
- cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
double c, s, sx, sy, x, y, prev_x, prev_y, da;
- int i, p;
- cdfPoint* poly = NULL;
-
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(canvas, (int)xc, (int)yc, (int)width, (int)height);
+ int i, k, K, p, new_n;
+ cdfPoint* old_poly = poly;
- poly = (cdfPoint*)malloc(sizeof(cdfPoint)*(n+1)); /* n+1 points */
- if (!poly) return;
+ sFixAngles(canvas, &angle1, &angle2);
/* number of segments for the arc */
- n = cdRound((fabs(angle2-angle1)*n)/360);
- if (n < 1) n = 1;
+ K = sCalcEllipseNumSegments(canvas, (int)xc, (int)yc, (int)width, (int)height, angle1, angle2);
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
+ 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 */
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
- /* generates arc points at origin with axis x and y */
-
- da = (angle2-angle1)/n;
+ /* generates arc points at origin with axis x and y */
+ da = (angle2-angle1)/K;
c = cos(da);
s = sin(da);
sx = -(width*s)/height;
@@ -282,12 +229,19 @@ void cdfSimArc(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, doubl
y = (height/2.0f)*sin(angle1);
prev_x = x;
prev_y = y;
- poly[0].x = x+xc;
- poly[0].y = y+yc;
- p = 1;
+ if (current)
+ {
+ poly[i] = *current;
+ i++;
+ new_n++; /* no need to reallocate */
+ }
- for (i = 1; i < n+1; i++) /* n+1 points */
+ poly[i].x = x+xc;
+ poly[i].y = y+yc;
+
+ p = i+1;
+ for (k = 1; k < K+1; k++) /* K+1 points */
{
x = c*prev_x + sx*prev_y;
y = sy*prev_x + c*prev_y;
@@ -303,221 +257,1249 @@ void cdfSimArc(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, doubl
prev_y = y;
}
- canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, p);
- free(poly);
+ *n = new_n;
+ return poly;
}
-void cdfSimElipse(cdCtxCanvas* ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2, int sector)
+void cdSimArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- double c, s, sx, sy, x, y, prev_x, prev_y, da;
- int i, p;
- cdfPoint* poly;
+ int n = 0;
+ cdPoint* poly = NULL;
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(canvas, (int)xc, (int)yc, (int)width, (int)height);
+ if (canvas->line_width == 1 && canvas->cxFPoly)
+ {
+ cdfSimArc(ctxcanvas, (double)xc, (double)yc, (double)width, (double)height, angle1, angle2);
+ return;
+ }
- /* number of segments for the arc */
- n = cdRound(((angle2-angle1)*n)/360);
- if (n < 1) n = 1;
+ poly = sPolyAddArc(canvas, poly, &n, xc, yc, width, height, angle1, angle2, NULL);
- poly = (cdfPoint*)malloc(sizeof(cdfPoint)*(n+2+1)); /* n+1 points +1 center */
+ if (poly)
+ {
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, n);
+ free(poly);
+ }
+}
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
+void cdfSimArc(cdCtxCanvas *ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2)
+{
+ /* can be used only by drivers that implement cxFPoly */
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+ int n = 0;
+ cdfPoint* poly = NULL;
- /* generates arc points at origin with axis x and y */
+ poly = sfPolyAddArc(canvas, poly, &n, xc, yc, width, height, angle1, angle2, NULL);
- da = (angle2-angle1)/n;
- c = cos(da);
- s = sin(da);
- sx = -(width*s)/height;
- sy = (height*s)/width;
+ if (poly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, n);
+ free(poly);
+ }
+}
- x = xc + (width/2.0)*cos(angle1);
- y = yc + (height/2.0)*sin(angle1);
- prev_x = x;
- prev_y = y;
+static void sElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2, int sector)
+{
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+ int n = 0;
+ cdPoint* poly = NULL;
- poly[0].x = x;
- poly[0].y = y;
- p = 1;
+ poly = sPolyAddArc(canvas, poly, &n, xc, yc, width, height, angle1, angle2, NULL);
+ if (!poly)
+ return;
- for (i = 1; i < n+1; i++) /* n+1 points */
+ if (poly[n-1].x != poly[0].x ||
+ poly[n-1].y != poly[0].y)
{
- x = xc + c*(prev_x-xc) + sx*(prev_y-yc);
- y = yc + sy*(prev_x-xc) + c*(prev_y-yc);
-
- poly[p].x = x;
- poly[p].y = y;
+ n++; /* no need to reallocate */
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
+ if (sector) /* cdSector */
+ {
+ /* add center */
+ poly[n-1].x = xc;
+ poly[n-1].y = yc;
+ }
+ else /* cdChord */
+ {
+ /* add initial point */
+ poly[n-1].x = poly[0].x;
+ poly[n-1].y = poly[0].y;
+ }
+ }
- prev_x = x;
- prev_y = y;
+ if (poly)
+ {
+ cdCanvasPoly(canvas, CD_FILL, poly, n);
+ free(poly);
}
+}
- if (poly[p-1].x != poly[0].x || poly[p-1].y != poly[0].y)
+static void sfElipse(cdCtxCanvas* ctxcanvas, double xc, double yc, double width, double height, double angle1, double angle2, int sector)
+{
+ /* can be used only by drivers that implement cxFPoly */
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+ int n = 0;
+ cdfPoint* poly = NULL;
+
+ poly = sfPolyAddArc(canvas, poly, &n, xc, yc, width, height, angle1, angle2, NULL);
+
+ if (poly[n-1].x != poly[0].x ||
+ poly[n-1].y != poly[0].y)
{
+ n++; /* no need to reallocate */
+
if (sector) /* cdSector */
{
/* add center */
- poly[p].x = xc;
- poly[p].y = yc;
+ poly[n-1].x = xc;
+ poly[n-1].y = yc;
}
else /* cdChord */
{
/* add initial point */
- poly[p].x = poly[0].x;
- poly[p].y = poly[0].y;
+ poly[n-1].x = poly[0].x;
+ poly[n-1].y = poly[0].y;
}
- p++;
}
- canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, p);
- free(poly);
+ if (poly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, n);
+ free(poly);
+ }
}
-static void cdSimElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2, int sector)
+void cdSimSector(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
{
- cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- float c, s, sx, sy, x, y, prev_x, prev_y;
- double da;
- int i, p, yc2 = 2*yc;
- cdPoint* poly;
+ sElipse(ctxcanvas, xc, yc, width, height, angle1, angle2, 1);
+}
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(canvas, xc, yc, width, height);
+void cdSimChord(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
+{
+ sElipse(ctxcanvas, xc, yc, width, height, angle1, angle2, 0);
+}
- /* number of segments for the arc */
- n = cdRound(((angle2-angle1)*n)/360);
- if (n < 1) n = 1;
+void cdfSimSector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
+{
+ sfElipse(ctxcanvas, xc, yc, w, h, a1, a2, 1);
+}
- poly = (cdPoint*)malloc(sizeof(cdPoint)*(n+2+1)); /* n+1 points +1 center */
+void cdfSimChord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
+{
+ sfElipse(ctxcanvas, xc, yc, w, h, a1, a2, 0);
+}
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
+/**************************************************************/
+/* Quick and Simple Bezier Curve Drawing --- Robert D. Miller */
+/* Graphics GEMS V */
+/**************************************************************/
- /* generates arc points at origin with axis x and y */
+/* Setup Bezier coefficient array once for each control polygon.
+ */
+static void sBezierForm(cdPoint start, const cdPoint* p, cdfPoint* c)
+{
+ int k;
+ static int choose[4] = {1, 3, 3, 1};
+ for (k = 0; k < 4; k++)
+ {
+ if (k == 0)
+ {
+ c[k].x = start.x * choose[k];
+ c[k].y = start.y * choose[k];
+ }
+ else
+ {
+ c[k].x = p[k-1].x * choose[k];
+ c[k].y = p[k-1].y * choose[k];
+ }
+ }
+}
- da = (angle2-angle1)/n;
- c = (float)cos(da);
- s = (float)sin(da);
- sx = -(width*s)/height;
- sy = (height*s)/width;
+static void sfBezierForm(cdfPoint start, const cdfPoint* p, cdfPoint* c)
+{
+ int k;
+ static int choose[4] = {1, 3, 3, 1};
+ for (k = 0; k < 4; k++)
+ {
+ if (k == 0)
+ {
+ c[k].x = start.x * choose[k];
+ c[k].y = start.y * choose[k];
+ }
+ else
+ {
+ c[k].x = p[k-1].x * choose[k];
+ c[k].y = p[k-1].y * choose[k];
+ }
+ }
+}
- x = xc + (width/2.0f)*(float)cos(angle1);
- y = yc + (height/2.0f)*(float)sin(angle1);
- prev_x = x;
- prev_y = y;
+/* Return Point pt(t), t <= 0 <= 1 from C.
+ * sBezierForm must be called once for any given control polygon.
+ */
+static void sBezierCurve(const cdfPoint* c, cdfPoint *pt, double t)
+{
+ int k;
+ double t1, tt, u;
+ cdfPoint b[4];
- poly[0].x = _cdRound(x);
- poly[0].y = _cdRound(y);
- if (canvas->invert_yaxis)
- poly[0].y = yc2 - poly[0].y;
- p = 1;
+ u = t;
- for (i = 1; i < n+1; i++) /* n+1 points */
+ b[0].x = c[0].x;
+ b[0].y = c[0].y;
+ for(k = 1; k < 4; k++)
{
- x = xc + c*(prev_x-xc) + sx*(prev_y-yc);
- y = yc + sy*(prev_x-xc) + c*(prev_y-yc);
+ b[k].x = c[k].x * u;
+ b[k].y = c[k].y * u;
+ u =u*t;
+ }
- poly[p].x = _cdRound(x);
- poly[p].y = _cdRound(y);
+ pt->x = b[3].x;
+ pt->y = b[3].y;
+ t1 = 1-t;
+ tt = t1;
+ for(k = 2; k >= 0; k--)
+ {
+ pt->x += b[k].x * tt;
+ pt->y += b[k].y * tt;
+ tt =tt*t1;
+ }
+}
- if (canvas->invert_yaxis)
- poly[p].y = yc2 - poly[p].y;
+static int sBezierNumSegments(cdCanvas* canvas, cdPoint start, const cdPoint* p)
+{
+ int i, K, dx, dy, d,
+ xmax = start.x,
+ ymax = start.y,
+ xmin = start.x,
+ ymin = start.y;
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
+ for (i = 1; i < 4; i++)
+ {
+ if (p[i].x > xmax)
+ xmax = p[i].x;
+ if (p[i].y > ymax)
+ ymax = p[i].y;
+ if (p[i].x < xmin)
+ xmin = p[i].x;
+ if (p[i].y < ymin)
+ ymin = p[i].y;
+ }
- prev_x = x;
- prev_y = y;
+ if (canvas->use_matrix)
+ {
+ cdMatrixTransformPoint(canvas->matrix, xmin, ymin, &xmin, &ymin);
+ cdMatrixTransformPoint(canvas->matrix, xmax, ymax, &xmax, &ymax);
}
- if (poly[p-1].x != poly[0].x || poly[p-1].y != poly[0].y)
+ /* diagonal of the bouding box */
+ dx = (xmax-xmin);
+ dy = (ymax-ymin);
+ d = (int)(sqrt(dx*dx + dy*dy));
+ K = d / 8;
+ if (K < 8) K = 8;
+ return K;
+}
+
+static int sfBezierNumSegments(cdCanvas* canvas, cdfPoint start, const cdfPoint* p)
+{
+ int i, K, d;
+ double dx, dy,
+ xmax = start.x,
+ ymax = start.y,
+ xmin = start.x,
+ ymin = start.y;
+
+ for (i = 1; i < 4; i++)
{
- if (sector) /* cdSector */
+ if (p[i].x > xmax)
+ xmax = p[i].x;
+ if (p[i].y > ymax)
+ ymax = p[i].y;
+ if (p[i].x < xmin)
+ xmin = p[i].x;
+ if (p[i].y < ymin)
+ ymin = p[i].y;
+ }
+
+ if (canvas->use_matrix)
+ {
+ cdfMatrixTransformPoint(canvas->matrix, xmin, ymin, &xmin, &ymin);
+ cdfMatrixTransformPoint(canvas->matrix, xmax, ymax, &xmax, &ymax);
+ }
+
+ /* diagonal of the bouding box */
+ dx = (xmax-xmin);
+ dy = (ymax-ymin);
+ d = (int)(sqrt(dx*dx + dy*dy));
+ K = d / 8;
+ if (K < 8) K = 8;
+ return K;
+}
+
+static cdPoint* sPolyAddBezier(cdCanvas* canvas, cdPoint* poly, int *n, cdPoint start, const cdPoint* points)
+{
+ int k, K, new_n, i;
+ cdfPoint pt;
+ cdfPoint bezier_control[4];
+ cdPoint* old_poly = poly;
+
+ sBezierForm(start, points, bezier_control);
+ K = sBezierNumSegments(canvas, start, points);
+
+ new_n = *n + K+1; /* add room for K+1 samples */
+ poly = realloc(poly, sizeof(cdPoint)*new_n);
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
+
+ /* first segment */
+ sBezierCurve(bezier_control, &pt, 0);
+
+ poly[i].x = _cdRound(pt.x);
+ poly[i].y = _cdRound(pt.y);
+
+ for(k = 1; k < K+1; k++)
+ {
+ sBezierCurve(bezier_control, &pt, (double)k/(double)K);
+
+ poly[i+k].x = _cdRound(pt.x);
+ poly[i+k].y = _cdRound(pt.y);
+ }
+
+ *n = new_n;
+ return poly;
+}
+
+static cdfPoint* sPolyFAddBezier(cdCanvas* canvas, cdfPoint* poly, int *n, cdfPoint start, const cdPoint* points)
+{
+ int k, K, new_n, i;
+ cdfPoint pt;
+ cdfPoint bezier_control[4], bezier[3];
+ cdfPoint* old_poly = poly;
+
+ bezier[0].x = points[0].x; bezier[1].x = points[1].x; bezier[2].x = points[2].x;
+ bezier[0].y = points[0].y; bezier[1].y = points[1].y; bezier[2].y = points[2].y;
+
+ sfBezierForm(start, bezier, bezier_control);
+ K = sfBezierNumSegments(canvas, start, bezier);
+
+ new_n = *n + K+1; /* add room for K+1 samples */
+ poly = realloc(poly, sizeof(cdfPoint)*new_n);
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
+
+ /* first segment */
+ sBezierCurve(bezier_control, &pt, 0);
+
+ poly[i] = pt;
+
+ for(k = 1; k < K+1; k++)
+ {
+ sBezierCurve(bezier_control, &pt, (double)k/(double)K);
+ poly[i+k] = pt;
+ }
+
+ *n = new_n;
+ return poly;
+}
+
+static cdfPoint* sfPolyAddBezier(cdCanvas* canvas, cdfPoint* poly, int *n, cdfPoint start, const cdfPoint* points)
+{
+ int k, K, new_n, i;
+ cdfPoint pt;
+ cdfPoint bezier_control[4];
+ cdfPoint* old_poly = poly;
+
+ sfBezierForm(start, points, bezier_control);
+ K = sfBezierNumSegments(canvas, start, points);
+
+ new_n = *n + K+1; /* add room for K+1 samples */
+ poly = realloc(poly, sizeof(cdfPoint)*new_n);
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
+
+ /* first segment */
+ sBezierCurve(bezier_control, &pt, 0);
+
+ poly[i] = pt;
+
+ for(k = 1; k < K+1; k++)
+ {
+ sBezierCurve(bezier_control, &pt, (double)k/(double)K);
+ poly[i+k] = pt;
+ }
+
+ *n = new_n;
+ return poly;
+}
+
+static void sPolyFBezier(cdCanvas* canvas, const cdPoint* points, int n)
+{
+ int i = 0, poly_n = 0;
+ cdfPoint* fpoly = NULL, start;
+
+ start.x = points[0].x;
+ start.y = points[0].y;
+
+ n--; /* first n is 4 */
+ while (n >= 3)
+ {
+ fpoly = sPolyFAddBezier(canvas, fpoly, &poly_n, start, points+i+1);
+ start = fpoly[poly_n-1];
+ n -= 3; i += 3;
+ }
+
+ if (fpoly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, fpoly, poly_n);
+ free(fpoly);
+ }
+}
+
+void cdSimPolyBezier(cdCanvas* canvas, const cdPoint* points, int n)
+{
+ int i = 0, poly_n = 0;
+ cdPoint* poly = NULL;
+
+ if (canvas->line_width == 1 && canvas->cxFPoly)
+ {
+ sPolyFBezier(canvas, points, n);
+ return;
+ }
+
+ n--; /* first n is 4 */
+ while (n >= 3)
+ {
+ poly = sPolyAddBezier(canvas, poly, &poly_n, points[i], points+i+1);
+ if (!poly) return;
+ n -= 3; i += 3;
+ }
+
+ if (poly)
+ {
+ cdCanvasPoly(canvas, CD_OPEN_LINES, poly, poly_n);
+ free(poly);
+ }
+}
+
+void cdfSimPolyBezier(cdCanvas* canvas, const cdfPoint* points, int n)
+{
+ /* can be used only by drivers that implement cxFPoly */
+ int i = 0, poly_n = 0;
+ cdfPoint* poly = NULL;
+
+ n--; /* first n is 4 */
+ while (n >= 3)
+ {
+ poly = sfPolyAddBezier(canvas, poly, &poly_n, points[i], points+i+1);
+ n -= 3; i += 3;
+ }
+
+ if (poly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, poly, poly_n);
+ free(poly);
+ }
+}
+
+static cdPoint* sPolyAddLine(cdPoint* poly, int *n, cdPoint p1, cdPoint p2)
+{
+ int new_n, i;
+ cdPoint* old_poly = poly;
+
+ new_n = *n + 2;
+ poly = realloc(poly, sizeof(cdPoint)*new_n);
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
+
+ poly[i] = p1;
+ poly[i+1] = p2;
+
+ *n = new_n;
+ return poly;
+}
+
+static cdfPoint* sfPolyAddLine(cdfPoint* poly, int *n, cdfPoint p1, cdfPoint p2)
+{
+ int new_n, i;
+ cdfPoint* old_poly = poly;
+
+ new_n = *n + 2;
+ poly = realloc(poly, sizeof(cdfPoint)*new_n);
+ if (!poly) {free(old_poly); return NULL;}
+ i = *n;
+
+ poly[i] = p1;
+ poly[i+1] = p2;
+
+ *n = new_n;
+ return poly;
+}
+
+void cdfSimPolyPath(cdCanvas* canvas, const cdfPoint* poly, int n)
+{
+ int p, i, current_set = 0, path_poly_n;
+ cdfPoint current;
+ cdfPoint* path_poly, *old_path_poly;
+
+ current.x = 0;
+ current.y = 0;
+ current_set = 0;
+
+ /* starts a new path */
+ path_poly = NULL;
+ path_poly_n = 0;
+
+ i = 0;
+ for (p=0; p<canvas->path_n; p++)
+ {
+ switch(canvas->path[p])
{
- /* add center */
- poly[p].x = xc;
- poly[p].y = yc;
+ case CD_PATH_NEW:
+ if (path_poly)
+ free(path_poly);
+ path_poly = NULL;
+ path_poly_n = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current = poly[i];
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ path_poly = sfPolyAddLine(path_poly, &path_poly_n, current, poly[i]);
+ current = poly[i];
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ 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, &current);
+ else
+ path_poly = sfPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, NULL);
+
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current.x = poly[i].x;
+ current.y = poly[i].y;
+ }
+ path_poly = sfPolyAddBezier(canvas, path_poly, &path_poly_n, current, poly+i);
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ if (path_poly[path_poly_n-1].x != path_poly[0].x ||
+ path_poly[path_poly_n-1].y != path_poly[0].y)
+ {
+ path_poly_n++;
+ old_path_poly = path_poly;
+ path_poly = (cdfPoint*)realloc(path_poly, sizeof(cdfPoint)*path_poly_n);
+ if (!path_poly) {free(old_path_poly); return;}
+
+ /* add initial point */
+ path_poly[path_poly_n-1].x = path_poly[0].x;
+ path_poly[path_poly_n-1].y = path_poly[0].y;
+ }
+ break;
+ case CD_PATH_FILL:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
+ break;
+ case CD_PATH_STROKE:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ break;
+ case CD_PATH_FILLSTROKE:
+ if (poly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ }
+ break;
+ case CD_PATH_CLIP:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_CLIP, path_poly, path_poly_n);
+ break;
}
- else /* cdChord */
+ }
+
+ if (path_poly)
+ free(path_poly);
+}
+
+static void sSimPolyFPath(cdCanvas* canvas, const cdPoint* poly, int n)
+{
+ int p, i, current_set = 0, path_poly_n;
+ cdfPoint current, pt;
+ cdfPoint* path_poly, *old_path_poly;
+
+ current.x = 0;
+ current.y = 0;
+ current_set = 0;
+
+ /* starts a new path */
+ path_poly = NULL;
+ path_poly_n = 0;
+
+ i = 0;
+ for (p=0; p<canvas->path_n; p++)
+ {
+ switch(canvas->path[p])
{
- /* add initial point */
- poly[p].x = poly[0].x;
- poly[p].y = poly[0].y;
+ case CD_PATH_NEW:
+ if (path_poly)
+ free(path_poly);
+ path_poly = NULL;
+ path_poly_n = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current.x = poly[i].x;
+ current.y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ pt.x = poly[i].x;
+ pt.y = poly[i].y;
+ path_poly = sfPolyAddLine(path_poly, &path_poly_n, current, pt);
+ current.x = poly[i].x;
+ current.y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ 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, &current);
+ else
+ path_poly = sfPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, NULL);
+
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current.x = poly[i].x;
+ current.y = poly[i].y;
+ }
+ path_poly = sPolyFAddBezier(canvas, path_poly, &path_poly_n, current, poly+i);
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ if (path_poly[path_poly_n-1].x != path_poly[0].x ||
+ path_poly[path_poly_n-1].y != path_poly[0].y)
+ {
+ path_poly_n++;
+ old_path_poly = path_poly;
+ path_poly = (cdfPoint*)realloc(path_poly, sizeof(cdfPoint)*path_poly_n);
+ if (!path_poly) {free(old_path_poly); return;}
+
+ /* add initial point */
+ path_poly[path_poly_n-1].x = path_poly[0].x;
+ path_poly[path_poly_n-1].y = path_poly[0].y;
+ }
+ break;
+ case CD_PATH_FILL:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
+ break;
+ case CD_PATH_STROKE:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ break;
+ case CD_PATH_FILLSTROKE:
+ if (poly)
+ {
+ canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, path_poly, path_poly_n);
+ canvas->cxFPoly(canvas->ctxcanvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ }
+ break;
+ case CD_PATH_CLIP:
+ if (poly)
+ canvas->cxFPoly(canvas->ctxcanvas, CD_CLIP, path_poly, path_poly_n);
+ break;
}
- p++;
}
- canvas->cxPoly(canvas->ctxcanvas, CD_FILL, poly, p);
-
- free(poly);
+ if (path_poly)
+ free(path_poly);
}
-void cdsectorSIM(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
+void cdSimPolyPath(cdCanvas* canvas, const cdPoint* poly, int n)
{
- cdSimElipse(ctxcanvas, xc, yc, width, height, angle1, angle2, 1);
+ int p, i, current_set = 0, path_poly_n;
+ cdPoint current;
+ cdPoint* path_poly, *old_path_poly;
+
+ if (canvas->line_width == 1 && canvas->cxFPoly)
+ {
+ int has_curve = 0;
+ for (p=0; p<canvas->path_n; p++)
+ {
+ if (canvas->path[p] == CD_PATH_ARC ||
+ canvas->path[p] == CD_PATH_CURVETO)
+ has_curve = 1;
+ if (canvas->path[p] == CD_PATH_STROKE &&
+ has_curve == 1)
+ {
+ sSimPolyFPath(canvas, poly, n);
+ return;
+ }
+ }
+ }
+
+ current.x = 0;
+ current.y = 0;
+ current_set = 0;
+
+ /* starts a new path */
+ path_poly = NULL;
+ path_poly_n = 0;
+
+ i = 0;
+ for (p=0; p<canvas->path_n; p++)
+ {
+ switch(canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ if (path_poly)
+ free(path_poly);
+ path_poly = NULL;
+ path_poly_n = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current = poly[i];
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ path_poly = sPolyAddLine(path_poly, &path_poly_n, current, poly[i]);
+ if (!path_poly) return;
+ current = poly[i];
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ 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, &current);
+ else
+ path_poly = sPolyAddArc(canvas, path_poly, &path_poly_n, xc, yc, w, h, a1, a2, NULL);
+ if (!path_poly) return;
+
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current.x = poly[i].x;
+ current.y = poly[i].y;
+ }
+ path_poly = sPolyAddBezier(canvas, path_poly, &path_poly_n, current, poly+i);
+ if (!path_poly) return;
+ current = path_poly[path_poly_n-1];
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ if (path_poly[path_poly_n-1].x != path_poly[0].x ||
+ path_poly[path_poly_n-1].y != path_poly[0].y)
+ {
+ path_poly_n++;
+ old_path_poly = path_poly;
+ path_poly = (cdPoint*)realloc(path_poly, sizeof(cdPoint)*path_poly_n);
+ if (!path_poly) {free(old_path_poly); return;}
+
+ /* add initial point */
+ path_poly[path_poly_n-1].x = path_poly[0].x;
+ path_poly[path_poly_n-1].y = path_poly[0].y;
+ }
+ break;
+ case CD_PATH_FILL:
+ if (poly)
+ cdCanvasPoly(canvas, CD_FILL, path_poly, path_poly_n);
+ break;
+ case CD_PATH_STROKE:
+ if (poly)
+ cdCanvasPoly(canvas, CD_OPEN_LINES, path_poly, path_poly_n);
+ break;
+ case CD_PATH_FILLSTROKE:
+ if (poly)
+ {
+ 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)
+ cdCanvasPoly(canvas, CD_CLIP, path_poly, path_poly_n);
+ break;
+ }
+ }
+
+ if (path_poly)
+ free(path_poly);
}
-void cdchordSIM(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2)
+/************************************************************************/
+
+/* 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)
{
- cdSimElipse(ctxcanvas, xc, yc, width, height, angle1, angle2, 0);
+ cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
+
+ switch(mode)
+ {
+ case CD_CLOSED_LINES:
+ poly[n] = poly[0]; /* can do that because poly is internal of the CD */
+ n++;
+ /* continue */
+ case CD_OPEN_LINES:
+ cdSimPolyLine(canvas, poly, n);
+ break;
+ case CD_BEZIER:
+ cdSimPolyBezier(canvas, poly, n);
+ break;
+ case CD_PATH:
+ cdSimPolyPath(canvas, poly, n);
+ break;
+ case CD_FILL:
+ cdSimPolyFill(canvas, poly, n);
+ break;
+ }
}
-void cdpolySIM(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
+void cdfSimPoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
{
cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
- int i, reset = 1;
switch(mode)
{
case CD_CLOSED_LINES:
- poly[n] = poly[0];
+ fpoly[n] = fpoly[0];
n++;
/* continue */
case CD_OPEN_LINES:
- if (simLineStyleNoReset) /* Bezier simulation use several poly */
- {
- reset = 0;
- simLineStyleNoReset = 1;
- }
- for (i = 0; i< n - 1; i++)
- canvas->cxLine(canvas->ctxcanvas, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y);
- if (reset) simLineStyleNoReset = 0;
+ cdfSimPolyLine(canvas, fpoly, n);
break;
case CD_BEZIER:
- simLineStyleNoReset = 1;
- cdSimPolyBezier(canvas, poly, n);
- simLineStyleNoReset = 0;
+ cdfSimPolyBezier(canvas, fpoly, n);
+ break;
+ case CD_PATH:
+ cdfSimPolyPath(canvas, fpoly, n);
break;
+ case CD_CLIP:
case CD_FILL:
{
- /* must set line attributes here, because fill simulation use cxLine */
- int oldwidth = cdCanvasLineWidth(canvas, 1);
- int oldstyle = cdCanvasLineStyle(canvas, CD_CONTINUOUS);
- int old_use_matrix = canvas->use_matrix;
+ cdPoint* poly = malloc(sizeof(cdPoint)*n);
+ int i;
- if (canvas->use_matrix && !canvas->invert_yaxis)
+ for (i = 0; i<n; i++)
{
- for(i = 0; i < n; i++)
- cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
+ poly[i].x = _cdRound(fpoly[i].x);
+ poly[i].y = _cdRound(fpoly[i].y);
}
- /* must disable transformation here, because line simulation use cxPixel */
- canvas->use_matrix = 0;
+ cdCanvasPoly(canvas, mode, poly, n);
- simPolyFill(canvas->simulation, poly, n);
+ free(poly);
+ }
+ break;
+ }
+}
- canvas->use_matrix = old_use_matrix;
- cdCanvasLineStyle(canvas, oldstyle);
- cdCanvasLineWidth(canvas, oldwidth);
+void cdSimMark(cdCanvas* canvas, int x, int y)
+{
+ int oldinteriorstyle = canvas->interior_style;
+ int oldlinestyle = canvas->line_style;
+ int oldlinewidth = canvas->line_width;
+ int size = canvas->mark_size;
+ int half_size = size/2;
+ int bottom = y-half_size;
+ int top = y+half_size;
+ int left = x-half_size;
+ int right = x+half_size;
+
+ if (canvas->interior_style != CD_SOLID &&
+ (canvas->mark_type == CD_CIRCLE ||
+ canvas->mark_type == CD_BOX ||
+ canvas->mark_type == CD_DIAMOND))
+ cdCanvasInteriorStyle(canvas, CD_SOLID);
+
+ if (canvas->line_style != CD_CONTINUOUS &&
+ (canvas->mark_type == CD_STAR ||
+ canvas->mark_type == CD_PLUS ||
+ canvas->mark_type == CD_X ||
+ canvas->mark_type == CD_HOLLOW_BOX ||
+ canvas->mark_type == CD_HOLLOW_CIRCLE ||
+ canvas->mark_type == CD_HOLLOW_DIAMOND))
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+
+ if (canvas->line_width != 1 &&
+ (canvas->mark_type == CD_STAR ||
+ canvas->mark_type == CD_PLUS ||
+ canvas->mark_type == CD_X ||
+ canvas->mark_type == CD_HOLLOW_BOX ||
+ canvas->mark_type == CD_HOLLOW_CIRCLE ||
+ canvas->mark_type == CD_HOLLOW_DIAMOND))
+ cdCanvasLineWidth(canvas, 1);
+
+ switch (canvas->mark_type)
+ {
+ case CD_STAR:
+ canvas->cxLine(canvas->ctxcanvas, left, bottom, right, top);
+ canvas->cxLine(canvas->ctxcanvas, left, top, right, bottom);
+ /* continue */
+ case CD_PLUS:
+ canvas->cxLine(canvas->ctxcanvas, left, y, right, y);
+ canvas->cxLine(canvas->ctxcanvas, x, bottom, x, top);
+ break;
+ case CD_X:
+ canvas->cxLine(canvas->ctxcanvas, left, bottom, right, top);
+ canvas->cxLine(canvas->ctxcanvas, left, top, right, bottom);
+ break;
+ case CD_HOLLOW_CIRCLE:
+ canvas->cxArc(canvas->ctxcanvas, x, y, size, size, 0, 360);
+ break;
+ case CD_HOLLOW_BOX:
+ canvas->cxRect(canvas->ctxcanvas, left, right, bottom, top);
+ break;
+ case CD_CIRCLE:
+ canvas->cxSector(canvas->ctxcanvas, x, y, size, size, 0, 360);
+ break;
+ case CD_BOX:
+ canvas->cxBox(canvas->ctxcanvas, left, right, bottom, top);
+ break;
+ case CD_HOLLOW_DIAMOND:
+ case CD_DIAMOND:
+ {
+ cdPoint poly[5]; /* leave room for one more point */
+ poly[0].x = left;
+ poly[0].y = y;
+ poly[1].x = x;
+ poly[1].y = top;
+ poly[2].x = right;
+ poly[2].y = y;
+ poly[3].x = x;
+ poly[3].y = bottom;
+
+ if (canvas->mark_type == CD_DIAMOND)
+ cdCanvasPoly(canvas, CD_FILL, poly, 4);
+ else
+ cdCanvasPoly(canvas, CD_CLOSED_LINES, poly, 4);
}
break;
}
+
+ if (canvas->interior_style != oldinteriorstyle &&
+ (canvas->mark_type == CD_CIRCLE ||
+ canvas->mark_type == CD_BOX ||
+ canvas->mark_type == CD_DIAMOND))
+ cdCanvasInteriorStyle(canvas, oldinteriorstyle);
+
+ if (canvas->line_style != oldlinestyle &&
+ (canvas->mark_type == CD_STAR ||
+ canvas->mark_type == CD_PLUS ||
+ canvas->mark_type == CD_X ||
+ canvas->mark_type == CD_HOLLOW_BOX ||
+ canvas->mark_type == CD_HOLLOW_CIRCLE ||
+ canvas->mark_type == CD_HOLLOW_DIAMOND))
+ cdCanvasLineStyle(canvas, oldlinestyle);
+
+ if (canvas->line_width != oldlinewidth &&
+ (canvas->mark_type == CD_STAR ||
+ canvas->mark_type == CD_PLUS ||
+ canvas->mark_type == CD_X ||
+ canvas->mark_type == CD_HOLLOW_BOX ||
+ canvas->mark_type == CD_HOLLOW_CIRCLE ||
+ canvas->mark_type == CD_HOLLOW_DIAMOND))
+ cdCanvasLineWidth(canvas, oldlinewidth);
+}
+
+void cdSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
+{
+ int size, i, j, dst, src, *fx, *fy, rw, rh;
+ unsigned char *ar, *ag, *ab, al;
+ (void)ih;
+
+ size = w * h;
+ ar = (unsigned char*)malloc(size*3);
+ if (!ar) return;
+ ag = ar + size;
+ ab = ag + size;
+
+ canvas->cxGetImageRGB(canvas->ctxcanvas, ar, ag, ab, x, y, w, h);
+
+ rw = xmax-xmin+1;
+ rh = ymax-ymin+1;
+
+ fx = cdGetZoomTable(w, rw, xmin);
+ fy = cdGetZoomTable(h, rh, ymin);
+
+ for (j = 0; j < h; j++)
+ {
+ for (i = 0; i < w; i++)
+ {
+ dst = j * w + i;
+ src = fy[j] * iw + fx[i];
+ al = a[src];
+ ar[dst] = CD_ALPHA_BLEND(r[src], ar[dst], al);
+ ag[dst] = CD_ALPHA_BLEND(g[src], ag[dst], al);
+ ab[dst] = CD_ALPHA_BLEND(b[src], ab[dst], al);
+ }
+ }
+
+ canvas->cxPutImageRectRGB(canvas->ctxcanvas, w, h, ar, ag, ab, x, y, w, h, 0, 0, 0, 0);
+
+ free(ar);
+
+ free(fx);
+ free(fy);
+}
+
+void cdSimPutImageRectRGB(cdCanvas* canvas, 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 height = ymax-ymin+1;
+ unsigned char* map;
+ int pal_size = 1L << canvas->bpp;
+ long colors[256];
+ (void)ih;
+
+ map = (unsigned char*)malloc(iw * height);
+ if (!map)
+ return;
+
+ if (pal_size == 2) /* probably a laser printer, use a gray image for better results */
+ cdRGB2Gray(iw, height, r+ymin*iw, g+ymin*iw, b+ymin*iw, map, colors);
+ else
+ cdRGB2Map(iw, height, r+ymin*iw, g+ymin*iw, b+ymin*iw, map, pal_size, colors);
+
+ canvas->cxPutImageRectMap(canvas->ctxcanvas, iw, height, map, colors, x, y, w, h, xmin, xmax, 0, height-1);
+
+ free(map);
+}
+
+
+/************************************************************************/
+
+#include "cd_truetype.h"
+#include "sim.h"
+
+static void cdSimPolyLine(cdCanvas* canvas, const cdPoint* poly, int n)
+{
+ int i, reset = 1, transform = 0;
+ int old_use_matrix = canvas->use_matrix;
+ int x1, y1, x2, y2;
+
+ if (canvas->use_matrix)
+ transform = 1;
+
+ /* disable line transformation */
+ canvas->use_matrix = 0;
+
+ /* prepare the line style for several lines */
+ if (simLineStyleNoReset)
+ {
+ reset = 0;
+ simLineStyleNoReset = 1;
+ }
+
+ x1 = poly[0].x;
+ y1 = poly[0].y;
+
+ if (transform)
+ cdMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
+
+ for (i = 0; i < n-1; i++)
+ {
+ x2 = poly[i+1].x;
+ y2 = poly[i+1].y;
+
+ if (transform)
+ cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
+
+ if(canvas->line_width > 1)
+ simLineThick(canvas, x1, y1, x2, y2);
+ else
+ simLineThin(canvas, x1, y1, x2, y2);
+
+ x1 = x2;
+ y1 = y2;
+ }
+
+ if (reset) simLineStyleNoReset = 0;
+ canvas->use_matrix = old_use_matrix;
}
+
+static void cdfSimPolyLine(cdCanvas* canvas, const cdfPoint* poly, int n)
+{
+ int i, reset = 1, transform = 0;
+ int old_use_matrix = canvas->use_matrix;
+ double x1, y1, x2, y2;
+ int last_xi_a = -65535,
+ last_yi_a = -65535,
+ last_xi_b = -65535,
+ last_yi_b = -65535;
+
+ if (canvas->use_matrix)
+ transform = 1;
+
+ /* disable line transformation */
+ canvas->use_matrix = 0;
+
+ /* prepare the line style for several lines */
+ if (simLineStyleNoReset)
+ {
+ reset = 0;
+ simLineStyleNoReset = 1;
+ }
+
+ x1 = poly[0].x;
+ y1 = poly[0].y;
+
+ if (transform)
+ cdfMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
+
+ for (i = 0; i < n-1; i++)
+ {
+ x2 = poly[i+1].x;
+ y2 = poly[i+1].y;
+
+ if (transform)
+ cdfMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
+
+ if(canvas->line_width > 1)
+ simfLineThick(canvas, x1, y1, x2, y2);
+ else
+ simfLineThin(canvas, x1, y1, x2, y2, &last_xi_a, &last_yi_a, &last_xi_b, &last_yi_b);
+
+ x1 = x2;
+ y1 = y2;
+ }
+
+ if (reset) simLineStyleNoReset = 0;
+ canvas->use_matrix = old_use_matrix;
+}
+
+static int sCheckIsBox(cdPoint* poly)
+{
+ if (poly[0].x == poly[1].x &&
+ poly[1].y == poly[2].y &&
+ poly[2].x == poly[3].x &&
+ poly[3].y == poly[0].y)
+ return 1;
+
+ if (poly[0].y == poly[1].y &&
+ poly[1].x == poly[2].x &&
+ poly[2].y == poly[3].y &&
+ poly[3].x == poly[0].x)
+ return 1;
+
+ return 0;
+}
+
+static void sGetBox(cdPoint* poly, int *xmin, int *xmax, int *ymin, int *ymax)
+{
+ int i;
+ *xmin = poly[0].x;
+ *xmax = poly[0].x;
+ *ymin = poly[0].y;
+ *ymax = poly[0].y;
+ for (i=1; i<4; i++)
+ {
+ if (poly[i].x < *xmin)
+ *xmin = poly[i].x;
+ if (poly[i].y < *ymin)
+ *ymin = poly[i].y;
+ if (poly[i].x > *xmax)
+ *xmax = poly[i].x;
+ if (poly[i].y > *ymin)
+ *ymax = poly[i].y;
+ }
+}
+
+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, and it will NOT be stored */
+ cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
+ }
+
+ /* disable fill transformation */
+ canvas->use_matrix = 0;
+
+ if (n == 4 && sCheckIsBox(poly))
+ {
+ int xmin, xmax, ymin, ymax;
+ sGetBox(poly, &xmin, &xmax, &ymin, &ymax);
+ simFillHorizBox(canvas->simulation, xmin, xmax, ymin, ymax);
+ }
+ else
+ simPolyFill(canvas->simulation, poly, n);
+
+ canvas->use_matrix = old_use_matrix;
+}
+
diff --git a/cd/src/sim/truetype.h b/cd/src/sim/truetype.h
deleted file mode 100755
index 5675998..0000000
--- a/cd/src/sim/truetype.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/** \file
- * \brief Text and Font Simulation using FreeType library.
- *
- * See Copyright Notice in cd.h
- */
-
-#ifndef __TRUETYPE_H
-#define __TRUETYPE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ft2build.h"
-#include FT_FREETYPE_H
-
-/*
- In CD version 4.4 we start to use FreeType 2.
- Only TrueType font support is enabled.
-*/
-
-typedef struct _cdTT_Text
-{
- FT_Library library;
- FT_Face face;
-
- unsigned char* rgba_data;
- int rgba_data_size;
-
- int max_height;
- int max_width;
- int descent;
- int ascent;
-
-}cdTT_Text;
-
-cdTT_Text* cdTT_create(void);
-void cdTT_free(cdTT_Text * tt_text);
-int cdTT_load(cdTT_Text * tt_text, const char *font,int size, double xres, double yres);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ifndef _CD_TRUETYPE_ */
-
diff --git a/cd/src/svg/cdsvg.c b/cd/src/svg/cdsvg.c
index 184031c..0510919 100644
--- a/cd/src/svg/cdsvg.c
+++ b/cd/src/svg/cdsvg.c
@@ -19,37 +19,33 @@
#include "lodepng.h"
#include "base64.h"
+
struct _cdCtxCanvas
{
cdCanvas* canvas;
- char* filename;
char bgColor[20];
char fgColor[20];
- char linecap[10];
- char linejoin[10];
- char linestyle[20];
- char poly[256];
- char pattern[30];
-
- char font_weight[15];
- char font_style[15];
- char font_decoration[15];
+ char* linecap;
+ char* linejoin;
+ char linestyle[50];
+ char pattern[50];
+
+ char* font_weight;
+ char* font_style;
+ char* font_decoration;
char font_family[256];
char font_size[10];
- int backopacity;
- int writemode;
- int linewidth;
+ double opacity;
int hatchboxsize;
- double xmatrix[6]; /* Transformation matrix that includes axis inversion */
-
/* private */
int last_fill_mode;
- int last_clip_path;
- int clip_off_control;
+ int last_clip_poly;
+ int last_clip_rect;
+ int clip_control;
int clip_polygon;
int transform_control;
@@ -57,100 +53,85 @@ struct _cdCtxCanvas
FILE* file;
};
+static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix);
+
static void cdkillcanvas(cdCtxCanvas* ctxcanvas)
{
- while(ctxcanvas->clip_off_control > 0)
- {
- fprintf(ctxcanvas->file, "</g>\n");
- --ctxcanvas->clip_off_control;
- }
+ if (ctxcanvas->clip_control)
+ fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */
- if(ctxcanvas->transform_control)
- fprintf(ctxcanvas->file, "</g>\n");
+ if (ctxcanvas->transform_control)
+ fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */
- fprintf(ctxcanvas->file, "</g>\n");
+ fprintf(ctxcanvas->file, "</g>\n"); /* close global container */
fprintf(ctxcanvas->file, "</svg>\n");
- free(ctxcanvas->filename);
fclose(ctxcanvas->file);
memset(ctxcanvas, 0, sizeof(cdCtxCanvas));
free(ctxcanvas);
}
-static void setclip_area(cdCtxCanvas *ctxcanvas)
+static int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode)
{
- cdRect* clip_rect = &ctxcanvas->canvas->clip_rect;
-
- fprintf(ctxcanvas->file, "<clipPath id=\"clippath%d\">\n", ++ctxcanvas->last_clip_path);
-
- if (ctxcanvas->canvas->use_matrix)
- {
- cdPoint poly[4];
- poly[0].x = clip_rect->xmin; poly[0].y = clip_rect->ymin;
- poly[1].x = clip_rect->xmin; poly[1].y = clip_rect->ymax;
- poly[2].x = clip_rect->xmax; poly[2].y = clip_rect->ymax;
- poly[3].x = clip_rect->xmax; poly[3].y = clip_rect->ymin;
-
- sprintf(ctxcanvas->poly, "%g,%g", (double)poly[0].x, (double)poly[0].y);
- sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[1].x, (double)poly[1].y);
- sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[2].x, (double)poly[2].y);
- sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, (double)poly[3].x, (double)poly[3].y);
-
- fprintf(ctxcanvas->file, "<polygon points=\"%s\" />\n", ctxcanvas->poly);
- }
- else
+ if (ctxcanvas->clip_control)
{
- double x, y, w, h;
- x = (double)clip_rect->xmin;
- y = (double)clip_rect->ymin;
- w = (double)(clip_rect->xmax - clip_rect->xmin + 1);
- h = (double)(clip_rect->ymax - clip_rect->ymin + 1);
-
- fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" />\n", x, y, w, h);
- }
+ int old_transform_control = ctxcanvas->transform_control;
+ if (ctxcanvas->transform_control)
+ {
+ fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */
+ ctxcanvas->transform_control = 0;
+ }
- fprintf(ctxcanvas->file, "</clipPath>\n");
+ fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */
+ ctxcanvas->clip_control = 0;
- fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippath%d)\">\n", ctxcanvas->last_clip_path);
- ++ctxcanvas->clip_off_control;
-}
+ if (old_transform_control)
+ cdtransform(ctxcanvas, ctxcanvas->canvas->matrix); /* reopen transform container */
+ }
-int cdclip(cdCtxCanvas *ctxcanvas, int clip_mode)
-{
switch (clip_mode)
{
- case CD_CLIPOFF:
- if(ctxcanvas->clip_off_control > 0)
- {
- fprintf(ctxcanvas->file, "</g>\n");
- --ctxcanvas->clip_off_control;
- }
- break;
case CD_CLIPAREA:
- setclip_area(ctxcanvas);
+ /* open clipping container */
+ fprintf(ctxcanvas->file, "<g clip-path=\"url(#cliprect%d)\">\n", ctxcanvas->last_clip_rect);
+ ctxcanvas->clip_control = 1;
break;
case CD_CLIPPOLYGON:
if (ctxcanvas->clip_polygon)
{
- fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippath%d)\">\n", ctxcanvas->last_clip_path);
- ++ctxcanvas->clip_off_control;
+ /* open clipping container */
+ fprintf(ctxcanvas->file, "<g clip-path=\"url(#clippoly%d)\" clip-rule:%s >\n", ctxcanvas->last_clip_poly, (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero");
+ ctxcanvas->clip_control = 1;
}
break;
}
+
return clip_mode;
}
static void cdfcliparea(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
+ double x, y, w, h;
+
+ ctxcanvas->canvas->clip_rect.xmin = (int)xmin;
+ ctxcanvas->canvas->clip_rect.ymin = (int)ymin;
+ ctxcanvas->canvas->clip_rect.xmax = (int)xmax;
+ ctxcanvas->canvas->clip_rect.ymax = (int)ymax;
+
+ x = xmin;
+ y = ymin;
+ w = xmax - xmin + 1;
+ h = ymax - ymin + 1;
+
+ fprintf(ctxcanvas->file, "<clipPath id=\"cliprect%d\">\n", ++ctxcanvas->last_clip_rect);
+
+ fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" />\n", x, y, w, h);
+
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+
if (ctxcanvas->canvas->clip_mode == CD_CLIPAREA)
- {
- ctxcanvas->canvas->clip_rect.xmin = (int)xmin;
- ctxcanvas->canvas->clip_rect.ymin = (int)ymin;
- ctxcanvas->canvas->clip_rect.xmax = (int)xmax;
- ctxcanvas->canvas->clip_rect.ymax = (int)ymax;
cdclip(ctxcanvas, CD_CLIPAREA);
- }
}
static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
@@ -160,39 +141,51 @@ static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int
static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
{
- if (matrix)
+ if (ctxcanvas->transform_control)
{
- /* Matrix identity */
- ctxcanvas->xmatrix[0] = 1;
- ctxcanvas->xmatrix[1] = 0;
- ctxcanvas->xmatrix[2] = 0;
- ctxcanvas->xmatrix[3] = -1;
- ctxcanvas->xmatrix[4] = 0;
- ctxcanvas->xmatrix[5] = (ctxcanvas->canvas->h-1);
-
- if(ctxcanvas->transform_control)
+ int old_clip_control = ctxcanvas->clip_control;
+ if (ctxcanvas->clip_control)
{
- fprintf(ctxcanvas->file, "</g>\n");
- --ctxcanvas->transform_control;
+ fprintf(ctxcanvas->file, "</g>\n"); /* close clipping container */
+ ctxcanvas->clip_control = 0;
}
- cdMatrixMultiply(matrix, ctxcanvas->xmatrix);
+ fprintf(ctxcanvas->file, "</g>\n"); /* close transform container */
+ ctxcanvas->transform_control = 0;
+
+ if (old_clip_control)
+ cdclip(ctxcanvas, ctxcanvas->canvas->clip_mode); /* reopen clipping container */
+ }
- ++ctxcanvas->transform_control;
- fprintf(ctxcanvas->file, "<g transform=\"matrix(%g %g %g %g %g %g)\">\n", ctxcanvas->xmatrix[0], ctxcanvas->xmatrix[1], ctxcanvas->xmatrix[2], ctxcanvas->xmatrix[3], ctxcanvas->xmatrix[4], ctxcanvas->xmatrix[5]);
+ if (matrix)
+ {
+ double xmatrix[6];
+
+ /* Matrix identity + invert axis */
+ xmatrix[0] = 1;
+ xmatrix[1] = 0;
+ xmatrix[2] = 0;
+ xmatrix[3] = -1;
+ xmatrix[4] = 0;
+ xmatrix[5] = (ctxcanvas->canvas->h-1);
+
+ /* compose transform */
+ cdMatrixMultiply(matrix, xmatrix);
+
+ /* open transform container */
+ fprintf(ctxcanvas->file, "<g transform=\"matrix(%g %g %g %g %g %g)\">\n", xmatrix[0], xmatrix[1], xmatrix[2], xmatrix[3], xmatrix[4], xmatrix[5]);
+ ctxcanvas->transform_control = 1;
ctxcanvas->canvas->invert_yaxis = 0;
}
else
- {
ctxcanvas->canvas->invert_yaxis = 1;
- }
}
static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2)
{
- fprintf(ctxcanvas->file, "<line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- x1, y1, x2, y2, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ x1, y1, x2, y2, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
}
static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
@@ -202,8 +195,8 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- xmin, ymin, xmax-xmin, ymax-ymin, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ xmin, ymin, xmax-xmin, ymax-ymin, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
}
static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
@@ -213,9 +206,8 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma
static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- xmin, ymin, xmax-xmin, ymax-ymin, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern,
- (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; stroke:none; opacity:%g\" />\n",
+ xmin, ymin, xmax-xmin, ymax-ymin, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
}
static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
@@ -223,36 +215,51 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
}
+static void sCalcArc(cdCanvas* canvas, double xc, double yc, double w, double h, double a1, double a2, double *arcStartX, double *arcStartY, double *arcEndX, double *arcEndY, int *largeArc, int swap)
+{
+ /* computation is done as if the angles are counterclockwise,
+ and yaxis is NOT inverted. */
+
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, arcStartX, arcStartY, arcEndX, arcEndY);
+
+ if (canvas->invert_yaxis)
+ {
+ /* fix axis orientation */
+ *arcStartY = 2*yc - *arcStartY;
+ *arcEndY = 2*yc - *arcEndY;
+ }
+ else
+ {
+ /* it is clock-wise when axis NOT inverted */
+ if (swap)
+ {
+ _cdSwapDouble(*arcStartX, *arcEndX);
+ _cdSwapDouble(*arcStartY, *arcEndY);
+ }
+ }
+
+ if (fabs(a2-a1) > 180.0)
+ *largeArc = 1;
+ else
+ *largeArc = 0;
+}
+
static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
+ int largeArc;
if((a1 == 0.0) && (a2 == 360.0)) /* an ellipse/circle */
{
- fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- xc, yc, w/2, h/2, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
-
+ fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ xc, yc, w/2, h/2, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
return;
}
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
-
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
-
- if((a2-a1) > 180.0)
- largeArc = 1;
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 1);
- fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
}
static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
@@ -263,35 +270,19 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
+ int largeArc;
if((a1 == 0.0) && (a2 == 360.0)) /* an ellipse/circle */
{
- fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- xc, yc, w/2, h/2, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern,
- (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
-
+ fprintf(ctxcanvas->file, "<ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" style=\"fill:%s; stroke:none; opacity:%g\" />\n",
+ xc, yc, w/2, h/2, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
return;
}
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
-
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
-
- if((a2-a1) > 180.0)
- largeArc = 1;
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 1);
- fprintf(ctxcanvas->file, "<path d=\"M%g,%g L%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- xc, yc, arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern,
- (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<path d=\"M%g,%g L%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:none; opacity:%g\" />\n",
+ xc, yc, arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
}
static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
@@ -302,26 +293,12 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
{
double arcStartX, arcStartY, arcEndX, arcEndY;
- int largeArc = 0;
-
- if (ctxcanvas->canvas->use_matrix) /* Transformation active */
- {
- double temp = 360 - a1;
- a1 = 360 - a2;
- a2 = temp;
- }
+ int largeArc;
- arcStartX = (xc+(w/2)*cos(a1*CD_DEG2RAD));
- arcStartY = (yc-(h/2)*sin(a1*CD_DEG2RAD));
- arcEndX = (xc+(w/2)*cos(a2*CD_DEG2RAD));
- arcEndY = (yc-(h/2)*sin(a2*CD_DEG2RAD));
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 1);
- if((a2-a1) > 180.0)
- largeArc = 1;
-
- fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern,
- (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none", ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<path d=\"M%g,%g A%g,%g 0 %d,0 %g,%g Z\" style=\"fill:%s; stroke:none; opacity:%g\" />\n",
+ arcStartX, arcStartY, w/2, h/2, largeArc, arcEndX, arcEndY, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, ctxcanvas->opacity);
}
static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
@@ -331,8 +308,8 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text, int len)
{
- char anchor[10];
- char alignment[20];
+ char* anchor;
+ char* alignment;
int i;
switch (ctxcanvas->canvas->text_alignment)
@@ -340,22 +317,23 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text
case CD_NORTH:
case CD_NORTH_EAST:
case CD_NORTH_WEST:
- sprintf(alignment, "%s", "text-before-edge");
+ alignment = "text-before-edge";
break;
case CD_SOUTH:
case CD_SOUTH_EAST:
case CD_SOUTH_WEST:
- sprintf(alignment, "%s", "text-after-edge");
+ alignment = "text-after-edge";
break;
case CD_CENTER:
case CD_EAST:
case CD_WEST:
- sprintf(alignment, "%s", "middle");
+ alignment = "middle";
break;
case CD_BASE_CENTER:
case CD_BASE_LEFT:
case CD_BASE_RIGHT:
- sprintf(alignment, "%s", "baseline");
+ default:
+ alignment = "baseline";
break;
}
@@ -365,19 +343,20 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text
case CD_NORTH_WEST:
case CD_SOUTH_WEST:
case CD_BASE_LEFT:
- sprintf(anchor, "%s", "start");
+ anchor = "start";
break;
case CD_CENTER:
case CD_NORTH:
case CD_SOUTH:
case CD_BASE_CENTER:
- sprintf(anchor, "%s", "middle");
+ anchor = "middle";
break;
case CD_EAST:
case CD_NORTH_EAST:
case CD_SOUTH_EAST:
case CD_BASE_RIGHT:
- sprintf(anchor, "%s", "end");
+ default:
+ anchor = "end";
break;
}
@@ -392,10 +371,10 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text
if (ctxcanvas->canvas->use_matrix) /* Transformation active */
fprintf(ctxcanvas->file, "<text transform=\"matrix(%g %g %g %g %g %g)\" font-family=\"%s\" font-size=\"%s\" font-style=\"%s\" font-weight=\"%s\" text-decoration=\"%s\" text-anchor=\"%s\" dominant-baseline=\"%s\" fill=\"%s\">\n",
- text_cos, text_sin, text_sin, -text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor);
+ text_cos, text_sin, text_sin, -text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor);
else
fprintf(ctxcanvas->file, "<text transform=\"matrix(%g %g %g %g %g %g)\" font-family=\"%s\" font-size=\"%s\" font-style=\"%s\" font-weight=\"%s\" text-decoration=\"%s\" text-anchor=\"%s\" dominant-baseline=\"%s\" fill=\"%s\">\n",
- text_cos, -text_sin, text_sin, text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor);
+ text_cos, -text_sin, text_sin, text_cos, x, y, ctxcanvas->font_family, ctxcanvas->font_size, ctxcanvas->font_style, ctxcanvas->font_weight, ctxcanvas->font_decoration, anchor, alignment, ctxcanvas->fgColor);
for(i = 0; i < len; i++)
fprintf(ctxcanvas->file, "&#x%02X;", (unsigned char)text[i]);
@@ -419,46 +398,178 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text, int l
cdftext(ctxcanvas, (double)x, (double)y, text, len);
}
+static void sWritePointsF(cdCtxCanvas *ctxcanvas, cdfPoint* poly, int n, int close)
+{
+ int i;
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%g,%g ", poly[i].x, poly[i].y);
+ if (close)
+ fprintf(ctxcanvas->file, "%g,%g ", poly[0].x, poly[0].y);
+}
+
+static void sWritePoints(cdCtxCanvas *ctxcanvas, cdPoint* poly, int n, int close)
+{
+ int i;
+ for(i = 0; i<n; i++)
+ fprintf(ctxcanvas->file, "%d,%d ", poly[i].x, poly[i].y);
+ if (close)
+ fprintf(ctxcanvas->file, "%d,%d ", poly[0].x, poly[0].y);
+}
+
static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
{
- int i, m = 0;
- char rule[8];
+ char* rule;
- if(mode == CD_BEZIER)
- m = 1;
+ if (mode == CD_PATH)
+ {
+ int i, p, clip_path = 0, end_path, current_set;
- sprintf(ctxcanvas->poly, "%g,%g", poly[m].x, poly[m].y);
- for(i = m+1; i<n; i++)
- sprintf(ctxcanvas->poly, "%s %g,%g", ctxcanvas->poly, poly[i].x, poly[i].y);
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ {
+ clip_path = 1;
+ break;
+ }
+ }
+
+ if (clip_path)
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
+
+ /* starts a new path */
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ if (!end_path)
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "M %g %g ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "L %g %g ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h, a1, a2;
+ double arcStartX, arcStartY, arcEndX, arcEndY;
+ int largeArc, sweep = 0;
+
+ if (i+3 > n) return;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 0);
+
+ if (ctxcanvas->canvas->invert_yaxis && (a2-a1)<0) /* can be clockwise */
+ sweep = 1;
+
+ if (current_set)
+ fprintf(ctxcanvas->file, "L %g %g A %g %g 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+ else
+ fprintf(ctxcanvas->file, "M %g %g A %g %g 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+
+ current_set = 1;
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "C %g %g %g %g %g %g ", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "Z ");
+ break;
+ case CD_PATH_FILL:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_STROKE:
+ fprintf(ctxcanvas->file, "\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_FILLSTROKE:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_CLIP:
+ fprintf(ctxcanvas->file, "\" />\n");
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+ ctxcanvas->clip_polygon = 1;
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ end_path = 1;
+ break;
+ }
+ }
+ return;
+ }
switch (mode)
{
- case CD_CLOSED_LINES :
- fprintf(ctxcanvas->file, "<polygon style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n",
- ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly);
+ case CD_CLOSED_LINES:
+ fprintf(ctxcanvas->file, "<polygon style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePointsF(ctxcanvas, poly, n, 1);
+ fprintf(ctxcanvas->file, "\" />\n");
break;
- case CD_OPEN_LINES :
- fprintf(ctxcanvas->file, "<polyline style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n",
- ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly);
+ case CD_OPEN_LINES:
+ fprintf(ctxcanvas->file, "<polyline style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePointsF(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
break;
- case CD_BEZIER :
- fprintf(ctxcanvas->file, "<path d=\"M%g,%g C%s\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- poly[0].x, poly[0].y, ctxcanvas->poly, ctxcanvas->fgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ case CD_BEZIER:
+ fprintf(ctxcanvas->file, "<path d=\"M%g,%g C", poly[0].x, poly[0].y);
+ sWritePointsF(ctxcanvas, poly+1, n-1, 0);
+ fprintf(ctxcanvas->file, "\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
break;
- case CD_FILL :
+ case CD_FILL:
if(ctxcanvas->canvas->fill_mode==CD_EVENODD)
- sprintf(rule, "%s", "evenodd");
+ rule = "evenodd";
else
- sprintf(rule, "%s", "nonzero");
+ rule = "nonzero";
- fprintf(ctxcanvas->file, "<polygon style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" points=\"%s\" />\n",
- (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : ctxcanvas->pattern, rule, (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor : "none",
- ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity, ctxcanvas->poly);
+ fprintf(ctxcanvas->file, "<polygon style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" points=\"",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ sWritePointsF(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
break;
case CD_CLIP:
- fprintf(ctxcanvas->file, "<clipPath id=\"clippath%d\">\n", ++ctxcanvas->last_clip_path);
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
- fprintf(ctxcanvas->file, "<polygon points=\"%s\" />\n", ctxcanvas->poly);
+ fprintf(ctxcanvas->file, "<polygon points=\"");
+ sWritePointsF(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
fprintf(ctxcanvas->file, "</clipPath>\n");
@@ -474,48 +585,193 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
- int i;
- cdfPoint* newPoly = NULL;
-
- newPoly = (cdfPoint*)malloc(sizeof(cdfPoint)*(n+1));
+ char* rule;
- for(i = 0; i < n; i++)
+ if (mode == CD_PATH)
{
- newPoly[i].x = (double)poly[i].x;
- newPoly[i].y = (double)poly[i].y;
+ int i, p, clip_path = 0, end_path, current_set;
+
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ if (ctxcanvas->canvas->path[p] == CD_PATH_CLIP)
+ {
+ clip_path = 1;
+ break;
+ }
+ }
+
+ if (clip_path)
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
+
+ /* starts a new path */
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ if (!end_path)
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "<path d=\"");
+ end_path = 0;
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "M %d %d ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ fprintf(ctxcanvas->file, "L %d %d ", poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+ double arcStartX, arcStartY, arcEndX, arcEndY;
+ int largeArc, sweep = 0;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arcStartX, &arcStartY, &arcEndX, &arcEndY, &largeArc, 0);
+
+ if (ctxcanvas->canvas->invert_yaxis && (a2-a1)<0) /* can be clockwise */
+ sweep = 1;
+
+ if (current_set)
+ fprintf(ctxcanvas->file, "L %g %g A %d %d 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+ else
+ fprintf(ctxcanvas->file, "M %g %g A %d %d 0 %d %d %g %g ",
+ arcStartX, arcStartY, w/2, h/2, largeArc, sweep, arcEndX, arcEndY);
+
+ current_set = 1;
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ fprintf(ctxcanvas->file, "C %d %d %d %d %d %d ", poly[i].x, poly[i].y,
+ poly[i+1].x, poly[i+1].y,
+ poly[i+2].x, poly[i+2].y);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ fprintf(ctxcanvas->file, "Z ");
+ break;
+ case CD_PATH_FILL:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_STROKE:
+ fprintf(ctxcanvas->file, "\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_FILLSTROKE:
+ rule = (ctxcanvas->canvas->fill_mode==CD_EVENODD)? "evenodd": "nonzero";
+ fprintf(ctxcanvas->file, "\" style=\"fill:%s; fill-rule:%s; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ end_path = 1;
+ break;
+ case CD_PATH_CLIP:
+ fprintf(ctxcanvas->file, "\" />\n");
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+ ctxcanvas->clip_polygon = 1;
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+ end_path = 1;
+ break;
+ }
+ }
+ return;
}
- cdfpoly(ctxcanvas, mode, (cdfPoint*)newPoly, n);
+ switch (mode)
+ {
+ case CD_CLOSED_LINES:
+ fprintf(ctxcanvas->file, "<polygon style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePoints(ctxcanvas, poly, n, 1);
+ fprintf(ctxcanvas->file, "\" />\n");
+ break;
+ case CD_OPEN_LINES:
+ fprintf(ctxcanvas->file, "<polyline style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" points=\"",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+ break;
+ case CD_BEZIER:
+ fprintf(ctxcanvas->file, "<path d=\"M%d,%d C", poly[0].x, poly[0].y);
+ sWritePoints(ctxcanvas, poly+1, n-1, 0);
+ fprintf(ctxcanvas->file, "\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%g\" />\n",
+ ctxcanvas->fgColor, ctxcanvas->canvas->line_width, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->opacity);
+ break;
+ case CD_FILL:
+ if(ctxcanvas->canvas->fill_mode==CD_EVENODD)
+ rule = "evenodd";
+ else
+ rule = "nonzero";
- free(newPoly);
-}
+ fprintf(ctxcanvas->file, "<polygon style=\"fill:%s; fill-rule:%s; stroke:none; opacity:%g\" points=\"",
+ (ctxcanvas->canvas->interior_style == CD_SOLID) ? ctxcanvas->fgColor: ctxcanvas->pattern, rule, ctxcanvas->opacity);
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+ break;
+ case CD_CLIP:
+ fprintf(ctxcanvas->file, "<clipPath id=\"clippoly%d\">\n", ++ctxcanvas->last_clip_poly);
-static int cdbackopacity(cdCtxCanvas *ctxcanvas, int opacity)
-{
- ctxcanvas->backopacity = opacity;
- return opacity;
+ fprintf(ctxcanvas->file, "<polygon points=\"");
+ sWritePoints(ctxcanvas, poly, n, 0);
+ fprintf(ctxcanvas->file, "\" />\n");
+
+ fprintf(ctxcanvas->file, "</clipPath>\n");
+
+ ctxcanvas->clip_polygon = 1;
+
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ cdclip(ctxcanvas, CD_CLIPPOLYGON);
+
+ break;
+
+ }
}
static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
{
switch (style)
{
- case CD_CONTINUOUS : /* empty dash */
+ case CD_CONTINUOUS: /* empty dash */
+ default:
sprintf(ctxcanvas->linestyle, "%s", "0");
break;
- case CD_DASHED :
+ case CD_DASHED:
sprintf(ctxcanvas->linestyle, "%s", "6,2");
break;
- case CD_DOTTED :
+ case CD_DOTTED:
sprintf(ctxcanvas->linestyle, "%s", "2,2");
break;
- case CD_DASH_DOT :
+ case CD_DASH_DOT:
sprintf(ctxcanvas->linestyle, "%s", "6,2,2,2");
break;
- case CD_DASH_DOT_DOT :
+ case CD_DASH_DOT_DOT:
sprintf(ctxcanvas->linestyle, "%s", "6,2,2,2,2,2");
break;
- case CD_CUSTOM :
+ case CD_CUSTOM:
{
int i;
sprintf(ctxcanvas->linestyle, "%d", ctxcanvas->canvas->line_dashes[0]);
@@ -529,34 +785,25 @@ static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style)
return style;
}
-static int cdlinewidth(cdCtxCanvas *ctxcanvas, int width)
-{
- ctxcanvas->linewidth = width;
-
- return width;
-}
-
static int cdlinecap(cdCtxCanvas *ctxcanvas, int cap)
{
if(cap == CD_CAPROUND)
- sprintf(ctxcanvas->linecap, "%s", "round");
+ ctxcanvas->linecap = "round";
else if(cap == CD_CAPSQUARE)
- sprintf(ctxcanvas->linecap, "%s", "square");
+ ctxcanvas->linecap = "square";
else /* CD_CAPFLAT */
- sprintf(ctxcanvas->linecap, "%s", "butt");
-
+ ctxcanvas->linecap = "butt";
return cap;
}
static int cdlinejoin(cdCtxCanvas *ctxcanvas, int join)
{
if(join == CD_ROUND)
- sprintf(ctxcanvas->linejoin, "%s", "round");
+ ctxcanvas->linejoin = "round";
else if(join == CD_BEVEL)
- sprintf(ctxcanvas->linejoin, "%s", "bevel");
+ ctxcanvas->linejoin = "bevel";
else /* CD_MITER */
- sprintf(ctxcanvas->linejoin, "%s", "miter");
-
+ ctxcanvas->linejoin = "miter";
return join;
}
@@ -565,39 +812,44 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
int hsize = ctxcanvas->hatchboxsize - 1;
int hhalf = hsize / 2;
- ctxcanvas->canvas->interior_style = CD_HATCH;
sprintf(ctxcanvas->pattern, "url(#pattern%d)", ++ctxcanvas->last_fill_mode);
fprintf(ctxcanvas->file, "<pattern id=\"pattern%d\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"%d\" height=\"%d\">\n", ctxcanvas->last_fill_mode, hsize, hsize);
+ if (ctxcanvas->canvas->back_opacity==CD_OPAQUE)
+ {
+ fprintf(ctxcanvas->file, "<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" style=\"fill:%s; stroke:none; opacity:%g\" />\n",
+ hsize, hsize, ctxcanvas->bgColor, ctxcanvas->opacity);
+ }
+
switch(style)
{
case CD_HORIZONTAL:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- 0, hhalf, hsize, hhalf, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ 0, hhalf, hsize, hhalf, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
case CD_VERTICAL:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- hhalf, 0, hhalf, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ hhalf, 0, hhalf, hsize, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
case CD_BDIAGONAL:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- 0, hsize, hsize, 0, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ 0, hsize, hsize, 0, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
case CD_FDIAGONAL:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- 0, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ 0, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
case CD_CROSS:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- hsize, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- 0, hhalf, hsize, hhalf, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ hsize, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->opacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ 0, hhalf, hsize, hhalf, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
case CD_DIAGCROSS:
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- 0, 0, hsize, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
- fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; opacity:%d\" />\n",
- hsize, 0, 0, hsize, (ctxcanvas->canvas->back_opacity != CD_OPAQUE) ? ctxcanvas->fgColor : ctxcanvas->bgColor, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ 0, 0, hsize, hsize, ctxcanvas->fgColor, ctxcanvas->opacity);
+ fprintf(ctxcanvas->file, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"fill:none; stroke:%s; opacity:%g\" />\n",
+ hsize, 0, 0, hsize, ctxcanvas->fgColor, ctxcanvas->opacity);
break;
}
@@ -608,7 +860,7 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style)
static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (*data2rgb)(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b))
{
- int i, j;
+ int i, j, ret;
unsigned char r, g, b;
char color[20];
@@ -619,13 +871,18 @@ static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (
{
for (i = 0; i < n; i++)
{
- int ret = data2rgb(ctxcanvas, n, i, j, data, &r, &g, &b);
+ /* internal transform, affects also pattern orientation */
+ if (ctxcanvas->canvas->invert_yaxis)
+ ret = data2rgb(ctxcanvas, n, i, m-1 - j, data, &r, &g, &b);
+ else
+ ret = data2rgb(ctxcanvas, n, i, j, data, &r, &g, &b);
+
if (ret == -1) continue;
sprintf(color, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b);
- fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; opacity:%d\" />\n",
- (double)i, (double)j, 1.0, 1.0, color, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:%s; opacity:%g\" />\n",
+ (double)i, (double)j, 1.0, 1.0, color, ctxcanvas->opacity);
}
}
@@ -642,65 +899,69 @@ static int long2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, uns
static void cdpattern(cdCtxCanvas *ctxcanvas, int n, int m, const long int *pattern)
{
- ctxcanvas->canvas->interior_style = CD_PATTERN;
make_pattern(ctxcanvas, n, m, (void*)pattern, long2rgb);
}
static int uchar2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b)
{
- int ret = 1;
unsigned char* uchar_data = (unsigned char*)data;
if (uchar_data[j*n+i])
- {
cdDecodeColor(ctxcanvas->canvas->foreground, r, g, b);
- ret = 1;
- }
else
{
- cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
if (ctxcanvas->canvas->back_opacity==CD_TRANSPARENT)
- ret = -1;
+ return -1;
+ else
+ cdDecodeColor(ctxcanvas->canvas->background, r, g, b);
}
- return ret;
+ return 1;
}
static void cdstipple(cdCtxCanvas *ctxcanvas, int n, int m, const unsigned char *stipple)
{
- ctxcanvas->canvas->interior_style = CD_STIPPLE;
make_pattern(ctxcanvas, n, m, (void*)stipple, uchar2rgb);
}
static int cdfont(cdCtxCanvas *ctxcanvas, const char* type_face, int style, int size)
{
/* Define type_face and size */
- if(type_face != NULL)
+ if (type_face != NULL)
sprintf(ctxcanvas->font_family, "%s", type_face);
- if(size > 0)
+ if (size > 0)
sprintf(ctxcanvas->font_size, "%dpt", size);
else
sprintf(ctxcanvas->font_size, "%dpx", (-1)*size);
- if(style != -1)
+ if (style != -1)
{
- /* Default: CD_PLAIN */
- sprintf(ctxcanvas->font_weight, "%s", "normal");
- sprintf(ctxcanvas->font_style, "%s", "normal");
- sprintf(ctxcanvas->font_decoration, "%s", "none");
-
/* Define styles and decorations */
if (style & CD_BOLD)
- sprintf(ctxcanvas->font_weight, "%s", "bold");
+ ctxcanvas->font_weight = "bold";
+ else
+ ctxcanvas->font_weight = "normal";
if (style & CD_ITALIC)
- sprintf(ctxcanvas->font_style, "%s", "italic");
+ ctxcanvas->font_style = "italic";
+ else
+ ctxcanvas->font_style = "normal";
- if (style & CD_STRIKEOUT)
- sprintf(ctxcanvas->font_decoration, "%s", "line-through");
+ if (style & CD_STRIKEOUT || style & CD_UNDERLINE)
+ {
+ if (style & CD_STRIKEOUT && style & CD_UNDERLINE)
+ ctxcanvas->font_decoration = "line-through underline";
+ else
+ {
+ if (style & CD_STRIKEOUT)
+ ctxcanvas->font_decoration = "line-through";
- if (style & CD_UNDERLINE)
- sprintf(ctxcanvas->font_decoration, "%s", "underline");
+ if (style & CD_UNDERLINE)
+ ctxcanvas->font_decoration = "underline";
+ }
+ }
+ else
+ ctxcanvas->font_decoration = "none";
}
return 1;
@@ -711,7 +972,6 @@ static long cdbackground(cdCtxCanvas *ctxcanvas, long int color)
unsigned char r, g, b;
cdDecodeColor(color, &r, &g, &b);
sprintf(ctxcanvas->bgColor, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b);
-
return color;
}
@@ -720,7 +980,6 @@ static long cdforeground(cdCtxCanvas *ctxcanvas, long int color)
unsigned char r, g, b;
cdDecodeColor(color, &r, &g, &b);
sprintf(ctxcanvas->fgColor, "rgb(%d,%d,%d)", (int)r, (int)g, (int)b);
-
return color;
}
@@ -762,10 +1021,10 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
if (ctxcanvas->canvas->use_matrix) /* Transformation active */
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, -1, x, y+h, w, h, rgb_target);
+ 1, 0, 0, -1, x, y+h, w, h, rgb_target);
else
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, 1, x, y-h, w, h, rgb_target);
+ 1, 0, 0, 1, x, y-h, w, h, rgb_target);
free(rgb_data);
free(rgb_buffer);
@@ -811,10 +1070,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
if (ctxcanvas->canvas->use_matrix) /* Transformation active */
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, -1, x, y+h, w, h, rgb_target);
+ 1, 0, 0, -1, x, y+h, w, h, rgb_target);
else
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, 1, x, y-h, w, h, rgb_target);
+ 1, 0, 0, 1, x, y-h, w, h, rgb_target);
free(rgb_data);
free(rgb_buffer);
@@ -862,10 +1121,10 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
if (ctxcanvas->canvas->use_matrix) /* Transformation active */
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, -1, x, y+h, w, h, rgb_target);
+ 1, 0, 0, -1, x, y+h, w, h, rgb_target);
else
fprintf(ctxcanvas->file, "<image transform=\"matrix(%d %d %d %d %d %d)\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,%s\"/>\n",
- 1, 0, 0, 1, x, y-h, w, h, rgb_target);
+ 1, 0, 0, 1, x, y-h, w, h, rgb_target);
free(rgb_data);
free(rgb_buffer);
@@ -878,8 +1137,8 @@ static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color)
unsigned char r, g, b;
cdDecodeColor(color, &r, &g, &b);
- fprintf(ctxcanvas->file, "<circle cx=\"%d\" cy=\"%d\" r=\"0.1\" style=\"fill:rgb(%d,%d,%d); stroke:rgb(%d,%d,%d); stroke-width:%d; stroke-linecap:%s; stroke-linejoin:%s; stroke-dasharray:%s; opacity:%d\" />\n",
- x, y, r, g, b, r, g, b, ctxcanvas->linewidth, ctxcanvas->linecap, ctxcanvas->linejoin, ctxcanvas->linestyle, ctxcanvas->backopacity);
+ fprintf(ctxcanvas->file, "<circle cx=\"%d\" cy=\"%d\" r=\"0.5\" style=\"fill:rgb(%d,%d,%d); stroke:none; opacity:%g\" />\n",
+ x, y, r, g, b, ctxcanvas->opacity);
}
static void cddeactivate (cdCtxCanvas* ctxcanvas)
@@ -892,13 +1151,80 @@ static void cdflush (cdCtxCanvas* ctxcanvas)
fflush(ctxcanvas->file);
}
+static void set_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ int hatchboxsize;
+
+ if (data == NULL)
+ {
+ ctxcanvas->hatchboxsize = 8;
+ return;
+ }
+
+ sscanf(data, "%d", &hatchboxsize);
+ ctxcanvas->hatchboxsize = hatchboxsize;
+}
+
+static char* get_hatchboxsize_attrib(cdCtxCanvas *ctxcanvas)
+{
+ static char size[10];
+ sprintf(size, "%d", ctxcanvas->hatchboxsize);
+ return size;
+}
+
+static cdAttribute hatchboxsize_attrib =
+{
+ "HATCHBOXSIZE",
+ set_hatchboxsize_attrib,
+ get_hatchboxsize_attrib
+};
+
+static void set_opacity_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ if (data)
+ {
+ int opacity = 255;
+ sscanf(data, "%d", &opacity);
+ if (opacity < 0) ctxcanvas->opacity = 0.0;
+ else if (opacity > 255) ctxcanvas->opacity = 1.0;
+ else ctxcanvas->opacity = (double)opacity/255.0;
+ }
+ else
+ ctxcanvas->opacity = 1.0;
+}
+
+static char* get_opacity_attrib(cdCtxCanvas *ctxcanvas)
+{
+ static char data[50];
+ sprintf(data, "%d", cdRound(ctxcanvas->opacity*255.0));
+ return data;
+}
+
+static cdAttribute opacity_attrib =
+{
+ "OPACITY",
+ set_opacity_attrib,
+ get_opacity_attrib
+};
+
+static void set_cmd_attrib(cdCtxCanvas *ctxcanvas, char* data)
+{
+ fprintf(ctxcanvas->file, "%s", data);
+}
+
+static cdAttribute cmd_attrib =
+{
+ "CMD",
+ set_cmd_attrib,
+ NULL
+};
+
static void cdcreatecanvas(cdCanvas *canvas, void *data)
{
char filename[10240] = "";
char* strdata = (char*)data;
double w_mm = INT_MAX*3.78, h_mm = INT_MAX*3.78, res = 3.78;
cdCtxCanvas* ctxcanvas;
- int size;
strdata += cdGetFileName(strdata, filename);
if (filename[0] == 0)
@@ -916,10 +1242,6 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data)
return;
}
- size = strlen(filename);
- ctxcanvas->filename = malloc(size+1);
- memcpy(ctxcanvas->filename, filename, size+1);
-
/* store the base canvas */
ctxcanvas->canvas = canvas;
@@ -937,17 +1259,23 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data)
canvas->ctxcanvas = ctxcanvas;
ctxcanvas->last_fill_mode = -1;
- ctxcanvas->last_clip_path = -1;
+ ctxcanvas->last_clip_poly = -1;
+ ctxcanvas->last_clip_rect = -1;
- ctxcanvas->clip_off_control = 0;
+ ctxcanvas->clip_control = 0;
ctxcanvas->transform_control = 0;
ctxcanvas->clip_polygon = 0;
ctxcanvas->hatchboxsize = 8;
+ ctxcanvas->opacity = 1.0;
+
+ cdRegisterAttribute(canvas, &cmd_attrib);
+ cdRegisterAttribute(canvas, &hatchboxsize_attrib);
+ cdRegisterAttribute(canvas, &opacity_attrib);
fprintf(ctxcanvas->file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- fprintf(ctxcanvas->file, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%dpt\" height=\"%dpt\" viewBox=\"0 0 %d %d\" version=\"1.1\">\n", canvas->w, canvas->h, canvas->w, canvas->h);
- fprintf(ctxcanvas->file, "<g>\n");
+ fprintf(ctxcanvas->file, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%gpt\" height=\"%gpt\" viewBox=\"0 0 %d %d\" version=\"1.1\">\n", CD_MM2PT*canvas->w_mm, CD_MM2PT*canvas->h_mm, canvas->w, canvas->h);
+ fprintf(ctxcanvas->file, "<g>\n"); /* open global container */
}
static void cdinittable(cdCanvas* canvas)
@@ -979,9 +1307,7 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFText = cdftext;
canvas->cxFClipArea = cdfcliparea;
- canvas->cxBackOpacity = cdbackopacity;
canvas->cxLineStyle = cdlinestyle;
- canvas->cxLineWidth = cdlinewidth;
canvas->cxLineCap = cdlinecap;
canvas->cxLineJoin = cdlinejoin;
@@ -996,7 +1322,7 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxFlush = cdflush;
canvas->cxDeactivate = cddeactivate;
- canvas->cxKillCanvas = (void (*)(cdCtxCanvas*))cdkillcanvas;
+ canvas->cxKillCanvas = cdkillcanvas;
}
static cdContext cdSVGContext =
diff --git a/cd/src/win32/cdwdbuf.c b/cd/src/win32/cdwdbuf.c
index 85af87c..4beac10 100755
--- a/cd/src/win32/cdwdbuf.c
+++ b/cd/src/win32/cdwdbuf.c
@@ -75,6 +75,7 @@ static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
canvas->bpp = ctximage->bpp;
canvas->xres = ctximage->xres;
canvas->yres = ctximage->yres;
+
ctxcanvas->clip_pnt[2].x = ctxcanvas->clip_pnt[1].x = ctximage->w - 1;
ctxcanvas->clip_pnt[3].y = ctxcanvas->clip_pnt[2].y = ctximage->h - 1;
}
diff --git a/cd/src/win32/cdwdib.c b/cd/src/win32/cdwdib.c
index aff3f64..25851cd 100755
--- a/cd/src/win32/cdwdib.c
+++ b/cd/src/win32/cdwdib.c
@@ -323,6 +323,44 @@ void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned
}
}
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi)
+{
+ int x,y, resto1, resto2, offset, line_size;
+ BYTE* bits;
+
+ line_size = cdwDIBLineSize(dib->w, 32);
+
+ bits = dib->bits + line_size*(dib->h-1);
+ resto1 = line_size - dib->w * 4;
+ resto2 = wi - dib->w;
+
+ offset = wi * yi + xi;
+
+ red = red + offset;
+ green = green + offset;
+ blue = blue + offset;
+ alpha = alpha + offset;
+
+ for (y = 0; y < dib->h; y++)
+ {
+ for (x = 0; x < dib->w; x++)
+ {
+ *bits++ = CD_ALPHAPRE(*blue, *alpha); blue++;
+ *bits++ = CD_ALPHAPRE(*green, *alpha); green++;
+ *bits++ = CD_ALPHAPRE(*red, *alpha); red++;
+ *bits++ = *alpha++;
+ }
+
+ bits += resto1;
+ bits -= 2*line_size;
+
+ red += resto2;
+ green += resto2;
+ blue += resto2;
+ alpha += resto2;
+ }
+}
+
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi)
{
int x,y, resto1, resto2, offset;
diff --git a/cd/src/win32/cdwin.c b/cd/src/win32/cdwin.c
index 313e833..e2eb9ea 100755
--- a/cd/src/win32/cdwin.c
+++ b/cd/src/win32/cdwin.c
@@ -626,6 +626,7 @@ static int cdinteriorstyle (cdCtxCanvas* ctxcanvas, int style)
ctxcanvas->hBrush = CreateBrushIndirect(&ctxcanvas->logBrush);
ctxcanvas->hOldBrush = SelectObject(ctxcanvas->hDC, ctxcanvas->hBrush);
break;
+ /* the remaining styles must recreate the current brush */
case CD_HATCH:
cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
break;
@@ -642,10 +643,26 @@ static int cdinteriorstyle (cdCtxCanvas* ctxcanvas, int style)
return style;
}
+static void sUpdateFill(cdCtxCanvas* ctxcanvas, int fill)
+{
+ if (fill)
+ {
+ if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
+ (ctxcanvas->canvas->interior_style != CD_PATTERN))
+ cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ }
+ else
+ {
+ if (ctxcanvas->rebuild_pen)
+ sCreatePen(ctxcanvas);
+ }
+}
+
+/*******************************************************************************/
+
static void cdline (cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
{
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
MoveToEx( ctxcanvas->hDC, x1, y1, NULL );
LineTo( ctxcanvas->hDC, x2, y2 );
@@ -656,8 +673,7 @@ static void cdrect (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ym
{
HBRUSH oldBrush;
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
oldBrush = SelectObject(ctxcanvas->hDC, GetStockObject(NULL_BRUSH)); /* tira o desenho do interior */
Rectangle(ctxcanvas->hDC, xmin, ymin, xmax+1, ymax+1); /* +1 porque nao inclue right/bottom */
@@ -666,9 +682,7 @@ static void cdrect (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ym
static void cdbox (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->canvas->new_region)
{
@@ -696,40 +710,46 @@ typedef struct _winArcParam
YEndArc; /* second radial ending point */
} winArcParam;
-static void calcArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2, winArcParam* arc)
+static void sCalcArc(cdCanvas* canvas, int xc, int yc, int w, int h, double a1, double a2, winArcParam* arc, int swap)
{
- arc->LeftRect = xc - w/2;
- arc->RightRect = xc + w/2 + 1;
- arc->XStartArc = xc + cdRound(w * cos(CD_DEG2RAD * angle1) / 2.0);
- arc->XEndArc = xc + cdRound(w * cos(CD_DEG2RAD * angle2) / 2.0);
+ /* computation is done as if the angles are counter-clockwise,
+ and yaxis is NOT inverted. */
- if (ctxcanvas->canvas->invert_yaxis)
+ arc->LeftRect = xc - w/2;
+ arc->TopRect = yc - h/2;
+ arc->RightRect = xc + w/2 + 1;
+ arc->BottomRect = yc + h/2 + 1;
+
+ /* GDI orientation is the same as CD */
+
+ if (!canvas->invert_yaxis)
+ _cdSwapInt(arc->BottomRect, arc->TopRect); /* not necessary, but done for clarity */
+
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &(arc->XStartArc), &(arc->YStartArc), &(arc->XEndArc), &(arc->YEndArc));
+
+ if (canvas->invert_yaxis)
{
- arc->TopRect = yc - h/2;
- arc->BottomRect = yc + h/2 + 1;
- arc->YStartArc = yc - cdRound(h * sin(CD_DEG2RAD * angle1) / 2.0);
- arc->YEndArc = yc - cdRound(h * sin(CD_DEG2RAD * angle2) / 2.0);
+ /* fix axis orientation */
+ arc->YStartArc = 2*yc - arc->YStartArc;
+ arc->YEndArc = 2*yc - arc->YEndArc;
}
else
{
- arc->BottomRect = yc - h/2;
- arc->TopRect = yc + h/2 + 1;
- arc->YStartArc = yc + cdRound(h * sin(CD_DEG2RAD * angle1) / 2.0);
- arc->YEndArc = yc + cdRound(h * sin(CD_DEG2RAD * angle2) / 2.0);
-
- /* it is clock-wise when axis inverted */
- _cdSwapInt(arc->XStartArc, arc->XEndArc);
- _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ /* it is clock-wise when axis NOT inverted */
+ if (swap)
+ {
+ _cdSwapInt(arc->XStartArc, arc->XEndArc);
+ _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ }
}
}
static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
Arc(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
}
@@ -737,11 +757,9 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (angle1==0 && angle2==360)
{
@@ -781,11 +799,9 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (angle1==0 && angle2==360)
{
@@ -828,6 +844,105 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
POINT* pnt;
HPEN oldPen = NULL, Pen = NULL;
+ if (mode == CD_PATH)
+ {
+ int p, current_set;
+
+ /* if there is any current path, remove it */
+ BeginPath(ctxcanvas->hDC);
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ EndPath(ctxcanvas->hDC);
+ BeginPath(ctxcanvas->hDC);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ MoveToEx(ctxcanvas->hDC, poly[i].x, poly[i].y, NULL);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ LineTo(ctxcanvas->hDC, poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h, old_arcmode = 0;
+ double a1, a2;
+ winArcParam arc;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arc, 0);
+
+ if (current_set)
+ LineTo(ctxcanvas->hDC, arc.XStartArc, arc.YStartArc);
+
+ if ((a2-a1)<0) /* can be clockwise */
+ {
+ /* Arc behave diferent when GM_ADVANCED is set */
+ old_arcmode = SetArcDirection(ctxcanvas->hDC, ctxcanvas->canvas->invert_yaxis? AD_CLOCKWISE: AD_COUNTERCLOCKWISE);
+ }
+
+ ArcTo(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
+
+ if (old_arcmode) /* restore */
+ SetArcDirection(ctxcanvas->hDC, old_arcmode);
+
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ PolyBezierTo(ctxcanvas->hDC, (POINT*)(poly + i), 3);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ CloseFigure(ctxcanvas->hDC);
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ FillPath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ EndPath(ctxcanvas->hDC);
+ StrokePath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 0);
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ StrokeAndFillPath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_CLIP:
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ SelectClipPath(ctxcanvas->hDC, RGN_AND);
+ break;
+ }
+ }
+ return;
+ }
+
switch( mode )
{
case CD_CLOSED_LINES:
@@ -836,13 +951,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
n++;
/* continua */
case CD_OPEN_LINES:
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
Polyline(ctxcanvas->hDC, (POINT*)poly, n);
break;
case CD_BEZIER:
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
PolyBezier(ctxcanvas->hDC, (POINT*)poly, n);
break;
case CD_FILL:
@@ -857,14 +970,10 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
}
else
{
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN))
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->canvas->interior_style != CD_SOLID || ctxcanvas->fill_attrib[0] == '0')
- {
SelectObject(ctxcanvas->hDC, ctxcanvas->hNullPen); /* tira o desenho da borda */
- }
else
{
Pen = CreatePen(PS_SOLID, 1, ctxcanvas->fg);
@@ -875,9 +984,7 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
Polygon(ctxcanvas->hDC, (POINT*)poly, n);
if (ctxcanvas->canvas->interior_style != CD_SOLID || ctxcanvas->fill_attrib[0] == '0')
- {
SelectObject(ctxcanvas->hDC, ctxcanvas->hPen); /* restaura a Pen corrente */
- }
else
{
SelectObject(ctxcanvas->hDC, oldPen);
@@ -963,8 +1070,37 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
else
{
ctxcanvas->canvas->invert_yaxis = 1;
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
- SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
+
+ if (ctxcanvas->rotate_angle)
+ {
+ XFORM xForm;
+
+ /* the rotation must be corrected because of the Y axis orientation */
+
+ SetGraphicsMode(ctxcanvas->hDC, GM_ADVANCED);
+ ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
+
+ xForm.eM11 = (FLOAT) cos(-CD_DEG2RAD*ctxcanvas->rotate_angle);
+ xForm.eM12 = (FLOAT) sin(-CD_DEG2RAD*ctxcanvas->rotate_angle);
+ xForm.eM21 = (FLOAT) -xForm.eM12;
+ xForm.eM22 = (FLOAT) xForm.eM11;
+ xForm.eDx = (FLOAT) ctxcanvas->rotate_center_x;
+ xForm.eDy = (FLOAT) _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
+ ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
+
+ xForm.eM11 = (FLOAT) 1;
+ xForm.eM12 = (FLOAT) 0;
+ xForm.eM21 = (FLOAT) 0;
+ xForm.eM22 = (FLOAT) 1;
+ xForm.eDx = (FLOAT) -ctxcanvas->rotate_center_x;
+ xForm.eDy = (FLOAT) -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
+ ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
+ }
+ else
+ {
+ ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
+ SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
+ }
}
}
@@ -1581,11 +1717,12 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *red, unsigned c
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
}
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
y = _cdInvertYAxis(ctxcanvas->canvas, y);
yr = y - (h - 1); /* y starts at the bottom of the image */
@@ -1622,10 +1759,12 @@ static void sFixImageY(cdCanvas* canvas, int *y, int *h)
/* Here, y is from top to bottom,
is at the bottom-left corner of the image if h>0
is at the top-left corner of the image if h<0. (Undocumented feature)
+
cdCalcZoom expects Y at top-left if h>0
and Y at bottom-left if h<0
if h<0 then eh<0 to StretchDIBits mirror the image.
- BUT!!!!!! AlphaBlend will NOT mirror the image. */
+ BUT!!!!!! AlphaBlend will NOT mirror the image.
+ So it must be manually made there. */
if (!canvas->invert_yaxis)
*h = -(*h);
@@ -1741,26 +1880,16 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int width, int height, co
return;
}
- cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
-
if (eh < 0) /* must mirror the image */
{
- XFORM xForm;
-
+ /* Fix position */
eh = -eh;
+ ey = ey - eh;
- SetGraphicsMode(hDCMem, GM_ADVANCED);
- ModifyWorldTransform(hDCMem, NULL, MWT_IDENTITY);
-
- /* configure a bottom-up coordinate system */
- xForm.eM11 = (FLOAT)1;
- xForm.eM12 = (FLOAT)0;
- xForm.eM21 = (FLOAT)0;
- xForm.eM22 = (FLOAT)-1;
- xForm.eDx = (FLOAT)0;
- xForm.eDy = (FLOAT)(bh-1);
- ModifyWorldTransform(hDCMem, &xForm, MWT_LEFTMULTIPLY);
+ cdwDIBEncodeRGBARectMirror(&dib, red, green, blue, alpha, bx, by, width, height);
}
+ else
+ cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
hOldBitmap = SelectObject(hDCMem, hBitmap);
@@ -1891,20 +2020,21 @@ static cdCtxImage *cdcreateimage(cdCtxCanvas* ctxcanvas, int width, int height)
static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int y)
{
- int yr;
XFORM xForm;
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
}
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
y = _cdInvertYAxis(ctxcanvas->canvas, y);
- yr = y - (ctximage->h - 1);
- BitBlt(ctximage->hDC, 0, 0, ctximage->w, ctximage->h, ctxcanvas->hDC, x, yr, SRCCOPY);
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
+ BitBlt(ctximage->hDC, 0, 0, ctximage->w, ctximage->h, ctxcanvas->hDC, x, y, SRCCOPY);
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
@@ -1971,18 +2101,15 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
{
XFORM xForm;
RECT rect;
- rect.left = xmin;
- rect.right = xmax+1;
- rect.top = ymin;
- rect.bottom = ymax+1;
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
}
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */
{
dy = -dy;
ymin = _cdInvertYAxis(ctxcanvas->canvas, ymin);
@@ -1990,6 +2117,11 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
_cdSwapInt(ymin, ymax);
}
+ rect.left = xmin;
+ rect.right = xmax+1;
+ rect.top = ymin;
+ rect.bottom = ymax+1;
+
ScrollDC(ctxcanvas->hDC, dx, dy, &rect, NULL, NULL, NULL);
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
@@ -2136,47 +2268,25 @@ static cdAttribute img_points_attrib =
static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
- /* ignore ROTATE if transform is set */
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
if (ctxcanvas->canvas->use_matrix)
return;
if (data)
{
- XFORM xForm;
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
-
- /* the rotation must be corrected because of the Y axis orientation */
-
- SetGraphicsMode(ctxcanvas->hDC, GM_ADVANCED);
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
-
- xForm.eM11 = (FLOAT) cos(-CD_DEG2RAD*ctxcanvas->rotate_angle);
- xForm.eM12 = (FLOAT) sin(-CD_DEG2RAD*ctxcanvas->rotate_angle);
- xForm.eM21 = (FLOAT) -xForm.eM12;
- xForm.eM22 = (FLOAT) xForm.eM11;
- xForm.eDx = (FLOAT) ctxcanvas->rotate_center_x;
- xForm.eDy = (FLOAT) _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
- ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
-
- xForm.eM11 = (FLOAT) 1;
- xForm.eM12 = (FLOAT) 0;
- xForm.eM21 = (FLOAT) 0;
- xForm.eM22 = (FLOAT) 1;
- xForm.eDx = (FLOAT) -ctxcanvas->rotate_center_x;
- xForm.eDy = (FLOAT) -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
- ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
}
else
{
ctxcanvas->rotate_angle = 0;
ctxcanvas->rotate_center_x = 0;
ctxcanvas->rotate_center_y = 0;
-
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
- SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
}
+
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
@@ -2325,6 +2435,7 @@ void cdwInitTable(cdCanvas* canvas)
canvas->cxSector = cdsector;
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+
canvas->cxGetFontDim = cdgetfontdim;
canvas->cxGetTextSize = cdgettextsize;
canvas->cxPutImageRectRGB = cdputimagerectrgb;
diff --git a/cd/src/win32/cdwin.h b/cd/src/win32/cdwin.h
index a8230e7..94ed62c 100755
--- a/cd/src/win32/cdwin.h
+++ b/cd/src/win32/cdwin.h
@@ -169,6 +169,7 @@ void cdwDIBEncodePattern(cdwDIB* dib, const long int *colors);
void cdwDIBEncodeMapRect(cdwDIB* dib, const unsigned char *index, const long int *colors, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBRect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARectZoom(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int w, int h, int xi, int yi, int wi, int hi);
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi);
diff --git a/cd/src/win32/cdwnative.c b/cd/src/win32/cdwnative.c
index 69623e1..3534c6e 100755
--- a/cd/src/win32/cdwnative.c
+++ b/cd/src/win32/cdwnative.c
@@ -44,7 +44,6 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
if (ctxcanvas->hWnd)
{
RECT rect;
- HDC ScreenDC;
GetClientRect(ctxcanvas->hWnd, &rect);
ctxcanvas->canvas->w = rect.right - rect.left;
ctxcanvas->canvas->h = rect.bottom - rect.top;
@@ -52,12 +51,7 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres;
ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres;
- ScreenDC = GetDC(NULL);
- ctxcanvas->canvas->bpp = GetDeviceCaps(ScreenDC, BITSPIXEL);
- ReleaseDC(NULL, ScreenDC);
-
- if (ctxcanvas->canvas->use_matrix)
- ctxcanvas->canvas->cxTransform(ctxcanvas, ctxcanvas->canvas->matrix);
+ ctxcanvas->canvas->bpp = cdGetScreenColorPlanes();
}
/* Se nao e' ownwer, tem que restaurar o contexto */
@@ -70,6 +64,9 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
cdwRestoreDC(ctxcanvas);
}
+ if (ctxcanvas->canvas->use_matrix)
+ ctxcanvas->canvas->cxTransform(ctxcanvas, ctxcanvas->canvas->matrix);
+
return CD_OK;
}
diff --git a/cd/src/x11/cdx11.c b/cd/src/x11/cdx11.c
index 94aae39..8c59d48 100755
--- a/cd/src/x11/cdx11.c
+++ b/cd/src/x11/cdx11.c
@@ -1137,10 +1137,12 @@ static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a
{
if (ctxcanvas->canvas->use_matrix)
{
- cdarcSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimArc(ctxcanvas, xc, yc, w, h, a1, a2);
return;
}
+ /* angles in 1/64ths of degrees counterclockwise, similar to CD */
+
cdxCheckSolidStyle(ctxcanvas, 1);
XDrawArc(ctxcanvas->dpy, ctxcanvas->wnd, ctxcanvas->gc, xc-w/2, yc-h/2, w, h, cdRound(a1*64), cdRound((a2 - a1)*64));
cdxCheckSolidStyle(ctxcanvas, 0);
@@ -1150,7 +1152,7 @@ static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, doubl
{
if (ctxcanvas->canvas->use_matrix)
{
- cdsectorSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimSector(ctxcanvas, xc, yc, w, h, a1, a2);
return;
}
@@ -1172,7 +1174,7 @@ static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double
{
if (ctxcanvas->canvas->use_matrix)
{
- cdchordSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimChord(ctxcanvas, xc, yc, w, h, a1, a2);
return;
}
@@ -1194,7 +1196,7 @@ static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int yma
{
if (ctxcanvas->canvas->use_matrix)
{
- cdrectSIM(ctxcanvas, xmin, xmax, ymin, ymax);
+ cdSimRect(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
@@ -1207,7 +1209,7 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
{
if (ctxcanvas->canvas->use_matrix)
{
- cdboxSIM(ctxcanvas, xmin, xmax, ymin, ymax);
+ cdSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
@@ -1394,6 +1396,9 @@ void cdxPoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
case CD_BEZIER:
cdSimPolyBezier(ctxcanvas->canvas, poly, n);
break;
+ case CD_PATH:
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
}
if (pnt) free(pnt);
@@ -2192,8 +2197,11 @@ static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)
static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y)
{
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
+
XCopyArea(ctxcanvas->dpy, ctxcanvas->wnd, ctximage->img, ctxcanvas->gc,
- x, y - ctximage->h+1, ctximage->w, ctximage->h, 0, 0);
+ x, y, ctximage->w, ctximage->h, 0, 0);
}
static void cdputimagerect (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y, int xmin, int xmax, int ymin, int ymax)
@@ -2243,6 +2251,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
if (data)
{
+ /* use this configuration when there is NO native tranformation support */
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
diff --git a/cd/src/x11/cdxclp.c b/cd/src/x11/cdxclp.c
index d775fde..a2d1b6b 100755
--- a/cd/src/x11/cdxclp.c
+++ b/cd/src/x11/cdxclp.c
@@ -120,7 +120,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdClipboardContext =
{
- CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE),
+ CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE ), /* same as CD_MF */
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/x11/cdxdbuf.c b/cd/src/x11/cdxdbuf.c
index 835687c..0f4955e 100755
--- a/cd/src/x11/cdxdbuf.c
+++ b/cd/src/x11/cdxdbuf.c
@@ -146,8 +146,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdDBufferContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS |
- CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/x11/cdximg.c b/cd/src/x11/cdximg.c
index 8131f78..c823705 100755
--- a/cd/src/x11/cdximg.c
+++ b/cd/src/x11/cdximg.c
@@ -30,7 +30,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER ),
0,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/x11/cdxnative.c b/cd/src/x11/cdxnative.c
index c708d20..a69314c 100755
--- a/cd/src/x11/cdxnative.c
+++ b/cd/src/x11/cdxnative.c
@@ -143,7 +143,7 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdNativeWindowContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES ),
+ CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_FPRIMTIVES | CD_CAP_PATH | CD_CAP_BEZIER),
1,
cdcreatecanvas,
cdinittable,
diff --git a/cd/src/xrender/cdxrender.c b/cd/src/xrender/cdxrender.c
index 4dc69e2..2f99da3 100755
--- a/cd/src/xrender/cdxrender.c
+++ b/cd/src/xrender/cdxrender.c
@@ -17,7 +17,7 @@
#include "cddbuf.h"
#include "cdimage.h"
#include "cdnative.h"
-#include "truetype.h"
+#include "cd_truetype.h"
#include "sim.h"
#include <X11/Xproto.h>
@@ -196,52 +196,6 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
cdfSimBox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
}
-static void xrFixAngles(cdCtxCanvas *ctxcanvas, double *angle1, double *angle2)
-{
- if (ctxcanvas->canvas->invert_yaxis)
- {
- double temp = 360 - *angle1;
- *angle1 = 360 - *angle2;
- *angle2 = temp;
- }
-}
-
-static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimArc(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2);
-}
-
-static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimArc(ctxcanvas, xc, yc, w, h, a1, a2);
-}
-
-static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimElipse(ctxcanvas, xc, yc, w, h, a1, a2, 1);
-}
-
-static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimElipse(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2, 1);
-}
-
-static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimElipse(ctxcanvas, xc, yc, w, h, a1, a2, 0);
-}
-
-static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- xrFixAngles(ctxcanvas, &a1, &a2);
- cdfSimElipse(ctxcanvas, (double)xc, (double)yc, (double)w, (double)h, a1, a2, 0);
-}
-
static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
{
int i;
@@ -254,11 +208,17 @@ static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* fpoly, int n)
/* continue */
case CD_OPEN_LINES:
for (i = 0; i< n - 1; i++)
+ {
+ /* because line styles are not supported, this is not a problem */
cdfline(ctxcanvas, fpoly[i].x, fpoly[i].y, fpoly[i+1].x, fpoly[i+1].y);
+ }
break;
case CD_BEZIER:
cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
break;
+ case CD_PATH:
+ cdfSimPolyPath(ctxcanvas->canvas, fpoly, n);
+ break;
case CD_FILL:
{
if (ctxcanvas->canvas->new_region)
@@ -327,23 +287,17 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
/* continue */
case CD_OPEN_LINES:
for (i = 0; i<n-1; i++)
- cdfline(ctxcanvas, (int)poly[i].x, (int)poly[i].y, (int)poly[i+1].x, (int)poly[i+1].y);
- break;
- case CD_BEZIER:
{
- cdfPoint* fpoly = malloc(sizeof(cdfPoint)*n);
-
- for (i = 0; i<n; i++)
- {
- fpoly[i].x = (double)poly[i].x;
- fpoly[i].y = (double)poly[i].y;
- }
-
- cdfSimPolyBezier(ctxcanvas->canvas, fpoly, n);
-
- free(fpoly);
+ /* because line styles are not supported, this is not a problem */
+ cdfline(ctxcanvas, (double)poly[i].x, (double)poly[i].y, (double)poly[i+1].x, (double)poly[i+1].y);
}
break;
+ case CD_PATH:
+ cdSimPolyPath(ctxcanvas->canvas, poly, n);
+ break;
+ case CD_BEZIER:
+ cdSimPolyBezier(ctxcanvas->canvas, poly, n);
+ break;
case CD_FILL:
{
if (ctxcanvas->canvas->new_region)
@@ -953,11 +907,11 @@ static void cdkillcanvas(cdCtxCanvas *ctxcanvas)
if (ctxcanvas->ctxplus->font)
XftFontClose(ctxcanvas->dpy, ctxcanvas->ctxplus->font);
- XftDrawDestroy(ctxcanvas->ctxplus->draw);
- free(ctxcanvas->ctxplus);
-
/* call original method */
ctxcanvas->ctxplus->cxKillCanvas(ctxcanvas);
+
+ XftDrawDestroy(ctxcanvas->ctxplus->draw);
+ free(ctxcanvas->ctxplus);
}
static void xrInitTable(cdCanvas* canvas)
@@ -978,19 +932,21 @@ static void xrInitTable(cdCanvas* canvas)
canvas->cxPixel = cdpixel;
canvas->cxClear = cdclear;
+
canvas->cxLine = cdline;
- canvas->cxFLine = cdfline;
canvas->cxRect = cdrect;
- canvas->cxFRect = cdfSimRect;
canvas->cxBox = cdbox;
- canvas->cxFBox = cdfSimBox;
- canvas->cxArc = cdarc;
- canvas->cxFArc = cdfarc;
- canvas->cxSector = cdsector;
- canvas->cxFSector = cdfsector;
- canvas->cxChord = cdchord;
- canvas->cxFChord = cdfchord;
+ canvas->cxArc = cdSimArc;
+ canvas->cxSector = cdSimSector;
+ canvas->cxChord = cdSimChord;
canvas->cxPoly = cdpoly;
+
+ canvas->cxFLine = cdfline;
+ canvas->cxFRect = cdfSimRect;
+ canvas->cxFBox = cdfSimBox;
+ canvas->cxFArc = cdfSimArc;
+ canvas->cxFSector = cdfSimSector;
+ canvas->cxFChord = cdfSimChord;
canvas->cxFPoly = cdfpoly;
/* TODO: canvas->cxPutImageRectRGBA = cdputimagerectrgba; */
@@ -1045,13 +1001,13 @@ static void xrCreateCanvasDBUFFER(cdCanvas* canvas, void *data)
{
cdcreatecanvasDBUFFER(canvas, data); /* call original first */
xrCreateContextPlus(canvas->ctxcanvas);
- canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasDBUFFER; /* must set it here since CreateContext clears the structure */
}
static void xrInitTableDBUFFER(cdCanvas* canvas)
{
- if (!cdkillcanvasDBUFFER) cdkillcanvasDBUFFER = canvas->cxKillCanvas; /* save original method */
cdinittableDBUFFER(canvas);
+ if (!cdkillcanvasDBUFFER) cdkillcanvasDBUFFER = canvas->cxKillCanvas;
+ canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasDBUFFER;
xrInitTable(canvas);
}
@@ -1062,6 +1018,7 @@ cdContext* cdContextDBufferPlus(void)
int old_plus = cdUseContextPlus(0); /* disable context plus */
cdDBufferContext = *cdContextDBuffer(); /* copy original context */
cdDBufferContext.plus = 1; /* mark as plus */
+ cdDBufferContext.caps |= CD_CAP_FPRIMTIVES;
/* save original methods */
cdcreatecanvasDBUFFER = cdDBufferContext.cxCreateCanvas;
@@ -1080,13 +1037,13 @@ static void xrCreateCanvasNATIVE(cdCanvas* canvas, void *data)
{
cdcreatecanvasNATIVE(canvas, data);
xrCreateContextPlus(canvas->ctxcanvas);
- canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasNATIVE;
}
static void xrInitTableNATIVE(cdCanvas* canvas)
{
- if (!cdkillcanvasNATIVE) cdkillcanvasNATIVE = canvas->cxKillCanvas;
cdinittableNATIVE(canvas);
+ if (!cdkillcanvasNATIVE) cdkillcanvasNATIVE = canvas->cxKillCanvas;
+ canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasNATIVE;
xrInitTable(canvas);
}
@@ -1101,6 +1058,7 @@ cdContext* cdContextNativeWindowPlus(void)
cdNativeWindowContext.cxCreateCanvas = xrCreateCanvasNATIVE;
cdNativeWindowContext.cxInitTable = xrInitTableNATIVE;
cdNativeWindowContext.plus = 1;
+ cdNativeWindowContext.caps |= CD_CAP_FPRIMTIVES;
cdUseContextPlus(old_plus);
}
return &cdNativeWindowContext;
@@ -1110,13 +1068,13 @@ static void xrCreateCanvasIMAGE(cdCanvas* canvas, void *data)
{
cdcreatecanvasIMAGE(canvas, data);
xrCreateContextPlus(canvas->ctxcanvas);
- canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasIMAGE;
}
static void xrInitTableIMAGE(cdCanvas* canvas)
{
- if (!cdkillcanvasIMAGE) cdkillcanvasIMAGE = canvas->cxKillCanvas;
cdinittableIMAGE(canvas);
+ if (!cdkillcanvasIMAGE) cdkillcanvasIMAGE = canvas->cxKillCanvas;
+ canvas->ctxcanvas->ctxplus->cxKillCanvas = cdkillcanvasIMAGE;
xrInitTable(canvas);
}
@@ -1131,6 +1089,7 @@ cdContext* cdContextImagePlus(void)
cdImageContext.cxCreateCanvas = xrCreateCanvasIMAGE;
cdImageContext.cxInitTable = xrInitTableIMAGE;
cdImageContext.plus = 1;
+ cdImageContext.caps |= CD_CAP_FPRIMTIVES;
cdUseContextPlus(old_plus);
}
return &cdImageContext;
diff --git a/cd/test/cdtest/cdtest.c b/cd/test/cdtest/cdtest.c
index 1e6375b..536cfc2 100755
--- a/cd/test/cdtest/cdtest.c
+++ b/cd/test/cdtest/cdtest.c
@@ -229,7 +229,7 @@ void CDTestInit(void)
if (use_contextplus)
{
-#ifdef USE_GDIPLUS
+#ifdef USE_CONTEXTPLUS
cdInitContextPlus();
#endif
}
diff --git a/cd/test/cdtest/drivers.c b/cd/test/cdtest/drivers.c
index dd23331..2387741 100755
--- a/cd/test/cdtest/drivers.c
+++ b/cd/test/cdtest/drivers.c
@@ -211,7 +211,7 @@ static int fSVG(void)
if (IupGetFile(filename)>=0)
{
- sprintf(data, "%s -s%d", filename, (int)(ctgc.res * 25.4));
+ sprintf(data, "%s %gx%g %g", filename, ((double)ctgc.w)/ctgc.res, ((double)ctgc.h)/ctgc.res, ctgc.res);
return SaveCanvas("CD_SVG", CD_SVG, data);
}
diff --git a/cd/test/simple/config.mak b/cd/test/simple/config.mak
index 2777b7d..6baa00a 100755
--- a/cd/test/simple/config.mak
+++ b/cd/test/simple/config.mak
@@ -1,12 +1,22 @@
-APPNAME = simple
+APPNAME := simple
-ifdef USE_GDK
- APPNAME = simplegdk
- USE_GTK = Yes
-else
- DEFINES = USE_CONTEXTPLUS
+ifdef GTK_DEFAULT
+ ifdef USE_MOTIF
+ # Build Motif version in Linux,Darwin,FreeBSD
+ APPNAME := $(APPNAME)mot
+ else
+ GDK_CAIRO = Yes
+ endif
+else
+ ifdef USE_GTK
+ # Build GTK version in IRIX,SunOS,AIX,Win32
+ APPNAME := $(APPNAME)gtk
+ GDK_CAIRO = Yes
+ endif
endif
+DEFINES = USE_CONTEXTPLUS
+
SRC = simple.c simple_led.c iupmain.c
#DBG = Yes
@@ -29,9 +39,33 @@ USE_STATIC = Yes
#USE_IM = Yes
+USE_OPENGL = Yes
+ifdef USE_OPENGL
+ DEFINES += USE_OPENGL
+endif
+
ifneq ($(findstring Win, $(TEC_SYSNAME)), )
- LIBS = cdpdf pdflib cdcontextplus gdiplus
+ LIBS = cdpdf pdflib
+ ifndef GDK_CAIRO
+ LIBS += cdcontextplus gdiplus
+ endif
+ ifdef USE_OPENGL
+ LIBS += cdgl ftgl
+ endif
else
- SLIB = $(CD)/lib/$(TEC_UNAME)/libcdpdf.a $(CD)/lib/$(TEC_UNAME)/libpdflib.a $(CD)/lib/$(TEC_UNAME)/libcdcontextplus.a
- LIBS = Xrender Xft
+ ifdef DBG_DIR
+ CDLIB = $(CD)/lib/$(TEC_UNAME)d
+ else
+ CDLIB = $(CD)/lib/$(TEC_UNAME)
+ endif
+
+ SLIB = $(CDLIB)/libcdpdf.a $(CDLIB)/libpdflib.a
+ ifndef GDK_CAIRO
+ SLIB += $(CDLIB)/libcdcontextplus.a
+ LIBS = Xrender Xft
+ endif
+ ifdef USE_OPENGL
+ SLIB += $(CDLIB)/libcdgl.a $(CDLIB)/libftgl.a
+ #LIBS = ftgl
+ endif
endif
diff --git a/cd/test/simple/gdiplustest.cpp b/cd/test/simple/gdiplustest.cpp
deleted file mode 100755
index af7b643..0000000
--- a/cd/test/simple/gdiplustest.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include <windows.h>
-#include <gdiplus.h>
-using namespace Gdiplus;
-
-/* Visual C++ 7.1 + SP1
- GDI+ 1.0 File Version 5.1.3102.2180
-*/
-
-void DrawLineMarks(Graphics* graphics, Pen* greenPen, int x, int y, int w, int h)
-{
- graphics->DrawLine(greenPen, x+w-1, y-5, x+w-1, y+5); // end markers
- graphics->DrawLine(greenPen, x-5, y+h-1, x+5, y+h-1);
-}
-
-void SimpleImageTest(HWND hWnd)
-{
- int x, y;
- Graphics* graphics = new Graphics(hWnd);
- graphics->Clear(Color(255, 255, 255)); // white background
-
- Bitmap image(16, 16, PixelFormat24bppRGB);
- image.SetResolution(graphics->GetDpiX(), graphics->GetDpiX());
-
- /* black pixel border */
- for (y = 0; y < 16; y++)
- image.SetPixel(0, y, Color(0, 0, 0));
- for (y = 0; y < 16; y++)
- image.SetPixel(15, y, Color(0, 0, 0));
- for (x = 1; x < 15; x++)
- image.SetPixel(x, 0, Color(0, 0, 0));
- for (x = 1; x < 15; x++)
- image.SetPixel(x, 15, Color(0, 0, 0));
-
- /* light yellow contents */
- for (y = 1; y < 15; y++)
- for (x = 1; x < 15; x++)
- image.SetPixel(x, y, Color(192, 192, 0));
-
- Pen redPen(Color(255, 0, 0), 1);
- redPen.SetDashStyle(DashStyleDash);
- Pen greenPen(Color(0, 255, 0), 1);
- greenPen.SetDashStyle(DashStyleDash);
-
- // I add {} to avoid reusing some Rect in the next test
-
- graphics->SetPixelOffsetMode(PixelOffsetModeHalf); // pixel center is (.5,.5) instead of (0, 0)
-
- // NO zoom
- {
- RectF actualRect(10, 10, 16, 16);
- graphics->DrawImage(&image, 10, 10);
- graphics->DrawRectangle(&redPen, actualRect);
- DrawLineMarks(graphics, &greenPen, 10, 10, 16, 16);
- }
-
- // zoom using Bilinear Interpolation
- {
- RectF zoomRect(50, 10, 160, 160);
- graphics->SetInterpolationMode(InterpolationModeBilinear);
- graphics->DrawImage(&image, zoomRect);
- graphics->DrawRectangle(&redPen, zoomRect);
- DrawLineMarks(graphics, &greenPen, 50, 10, 160, 160);
- }
-
- // zoom using Nearest Neighborhood
- {
- RectF zoomRect2(250, 10, 160, 160);
- graphics->SetInterpolationMode(InterpolationModeNearestNeighbor);
- graphics->DrawImage(&image, zoomRect2);
- graphics->DrawRectangle(&redPen, zoomRect2);
- DrawLineMarks(graphics, &greenPen, 250, 10, 160, 160);
- }
-
-
- // Using a source image size, smaller than actual
-
-
- // NO zoom
- {
- RectF actualRect3(10, 200, 16, 16);
- graphics->DrawImage(&image, actualRect3, 0, 0, 16-1, 16-1, UnitPixel, NULL, NULL);
- graphics->DrawRectangle(&redPen, actualRect3);
- DrawLineMarks(graphics, &greenPen, 10, 400, 16, 16);
- }
-
- // zoom using Bilinear Interpolation
- {
- RectF zoomRect6(50, 200, 160, 160);
- graphics->SetInterpolationMode(InterpolationModeBilinear);
- graphics->DrawImage(&image, zoomRect6, 0, 0, 16-1, 16-1, UnitPixel, NULL, NULL);
- graphics->DrawRectangle(&redPen, zoomRect6);
- DrawLineMarks(graphics, &greenPen, 50, 400, 160, 160);
- }
-
- // zoom using Nearest Neighborhood
- {
- RectF zoomRect7(250, 200, 160, 160);
- graphics->SetInterpolationMode(InterpolationModeNearestNeighbor);
- graphics->DrawImage(&image, zoomRect7, 0, 0, 16-1, 16-1, UnitPixel, NULL, NULL);
- graphics->DrawRectangle(&redPen, zoomRect7);
- DrawLineMarks(graphics, &greenPen, 250, 400, 160, 160);
- }
-
- delete graphics;
-}
-
-#include <iup.h>
-
-extern "C" char* winData;
-extern "C" void SimpleDrawTest(void);
-
-void SimpleDrawTest(void)
-{
- HWND hWnd = (HWND)IupGetAttribute((Ihandle*)winData, "HWND");
- SimpleImageTest(hWnd);
-}
diff --git a/cd/test/simple/iupmain.c b/cd/test/simple/iupmain.c
index daf058a..de01979 100755
--- a/cd/test/simple/iupmain.c
+++ b/cd/test/simple/iupmain.c
@@ -1,9 +1,21 @@
#include <stdlib.h>
+#include <stdio.h>
+
#include <iup.h>
+#include <iupgl.h>
#include <cd.h>
#include "simple.h"
+#ifdef USE_OPENGL
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
int cmdExit(void)
{
return IUP_CLOSE;
@@ -11,6 +23,43 @@ int cmdExit(void)
void simple_loadled (void);
+#ifdef USE_OPENGL
+/* USE_OPENGL - add to linker:
+cdgl
+iupgl
+ftgl
+glu32
+opengl32
+*/
+
+void SimpleUpdateSize(cdCanvas* cnv)
+{
+ Ihandle* canvas = IupGetHandle("SimpleCanvas");
+ int w = IupGetInt(canvas, "RASTERSIZE");
+ int h = IupGetInt2(canvas, "RASTERSIZE");
+ IupGLMakeCurrent(canvas);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0, w, 0, h);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if (cnv)
+ {
+ char StrData[100];
+ sprintf(StrData, "%dx%d", w, h); /* no need to update resolution */
+ cdCanvasSetAttribute(cnv, "SIZE", StrData);
+ }
+}
+
+void SimpleFlush(void)
+{
+ IupGLSwapBuffers(IupGetHandle("SimpleCanvas"));
+}
+#endif
+
int main(int argc, char** argv)
{
IupOpen(&argc, &argv);
@@ -18,8 +67,21 @@ int main(int argc, char** argv)
#ifdef USE_CONTEXTPLUS
cdInitContextPlus();
#endif
+#ifdef USE_OPENGL
+ IupGLCanvasOpen();
+#endif
simple_loadled();
+#ifdef USE_OPENGL
+ {
+ Ihandle* dialog = IupGetHandle("SimpleDialog");
+ Ihandle* canvas = IupGetHandle("SimpleCanvas");
+ IupDestroy(canvas);
+ canvas = IupGLCanvas("SimpleRepaint");
+ IupSetHandle("SimpleCanvas", canvas);
+ IupAppend(dialog, canvas);
+ }
+#endif
IupSetAttribute(IupGetHandle("SimpleDialog"), "PLACEMENT", "MAXIMIZED");
IupShow(IupGetHandle("SimpleDialog"));
@@ -57,6 +119,10 @@ int main(int argc, char** argv)
IupSetFunction("SimpleDrawImageRGB", (Icallback) SimpleDrawImageRGB);
IupSetFunction("SimpleDrawSimulate", (Icallback) SimpleDrawSimulate);
+#ifdef USE_OPENGL
+ IupSetFunction("SimpleDrawGL", (Icallback) SimpleDrawGL);
+#endif
+
IupSetFunction("SimpleNotXor", (Icallback) SimpleNotXor);
IupSetFunction("SimpleXor", (Icallback) SimpleXor);
IupSetFunction("SimpleReplace", (Icallback) SimpleReplace);
@@ -67,15 +133,20 @@ int main(int argc, char** argv)
IupSetFunction("SimpleContextPlus", (Icallback) SimpleContextPlus);
IupSetFunction("SimpleTransform", (Icallback) SimpleTransform);
- IupSetFunction("SimpleDrawAll", (Icallback) SimpleDrawAll);
- IupSetFunction("SimpleDrawTextAlign", (Icallback) SimpleDrawTextAlign);
- IupSetFunction("SimpleDrawTextFonts", (Icallback) SimpleDrawTextFonts);
- IupSetFunction("SimpleDrawTest", (Icallback) SimpleDrawTest);
+ IupSetFunction("SimpleAll", (Icallback) SimpleAll);
+ IupSetFunction("SimpleTextAlign", (Icallback) SimpleTextAlign);
+ IupSetFunction("SimpleTextFonts", (Icallback) SimpleTextFonts);
+ IupSetFunction("SimpleTest", (Icallback) SimpleTest);
- IupSetFunction("SimpleRepaint", (Icallback) SimpleDrawRepaint);
+ IupSetFunction("SimpleRepaint", (Icallback) SimpleRepaint);
SimpleDrawWindow();
+#ifdef USE_OPENGL
+ SimpleUpdateSize(NULL);
+ IupUpdate(IupGetHandle("SimpleCanvas"));
+#endif
+
IupMainLoop();
SimpleKillCanvas();
diff --git a/cd/test/simple/simple.c b/cd/test/simple/simple.c
index d04b96c..c47812e 100755
--- a/cd/test/simple/simple.c
+++ b/cd/test/simple/simple.c
@@ -29,6 +29,7 @@
#include "cddebug.h"
#include "wd.h"
#include "cdgdiplus.h"
+#include "cdgl.h"
#include "simple.h"
@@ -46,10 +47,11 @@ cdCanvas *curCanvas = NULL; /* The current canvas */
int clipping = CD_CLIPOFF; /* Clipping flag, same as the CD */
int write_mode = CD_REPLACE; /* Write Mode flag, same as the CD */
-int gdpiplus = 0;
+int contextplus = 0;
int simple_draw = 0;
int use_transform = 0;
int simulate = 0;
+int use_opengl = 0;
enum {DRAW_ALL, DRAW_TEXTFONTS, DRAW_TEXTALIGN, DRAW_TEST};
@@ -65,7 +67,7 @@ unsigned char alpha[IMAGE_SIZE*IMAGE_SIZE]; /* Alpha image buffer */
/* Prototype of the function that makes the drawing independent of canvas. */
-void SimpleDraw(void);
+void SimpleDraw(cdCanvas* canvas);
void SimpleInitAlpha(int width, int height, unsigned char* _alpha)
{
@@ -79,9 +81,9 @@ void SimpleInitAlpha(int width, int height, unsigned char* _alpha)
void SimpleCreateCanvasWindow(void)
{
/* creates the canvas based in an existing window */
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
winCanvas = cdCreateCanvas(CD_IUP, winData);
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
curCanvas = winCanvas;
}
@@ -144,17 +146,17 @@ void SimpleCreateCanvas(char* data)
int SimpleTransform(void)
{
use_transform = !use_transform;
- SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleContextPlus(void)
{
#ifdef USE_CONTEXTPLUS
- gdpiplus = !gdpiplus;
+ contextplus = !contextplus;
SimpleKillCanvas();
SimpleCreateCanvasWindow();
- SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
#endif
return 0;
}
@@ -162,12 +164,12 @@ int SimpleContextPlus(void)
void PlayCanvasDriver(cdContext* ctx, char* StrData)
{
int w, h;
- cdActivate(curCanvas);
- cdBackground(CD_WHITE);
- cdClear();
- cdGetCanvasSize(&w, &h, 0, 0);
- cdPlay(ctx, 100, w-100, 100, h-100, StrData);
-// cdPlay(ctx, 0, 0, 0, 0, StrData);
+ cdCanvasActivate(curCanvas);
+ cdCanvasBackground(curCanvas, CD_WHITE);
+ cdCanvasClear(curCanvas);
+ cdCanvasGetSize(curCanvas, &w, &h, 0, 0);
+ cdCanvasPlay(curCanvas, ctx, 100, w-100, 100, h-100, StrData);
+// cdCanvasPlay(curCanvas, ctx, 0, 0, 0, 0, StrData);
}
int SimplePlayClipboard(void)
@@ -206,28 +208,32 @@ int SimplePlayEMF(void)
return 0;
}
-int SimpleDrawRepaint(void)
+int SimpleRepaint(void)
{
- cdActivate(curCanvas);
- SimpleDraw();
- cdFlush();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleDrawWindow(void)
{
+ use_opengl = 0;
curCanvas = winCanvas;
- return SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
+ return 0;
}
void DrawCanvasDriver(cdContext* ctx, char* StrData)
{
cdCanvas* tmpCanvas = cdCreateCanvas(ctx, StrData);
- if (tmpCanvas == NULL) return;
- cdActivate(tmpCanvas);
- SimpleDraw();
+ if (tmpCanvas == NULL)
+ {
+ printf("CreateCanvas(%s) - Failed!\n", StrData);
+ return;
+ }
+ printf("CreateCanvas(%s)\n", StrData);
+ SimpleDraw(tmpCanvas);
cdKillCanvas(tmpCanvas);
- cdActivate(curCanvas);
+ printf("KillCanvas()\n");
}
void DrawCanvasDriverSize(cdContext* ctx, char* name, int pixels)
@@ -235,12 +241,13 @@ void DrawCanvasDriverSize(cdContext* ctx, char* name, int pixels)
char StrData[100];
int w, h;
double w_mm, h_mm;
- cdActivate(curCanvas);
- cdGetCanvasSize(&w, &h, &w_mm, &h_mm);
- if (pixels)
+ cdCanvasGetSize(curCanvas, &w, &h, &w_mm, &h_mm);
+ if (pixels == 1)
sprintf(StrData, "%s %dx%d", name, w, h);
+ else if (pixels == 2)
+ sprintf(StrData, "%s -w%g -h%g -s%g", name, w_mm, h_mm, ((double)w/w_mm)*25.4);
else
- sprintf(StrData, "%s %gx%g", name, w_mm, h_mm);
+ sprintf(StrData, "%s %gx%g %g", name, w_mm, h_mm, (double)w/w_mm);
DrawCanvasDriver(ctx, StrData);
}
@@ -248,8 +255,7 @@ void DrawCanvasDriverSizeParam(cdContext* ctx, char* param)
{
char StrData[100];
int w, h;
- cdActivate(curCanvas);
- cdGetCanvasSize(&w, &h, 0, 0);
+ cdCanvasGetSize(curCanvas, &w, &h, 0, 0);
sprintf(StrData, "%dx%d %s", w, h, param);
DrawCanvasDriver(ctx, StrData);
}
@@ -262,7 +268,7 @@ int SimpleDrawDebug(void)
int SimpleDrawCGMText(void)
{
- DrawCanvasDriverSize(CD_CGM, "simple_t.cgm - t", 0);
+ DrawCanvasDriverSize(CD_CGM, "simple_t.cgm -t", 0);
return 0;
}
@@ -286,9 +292,9 @@ int SimpleDrawDGN(void)
int SimpleDrawEMF(void)
{
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
DrawCanvasDriverSize(CD_EMF, "simple.emf", 1);
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
@@ -300,7 +306,7 @@ int SimpleDrawMetafile(void)
int SimpleDrawPS(void)
{
- DrawCanvasDriver(CD_PS, "simple.ps");
+ DrawCanvasDriverSize(CD_PS, "simple.ps -l0 -r0 -t0 -b0", 2);
return 0;
}
@@ -312,13 +318,13 @@ int SimpleDrawSVG(void)
int SimpleDrawPDF(void)
{
- DrawCanvasDriver(CD_PDF, "simple.pdf");
+ DrawCanvasDriverSize(CD_PDF, "simple.pdf", 2);
return 0;
}
int SimpleDrawEPS(void)
{
- DrawCanvasDriver(CD_PS, "simple.eps -e");
+ DrawCanvasDriverSize(CD_PS, "simple.eps -e", 2);
return 0;
}
@@ -330,97 +336,118 @@ int SimpleDrawWMF(void)
int SimpleDrawPrint(void)
{
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
DrawCanvasDriver(CD_PRINTER, "simple print");
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
int SimpleDrawPrintDialog(void)
{
- if (gdpiplus) cdUseContextPlus(1);
- DrawCanvasDriver(CD_PRINTER, "simple -d");
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(1);
+ DrawCanvasDriver(CD_PRINTER, "simple -d"); /* show dialog */
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
int SimpleDrawClipboardBitmap(void)
{
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
DrawCanvasDriverSizeParam(CD_CLIPBOARD, "-b");
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
int SimpleDrawClipboardMetafile(void)
{
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
DrawCanvasDriverSizeParam(CD_CLIPBOARD, "-m");
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
int SimpleDrawClipboardEMF(void)
{
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
DrawCanvasDriverSizeParam(CD_CLIPBOARD, "");
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
return 0;
}
int SimpleReplace(void)
{
write_mode = CD_REPLACE;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleXor(void)
{
write_mode = CD_XOR;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleNotXor(void)
{
write_mode = CD_NOT_XOR;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleClippingOff(void)
{
clipping = CD_CLIPOFF;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleClippingArea(void)
{
clipping = CD_CLIPAREA;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleClippingPolygon(void)
{
clipping = CD_CLIPPOLYGON;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleClippingRegion(void)
{
clipping = CD_CLIPREGION;
- cdActivate(curCanvas);
- SimpleDrawAll();
+ SimpleDraw(curCanvas);
+ return 0;
+}
+
+int SimpleAll(void)
+{
+ simple_draw = DRAW_ALL;
+ SimpleDraw(curCanvas);
+ return 0;
+}
+
+int SimpleTextAlign(void)
+{
+ simple_draw = DRAW_TEXTALIGN;
+ SimpleDraw(curCanvas);
+ return 0;
+}
+
+int SimpleTextFonts(void)
+{
+ simple_draw = DRAW_TEXTFONTS;
+ SimpleDraw(curCanvas);
+ return 0;
+}
+
+int SimpleTest(void)
+{
+ simple_draw = DRAW_TEST;
+ SimpleDraw(curCanvas);
return 0;
}
@@ -429,53 +456,79 @@ void* CreateImageRGBA(int w, int h)
void* myImage;
unsigned char * _alpha = malloc(w * h);
SimpleInitAlpha(w, h, _alpha);
- cdSetAttribute("IMAGEALPHA", (char*)_alpha);
- cdSetAttribute("IMAGEFORMAT", "32"); // afetara´ o proximo cdCreateImage
- myImage = cdCreateImage(w, h);
- cdSetAttribute("IMAGEFORMAT", NULL); // remove o atributo para nao afetar outros cdCreateImage
+ cdCanvasSetAttribute(curCanvas, "IMAGEALPHA", (char*)_alpha);
+ cdCanvasSetAttribute(curCanvas, "IMAGEFORMAT", "32"); // afetara´ o proximo cdCreateImage
+ myImage = cdCanvasCreateImage(curCanvas, w, h);
+ cdCanvasSetAttribute(curCanvas, "IMAGEFORMAT", NULL); // remove o atributo para nao afetar outros cdCreateImage
return myImage;
}
int SimpleDrawImage(void)
{
+ use_opengl = 0;
if (dbCanvas) cdKillCanvas(dbCanvas);
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
dbCanvas = cdCreateCanvas(CD_DBUFFER, winCanvas);
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
curCanvas = dbCanvas;
- SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
return 0;
}
int SimpleDrawImageRGB(void)
{
+ use_opengl = 0;
if (dbCanvas) cdKillCanvas(dbCanvas);
- if (gdpiplus) cdUseContextPlus(1);
+ if (contextplus) cdUseContextPlus(1);
dbCanvas = cdCreateCanvas(CD_DBUFFERRGB, winCanvas);
- if (gdpiplus) cdUseContextPlus(0);
+ if (contextplus) cdUseContextPlus(0);
curCanvas = dbCanvas;
- SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
return 0;
}
-int SimpleDrawSimulate(void)
+#ifdef USE_OPENGL
+int SimpleDrawGL(void)
{
- cdActivate(curCanvas);
+ char StrData[100];
+ int w, h;
+ double w_mm, h_mm;
+
+ if (use_opengl)
+ return 0;
+ cdCanvasGetSize(curCanvas, &w, &h, &w_mm, &h_mm);
+
+ sprintf(StrData, "%dx%d %g", w, h, ((double)w/w_mm));
+
+ if (dbCanvas) cdKillCanvas(dbCanvas);
+
+ dbCanvas = cdCreateCanvas(CD_GL, StrData);
+
+ curCanvas = dbCanvas;
+ use_opengl = 1;
+ SimpleDraw(curCanvas);
+
+ return 0;
+}
+#endif
+
+int SimpleDrawSimulate(void)
+{
simulate = !simulate;
if (simulate)
- cdSimulate(CD_SIM_ALL);
+ cdCanvasSimulate(curCanvas, CD_SIM_ALL);
else
- cdSimulate(CD_SIM_NONE);
+ cdCanvasSimulate(curCanvas, CD_SIM_NONE);
- SimpleDrawRepaint();
+ SimpleDraw(curCanvas);
return 0;
}
@@ -494,167 +547,207 @@ void SimpleKillCanvas(void)
}
}
-void SimpleDraw(void)
+void SimpleDrawTextFonts(cdCanvas* canvas);
+void SimpleDrawTextAlign(cdCanvas* canvas);
+void SimpleDrawAll(cdCanvas* canvas);
+void SimpleDrawTest(cdCanvas* canvas);
+
+void SimpleDraw(cdCanvas* canvas)
{
+#ifdef USE_OPENGL
+ if (use_opengl)
+ SimpleUpdateSize(canvas);
+#endif
+
+ /* refresh CD canvas size, when window size has changed */
+ cdCanvasActivate(canvas);
+
if (simple_draw == DRAW_TEXTFONTS)
- SimpleDrawTextFonts();
+ SimpleDrawTextFonts(canvas);
else if (simple_draw == DRAW_TEXTALIGN)
- SimpleDrawTextAlign();
+ SimpleDrawTextAlign(canvas);
else if (simple_draw == DRAW_TEST)
- SimpleDrawTest();
+ SimpleDrawTest(canvas);
else
- SimpleDrawAll();
+ SimpleDrawAll(canvas);
+
+ /* Adds a new page, or
+ flushes the file, or
+ flushes the screen, or
+ swap the double buffer. */
+ cdCanvasFlush(canvas);
+
+#ifdef USE_OPENGL
+ if (use_opengl)
+ SimpleFlush();
+#endif
}
-int SimpleDrawAll(void)
+void SimpleDrawAll(cdCanvas* canvas)
{
int w, h;
- cdGetCanvasSize(&w, &h, 0, 0);
+ cdCanvasGetSize(canvas, &w, &h, NULL, NULL);
- simple_draw = DRAW_ALL;
-
- wdViewport(0,w-1,0,h-1);
- if (w>h)
- wdWindow(0,(double)w/(double)h,0,1);
- else
- wdWindow(0,1,0,(double)h/(double)w);
-
/* Clear the background to be white */
- cdBackground(CD_WHITE);
+ cdCanvasBackground(canvas, CD_WHITE);
// cdBackground(CD_GREEN);
- cdClear();
-
- cdLineWidth(3);
- cdForeground(cdEncodeAlpha(CD_DARK_MAGENTA, 128));
- cdRect(100, 200, 100, 200);
-
- cdBegin(CD_OPEN_LINES);
- cdVertex(300, 250);
- cdVertex(320, 270);
- cdVertex(350, 260);
- cdVertex(340, 200);
- cdVertex(310, 210);
- cdEnd();
+ cdCanvasClear(canvas);
+
+ /* Draw a reactangle and a polyline at the bottom-left area,
+ using a thick line with transparency.
+ Observe that transparency is only supported in a few drivers,
+ and line join is not supported in the IMAGERGB driver. */
+ cdCanvasLineWidth(canvas, 3);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+ cdCanvasForeground(canvas, cdEncodeAlpha(CD_DARK_MAGENTA, 128));
+ cdCanvasRect(canvas, 100, 200, 100, 200);
+
+ cdCanvasBegin(canvas, CD_OPEN_LINES);
+ cdCanvasVertex(canvas, 300, 250);
+ cdCanvasVertex(canvas, 320, 270);
+ cdCanvasVertex(canvas, 350, 260);
+ cdCanvasVertex(canvas, 340, 200);
+ cdCanvasVertex(canvas, 310, 210);
+ cdCanvasEnd(canvas);
- cdInteriorStyle(CD_SOLID);
-
- cdForeground(CD_RED);
- cdLineWidth(3);
+ /* Draw the red diagonal line with a custom line style.
+ Observe that line styles are not supported in the IMAGERGB driver. */
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasLineWidth(canvas, 3);
{
int dashes[] = {20, 15, 5, 5};
- cdLineStyleDashes(dashes, 4);
+ cdCanvasLineStyleDashes(canvas, dashes, 4);
}
- cdLineStyle(CD_CUSTOM);
- cdLine(0, 0, w-1, h-1);
+ cdCanvasLineStyle(canvas, CD_CUSTOM);
+ cdCanvasLine(canvas, 0, 0, w-1, h-1);
- cdForeground(CD_BLUE);
- cdLineWidth(10);
- cdLineStyle(CD_DOTTED);
- //cdLine(0, 0, 500, 500);
-// wdLine(0, 1, 1, 0);
- cdLine(0, h-1, w-1, 0);
+ /* Draw the blue diagonal line with a pre-defined line style.
+ Observe that the pre-defined line style is dependent on the driver. */
+ cdCanvasForeground(canvas, CD_BLUE);
+ cdCanvasLineWidth(canvas, 10);
+ cdCanvasLineStyle(canvas, CD_DOTTED);
+ cdCanvasLine(canvas, 0, h-1, w-1, 0);
switch(clipping)
{
case CD_CLIPOFF:
- cdClip(CD_CLIPOFF);
+ cdCanvasClip(canvas, CD_CLIPOFF);
break;
case CD_CLIPAREA:
/* Defines the clipping area equals the canvas area minus a 100 pixels margin. */
- cdClipArea(100, w - 100, 100, h - 100);
- cdClip(CD_CLIPAREA);
+ cdCanvasClipArea(canvas, 100, w - 100, 100, h - 100);
+ cdCanvasClip(canvas, CD_CLIPAREA);
break;
case CD_CLIPPOLYGON:
- cdBegin(CD_CLIP);
- cdVertex(100, 100);
- cdVertex(w - 100, 100);
- cdVertex(w / 2, h - 100);
- cdEnd();
- cdClip(CD_CLIPPOLYGON);
+ cdCanvasBegin(canvas, CD_CLIP);
+ cdCanvasVertex(canvas, 100, 100);
+ cdCanvasVertex(canvas, w - 100, 100);
+ cdCanvasVertex(canvas, w / 2, h - 100);
+ cdCanvasEnd(canvas);
+ cdCanvasClip(canvas, CD_CLIPPOLYGON);
break;
case CD_CLIPREGION:
- cdTextAlignment(CD_CENTER);
- cdFont(CD_TIMES_ROMAN, CD_BOLD, 50);
-
- cdBegin(CD_REGION);
- cdRegionCombineMode(CD_UNION);
- cdBox(100, 200, 100, 200);
- cdSector(w/2-50, h/2+50, 150, 150, 0, 360);
- cdSector(w/2-50, h/2-50, 150, 150, 0, 360);
- cdSector(w/2+50, h/2+50, 150, 150, 0, 360);
- cdSector(w/2+50, h/2-50, 150, 150, 0, 360);
- cdRegionCombineMode(CD_DIFFERENCE);
- cdText(w/2, h/2, "TEXT");
- cdEnd();
-// cdOffsetRegion(-50, 50);
- cdClip(CD_CLIPREGION);
-
- cdForeground(CD_DARK_RED);
- cdBox(0,w,0,h);
+ cdCanvasTextAlignment(canvas, CD_CENTER);
+ cdCanvasFont(canvas, "Times", CD_BOLD, 50);
+
+ cdCanvasBegin(canvas, CD_REGION);
+ cdCanvasRegionCombineMode(canvas, CD_UNION);
+ cdCanvasBox(canvas, 100, 200, 100, 200);
+ cdCanvasSector(canvas, w/2-50, h/2+50, 150, 150, 0, 360);
+ cdCanvasSector(canvas, w/2-50, h/2-50, 150, 150, 0, 360);
+ cdCanvasSector(canvas, w/2+50, h/2+50, 150, 150, 0, 360);
+ cdCanvasSector(canvas, w/2+50, h/2-50, 150, 150, 0, 360);
+ cdCanvasRegionCombineMode(canvas, CD_DIFFERENCE);
+ cdCanvasText(canvas, w/2, h/2, "TEXT");
+ cdCanvasEnd(canvas);
+// cdCanvasOffsetRegion(canvas, -50, 50);
+ cdCanvasClip(canvas, CD_CLIPREGION);
+
+ cdCanvasForeground(canvas, CD_DARK_RED);
+ cdCanvasBox(canvas, 0,w,0,h);
break;
}
switch(write_mode)
{
case CD_REPLACE:
- cdWriteMode(CD_REPLACE);
+ cdCanvasWriteMode(canvas, CD_REPLACE);
break;
case CD_XOR:
- cdWriteMode(CD_XOR);
+ cdCanvasWriteMode(canvas, CD_XOR);
break;
case CD_NOT_XOR:
- cdWriteMode(CD_NOT_XOR);
+ cdCanvasWriteMode(canvas, CD_NOT_XOR);
break;
}
if (use_transform)
{
- cdCanvasTransform(cdActiveCanvas(), NULL);
- cdCanvasTransformTranslate(cdActiveCanvas(), w/2, h/2);
- cdCanvasTransformRotate(cdActiveCanvas(), 30);
- cdCanvasTransformScale(cdActiveCanvas(), 0.5, 0.5);
- cdCanvasTransformTranslate(cdActiveCanvas(), -w/2, -h/2);
+ cdCanvasTransform(canvas, NULL);
+ cdCanvasTransformTranslate(canvas, w/2, h/2);
+ cdCanvasTransformRotate(canvas, 30);
+ cdCanvasTransformScale(canvas, 0.5, 0.5);
+ cdCanvasTransformTranslate(canvas, -w/2, -h/2);
}
// cdSetfAttribute("ROTATE", "15 %d %d", w/2, h/2);
- cdLineStyle(CD_CONTINUOUS);
- cdLineWidth(1);
- cdBackOpacity(CD_TRANSPARENT);
-
- cdForeground(CD_MAGENTA);
- cdSector(w-100, 100, 100, 100, 50, 180);
- cdForeground(CD_RED);
- cdArc(100, 100, 100, 100, 50, 180);
-
- cdForeground(CD_YELLOW);
- cdBox(w/2 - 100, w/2 + 100, h/2 - 100, h/2 + 100);
-
- cdTextAlignment(CD_CENTER);
- cdTextOrientation(70);
- cdFont(CD_TIMES_ROMAN, CD_BOLD, 24);
-
+ /* Reset line style and width */
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+ cdCanvasLineWidth(canvas, 1);
+// cdBackOpacity(CD_TRANSPARENT);
+
+ /* Draw an arc at bottom-left, and a sector at bottom-right.
+ Notice that counter-clockwise orientation of both. */
+ cdCanvasInteriorStyle(canvas, CD_SOLID);
+ cdCanvasForeground(canvas, CD_MAGENTA);
+ cdCanvasSector(canvas, w-100, 100, 100, 100, 50, 180);
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasArc(canvas, 100, 100, 100, 100, 50, 180);
+
+ /* Draw a solid filled rectangle at center. */
+ cdCanvasForeground(canvas, CD_YELLOW);
+ cdCanvasBox(canvas, w/2 - 100, w/2 + 100, h/2 - 100, h/2 + 100);
+
+ /* Prepare font for text. */
+ cdCanvasTextAlignment(canvas, CD_CENTER);
+ cdCanvasTextOrientation(canvas, 70);
+ cdCanvasFont(canvas, "Times", CD_BOLD, 24);
+
+ /* Draw text at center, with orientation,
+ and draw its bounding box.
+ Notice that in some drivers the bounding box is not precise. */
{
int rect[8];
- cdTextBounds(w/2, h/2, "cdMin Draw (çãí)", rect);
- cdForeground(CD_RED);
- cdBegin(CD_CLOSED_LINES);
- cdVertex(rect[0], rect[1]);
- cdVertex(rect[2], rect[3]);
- cdVertex(rect[4], rect[5]);
- cdVertex(rect[6], rect[7]);
- cdEnd();
+ cdCanvasGetTextBounds(canvas, w/2, h/2, "Simple Draw (pçãí)", rect);
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasBegin(canvas, CD_CLOSED_LINES);
+ cdCanvasVertex(canvas, rect[0], rect[1]);
+ cdCanvasVertex(canvas, rect[2], rect[3]);
+ cdCanvasVertex(canvas, rect[4], rect[5]);
+ cdCanvasVertex(canvas, rect[6], rect[7]);
+ cdCanvasEnd(canvas);
}
- cdForeground(CD_BLUE);
- cdText(w/2, h/2, "cdMin Draw (çãí)");
- cdTextOrientation(0);
+ cdCanvasForeground(canvas, CD_BLUE);
+ cdCanvasText(canvas, w/2, h/2, "Simple Draw (pçãí)");
+ cdCanvasTextOrientation(canvas, 0);
- wdBox(0.20, 0.30, 0.40, 0.50);
- cdForeground(CD_RED);
- wdLine(0.20, 0.40, 0.30, 0.50);
+ /* Prepare World Coordinates */
+ wdCanvasViewport(canvas, 0,w-1,0,h-1);
+ if (w>h)
+ wdCanvasWindow(canvas, 0,(double)w/(double)h,0,1);
+ else
+ wdCanvasWindow(canvas, 0,1,0,(double)h/(double)w);
+
+ /* Draw a filled blue rectangle in WC */
+ wdCanvasBox(canvas, 0.20, 0.30, 0.40, 0.50);
+ cdCanvasForeground(canvas, CD_RED);
+ /* Draw the diagonal of that rectangle in WC */
+ wdCanvasLine(canvas, 0.20, 0.40, 0.30, 0.50);
// wdVectorTextDirection(0, 0, 1, 1);
- wdVectorCharSize(0.07);
+ /* Prepare Vector Text in WC. */
+ wdCanvasVectorCharSize(canvas, 0.07);
// wdVectorText(0.1, 0.4, "ñç áéíóú àèìòù âêîôû äëïöü");
// wdVectorText(0.1, 0.2, "ÑÇ ÁÉÍÓÚ ÀÈÌÒÙ ÂÊÎÔÛ ÄËÏÖÜ");
@@ -684,115 +777,158 @@ int SimpleDrawAll(void)
// }
//}
+ /* Draw vector text, and draw its bounding box.
+ We also use this text to show when we are using a contextplus driver. */
{
double rect[8];
- cdForeground(CD_RED);
- if (gdpiplus)
- wdGetVectorTextBounds("WDj-Plus", 0.25, 0.35, rect);
+ cdCanvasForeground(canvas, CD_RED);
+ if (contextplus)
+ wdCanvasGetVectorTextBounds(canvas, "WDj-Plus", 0.25, 0.35, rect);
+ else
+ wdCanvasGetVectorTextBounds(canvas, "WDj", 0.25, 0.35, rect);
+ cdCanvasBegin(canvas, CD_CLOSED_LINES);
+ wdCanvasVertex(canvas, rect[0], rect[1]);
+ wdCanvasVertex(canvas, rect[2], rect[3]);
+ wdCanvasVertex(canvas, rect[4], rect[5]);
+ wdCanvasVertex(canvas, rect[6], rect[7]);
+ cdCanvasEnd(canvas);
+
+ cdCanvasLineWidth(canvas, 2);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+ if (contextplus)
+ wdCanvasVectorText(canvas, 0.25, 0.35, "WDj-Plus");
else
- wdGetVectorTextBounds("WDj", 0.25, 0.35, rect);
- cdBegin(CD_CLOSED_LINES);
- wdVertex(rect[0], rect[1]);
- wdVertex(rect[2], rect[3]);
- wdVertex(rect[4], rect[5]);
- wdVertex(rect[6], rect[7]);
- cdEnd();
+ wdCanvasVectorText(canvas, 0.25, 0.35, "WDj");
+ cdCanvasLineWidth(canvas, 1);
}
- cdPixel(10, h/2+0, CD_RED);
- cdPixel(11, h/2+1, CD_GREEN);
- cdPixel(12, h/2+2, CD_BLUE);
-
- /* draws all the mark type possibilities */
- cdForeground(CD_RED);
- cdMarkSize(30);
- cdMarkType(CD_PLUS);
- cdMark(200, 200);
- cdMarkType(CD_CIRCLE);
- cdMark(w - 200, 200);
- cdMarkType(CD_HOLLOW_CIRCLE);
- cdMark(200, h - 200);
- cdMarkType(CD_DIAMOND);
- cdMark(w - 200, h - 200);
-
- /* draws all the line style possibilities */
- cdLineWidth(1);
- cdLineStyle(CD_CONTINUOUS);
- cdLine(0, 10, w, 10);
- cdLineStyle(CD_DASHED);
- cdLine(0, 20, w, 20);
- cdLineStyle(CD_DASH_DOT);
- cdLine(0, 30, w, 30);
- cdLineStyle(CD_DASH_DOT_DOT);
- cdLine(0, 40, w, 40);
-
- /* draws all the hatch style possibilities */
- cdHatch(CD_VERTICAL);
- cdBox(0, 50, h - 60, h);
- cdHatch(CD_FDIAGONAL);
- cdBox(50, 100, h - 60, h);
- cdHatch(CD_BDIAGONAL);
- cdBox(100, 150, h - 60, h);
- cdHatch(CD_CROSS);
- cdBox(150, 200, h - 60, h);
- cdHatch(CD_HORIZONTAL);
- cdBox(200, 250, h - 60, h);
- cdHatch(CD_DIAGCROSS);
- cdBox(250, 300, h - 60, h);
-
- /* closed polygon */
- cdBegin(CD_CLOSED_LINES);
- cdVertex(w/2, h - 100);
- cdVertex(w/2 + 50, h - 150);
- cdVertex(w/2, h - 200);
- cdVertex(w/2 - 50, h - 150);
- cdEnd();
-
- /* hatch filled polygon */
- cdHatch(CD_DIAGCROSS);
- cdBegin(CD_FILL);
- cdVertex(100, h/2);
- cdVertex(150, h/2 + 50);
- cdVertex(200, h/2);
- cdVertex(150, h/2 - 50);
- cdEnd();
-
- /* pattern filled polygon */
- cdPattern(STYLE_SIZE, STYLE_SIZE, pattern);
- cdBegin(CD_FILL);
- cdVertex(w - 100, h/2);
- cdVertex(w - 150, h/2 + 50);
- cdVertex(w - 200, h/2);
- cdVertex(w - 150, h/2 - 50);
- cdEnd();
+ /* Draw a filled path at center-right (looks like a weird fish).
+ Notice that in PDF the arc is necessarily a circle arc, and not an ellipse. */
+ cdCanvasForeground(canvas, CD_GREEN);
+ cdCanvasBegin(canvas, CD_PATH);
+ cdCanvasPathSet(canvas, CD_PATH_MOVETO);
+ cdCanvasVertex(canvas, w/2 + 200, h/2);
+ cdCanvasPathSet(canvas, CD_PATH_LINETO);
+ cdCanvasVertex(canvas, w/2 + 230, h/2 + 50);
+ cdCanvasPathSet(canvas, CD_PATH_LINETO);
+ cdCanvasVertex(canvas, w/2 + 250, h/2 + 50);
+ cdCanvasPathSet(canvas, CD_PATH_CURVETO);
+ cdCanvasVertex(canvas, w/2+150+150, h/2+200-50); /* control point for start */
+ cdCanvasVertex(canvas, w/2+150+180, h/2+250-50); /* control point for end */
+ cdCanvasVertex(canvas, w/2+150+180, h/2+200-50); /* end point */
+ cdCanvasPathSet(canvas, CD_PATH_CURVETO);
+ cdCanvasVertex(canvas, w/2+150+180, h/2+150-50);
+ cdCanvasVertex(canvas, w/2+150+150, h/2+100-50);
+ cdCanvasVertex(canvas, w/2+150+300, h/2+100-50);
+ cdCanvasPathSet(canvas, CD_PATH_LINETO);
+ cdCanvasVertex(canvas, w/2+150+300, h/2-50);
+ cdCanvasPathSet(canvas, CD_PATH_ARC);
+ cdCanvasVertex(canvas, w/2+300, h/2); /* center */
+ cdCanvasVertex(canvas, 200, 100); /* width, height */
+ cdCanvasVertex(canvas, -30*1000, -170*1000); /* start angle, end angle (degrees / 1000) */
+// cdCanvasPathSet(canvas, CD_PATH_CLOSE);
+// cdCanvasPathSet(canvas, CD_PATH_STROKE);
+ cdCanvasPathSet(canvas, CD_PATH_FILL);
+// cdCanvasPathSet(canvas, CD_PATH_FILLSTROKE);
+ cdCanvasEnd(canvas);
+
+ /* Draw 3 pixels at center left. */
+ cdCanvasPixel(canvas, 10, h/2+0, CD_RED);
+ cdCanvasPixel(canvas, 11, h/2+1, CD_GREEN);
+ cdCanvasPixel(canvas, 12, h/2+2, CD_BLUE);
+
+ /* Draw 4 mark types, distributed near each corner. */
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasMarkSize(canvas, 30);
+ cdCanvasMarkType(canvas, CD_PLUS);
+ cdCanvasMark(canvas, 200, 200);
+ cdCanvasMarkType(canvas, CD_CIRCLE);
+ cdCanvasMark(canvas, w - 200, 200);
+ cdCanvasMarkType(canvas, CD_HOLLOW_CIRCLE);
+ cdCanvasMark(canvas, 200, h - 200);
+ cdCanvasMarkType(canvas, CD_DIAMOND);
+ cdCanvasMark(canvas, w - 200, h - 200);
+
+ /* Draw all the line style possibilities at bottom.
+ Notice that they have some small differences between drivers. */
+ cdCanvasLineWidth(canvas, 1);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
+ cdCanvasLine(canvas, 0, 10, w, 10);
+ cdCanvasLineStyle(canvas, CD_DASHED);
+ cdCanvasLine(canvas, 0, 20, w, 20);
+ cdCanvasLineStyle(canvas, CD_DOTTED);
+ cdCanvasLine(canvas, 0, 30, w, 30);
+ cdCanvasLineStyle(canvas, CD_DASH_DOT);
+ cdCanvasLine(canvas, 0, 40, w, 40);
+ cdCanvasLineStyle(canvas, CD_DASH_DOT_DOT);
+ cdCanvasLine(canvas, 0, 50, w, 50);
+
+ /* Draw all the hatch style possibilities in the top-left corner.
+ Notice that they have some small differences between drivers. */
+ cdCanvasHatch(canvas, CD_VERTICAL);
+ cdCanvasBox(canvas, 0, 50, h - 60, h);
+ cdCanvasHatch(canvas, CD_FDIAGONAL);
+ cdCanvasBox(canvas, 50, 100, h - 60, h);
+ cdCanvasHatch(canvas, CD_BDIAGONAL);
+ cdCanvasBox(canvas, 100, 150, h - 60, h);
+ cdCanvasHatch(canvas, CD_CROSS);
+ cdCanvasBox(canvas, 150, 200, h - 60, h);
+ cdCanvasHatch(canvas, CD_HORIZONTAL);
+ cdCanvasBox(canvas, 200, 250, h - 60, h);
+ cdCanvasHatch(canvas, CD_DIAGCROSS);
+ cdCanvasBox(canvas, 250, 300, h - 60, h);
+
+ /* Draw 4 regions, in diamond shape,
+ at top, bottom, left, right,
+ using different interior styles. */
+
+ /* At top, not filled polygon, notice that the last line style is used. */
+ cdCanvasBegin(canvas, CD_CLOSED_LINES);
+ cdCanvasVertex(canvas, w/2, h - 100);
+ cdCanvasVertex(canvas, w/2 + 50, h - 150);
+ cdCanvasVertex(canvas, w/2, h - 200);
+ cdCanvasVertex(canvas, w/2 - 50, h - 150);
+ cdCanvasEnd(canvas);
+
+ /* At left, hatch filled polygon */
+ cdCanvasHatch(canvas, CD_DIAGCROSS);
+ cdCanvasBegin(canvas, CD_FILL);
+ cdCanvasVertex(canvas, 100, h/2);
+ cdCanvasVertex(canvas, 150, h/2 + 50);
+ cdCanvasVertex(canvas, 200, h/2);
+ cdCanvasVertex(canvas, 150, h/2 - 50);
+ cdCanvasEnd(canvas);
+
+ /* At right, pattern filled polygon */
+ cdCanvasPattern(canvas, STYLE_SIZE, STYLE_SIZE, pattern);
+ cdCanvasBegin(canvas, CD_FILL);
+ cdCanvasVertex(canvas, w - 100, h/2);
+ cdCanvasVertex(canvas, w - 150, h/2 + 50);
+ cdCanvasVertex(canvas, w - 200, h/2);
+ cdCanvasVertex(canvas, w - 150, h/2 - 50);
+ cdCanvasEnd(canvas);
- /* stipple filled polygon */
- cdStipple(STYLE_SIZE, STYLE_SIZE, stipple);
- cdBegin(CD_FILL);
- cdVertex(w/2, 100);
- cdVertex(w/2 + 50, 150);
- cdVertex(w/2, 200);
- cdVertex(w/2 - 50, 150);
- cdEnd();
-
- cdBegin(CD_BEZIER);
- cdVertex(100, 100);
- cdVertex(150, 200);
- cdVertex(180, 250);
- cdVertex(180, 200);
- cdVertex(180, 150);
- cdVertex(150, 100);
- cdVertex(300, 100);
- cdEnd();
-
- cdLineWidth(2);
- cdLineStyle(CD_CONTINUOUS);
- if (gdpiplus)
- wdVectorText(0.25, 0.35, "WDj-Plus");
- else
- wdVectorText(0.25, 0.35, "WDj");
-
- /* always clear the image buffer contents */
+ /* At bottom, stipple filled polygon */
+ cdCanvasStipple(canvas, STYLE_SIZE, STYLE_SIZE, stipple);
+ cdCanvasBegin(canvas, CD_FILL);
+ cdCanvasVertex(canvas, w/2, 100);
+ cdCanvasVertex(canvas, w/2 + 50, 150);
+ cdCanvasVertex(canvas, w/2, 200);
+ cdCanvasVertex(canvas, w/2 - 50, 150);
+ cdCanvasEnd(canvas);
+
+ /* Draw two beziers at bottom-left */
+ cdCanvasBegin(canvas, CD_BEZIER);
+ cdCanvasVertex(canvas, 100, 100);
+ cdCanvasVertex(canvas, 150, 200);
+ cdCanvasVertex(canvas, 180, 250);
+ cdCanvasVertex(canvas, 180, 200);
+ cdCanvasVertex(canvas, 180, 150);
+ cdCanvasVertex(canvas, 150, 100);
+ cdCanvasVertex(canvas, 300, 100);
+ cdCanvasEnd(canvas);
+
+ /* Initialize the image buffer contents */
//#define IMAGE_SIZE 16
memset(red, 0xFF, IMAGE_SIZE*IMAGE_SIZE/2);
memset(green, 0x5F, IMAGE_SIZE*IMAGE_SIZE/2);
@@ -828,138 +964,136 @@ int SimpleDrawAll(void)
// cdPutImageRGB(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, 100, h - 200, IMAGE_SIZE, IMAGE_SIZE);
// cdPutImageRGBA(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, alpha, 100, h - 200, IMAGE_SIZE, IMAGE_SIZE);
- cdPutImageRGB(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE);
-// cdPutImageRGBA(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, alpha, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE);
+// cdPutImageRGB(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE);
+ /* Draw the image on the top-right corner but increasing its actual size, and uses its full area */
+ cdCanvasPutImageRectRGBA(canvas, IMAGE_SIZE, IMAGE_SIZE, red, green, blue, alpha, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE, 0, 0, 0, 0);
- cdSetAttribute("ROTATE", NULL);
+ cdCanvasSetAttribute(canvas, "ROTATE", NULL);
if (use_transform)
- cdCanvasTransform(cdActiveCanvas(), NULL);
- cdClip(CD_CLIPOFF);
- cdFlush();
-
- return 0;
+ cdCanvasTransform(canvas, NULL);
+ cdCanvasClip(canvas, CD_CLIPOFF);
}
-void DrawVectorTextBox(int x, int y, char* text)
+void DrawVectorTextBox(cdCanvas* canvas, int x, int y, char* text)
{
int rect[8], draw_box;
- cdLineWidth(1);
- cdLineStyle(CD_CONTINUOUS);
+ cdCanvasLineWidth(canvas, 1);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
draw_box = 0;
if (draw_box)
{
int xmin, xmax, ymin, ymax;
- cdCanvasGetVectorTextBox(cdActiveCanvas(), x, y, text, &xmin, &xmax, &ymin, &ymax);
- cdForeground(CD_GREEN);
- cdRect(xmin, xmax, ymin, ymax);
+ cdCanvasGetVectorTextBox(canvas, x, y, text, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasForeground(canvas, CD_GREEN);
+ cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
- if (cdTextOrientation(CD_QUERY) == 0)
+ if (cdCanvasTextOrientation(canvas, CD_QUERY) == 0)
{
- cdForeground(CD_RED);
- cdLine(xmin, y, xmax, y);
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasLine(canvas, xmin, y, xmax, y);
}
}
else
{
/* bounding box */
- cdGetVectorTextBounds(text, x, y, rect);
- cdForeground(CD_GREEN);
- cdBegin(CD_CLOSED_LINES);
- cdVertex(rect[0], rect[1]);
- cdVertex(rect[2], rect[3]);
- cdVertex(rect[4], rect[5]);
- cdVertex(rect[6], rect[7]);
- cdEnd();
+ cdCanvasGetVectorTextBounds(canvas, text, x, y, rect);
+ cdCanvasForeground(canvas, CD_GREEN);
+ cdCanvasBegin(canvas, CD_CLOSED_LINES);
+ cdCanvasVertex(canvas, rect[0], rect[1]);
+ cdCanvasVertex(canvas, rect[2], rect[3]);
+ cdCanvasVertex(canvas, rect[4], rect[5]);
+ cdCanvasVertex(canvas, rect[6], rect[7]);
+ cdCanvasEnd(canvas);
}
/* reference point */
- cdForeground(CD_BLUE);
- cdMarkType(CD_PLUS);
- cdMarkSize(30);
- cdMark(x, y);
+ cdCanvasForeground(canvas, CD_BLUE);
+ cdCanvasMarkType(canvas, CD_PLUS);
+ cdCanvasMarkSize(canvas, 30);
+ cdCanvasMark(canvas, x, y);
- cdForeground(CD_BLACK);
- cdVectorText(x, y, text);
+ cdCanvasForeground(canvas, CD_BLACK);
+ cdCanvasVectorText(canvas, x, y, text);
}
-void DrawTextBox(int x, int y, char* text)
+void DrawTextBox(cdCanvas* canvas, int x, int y, char* text)
{
int rect[8], draw_box;
- cdLineWidth(1);
- cdLineStyle(CD_CONTINUOUS);
+ cdCanvasLineWidth(canvas, 1);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
draw_box = 0;
if (draw_box)
{
int xmin, xmax, ymin, ymax;
- cdTextBox(x, y, text, &xmin, &xmax, &ymin, &ymax);
- cdRect(xmin, xmax, ymin, ymax);
+ cdCanvasGetTextBox(canvas, x, y, text, &xmin, &xmax, &ymin, &ymax);
+ cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
- if (cdTextOrientation(CD_QUERY) == 0)
+ if (cdCanvasTextOrientation(canvas, CD_QUERY) == 0)
{
- cdForeground(CD_RED);
- cdLine(xmin, y, xmax, y);
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasLine(canvas, xmin, y, xmax, y);
}
}
else
{
/* bounding box */
- cdTextBounds(x, y, text, rect);
- cdForeground(CD_GREEN);
- cdBegin(CD_CLOSED_LINES);
- cdVertex(rect[0], rect[1]);
- cdVertex(rect[2], rect[3]);
- cdVertex(rect[4], rect[5]);
- cdVertex(rect[6], rect[7]);
- cdEnd();
+ cdCanvasGetTextBounds(canvas, x, y, text, rect);
+ cdCanvasForeground(canvas, CD_GREEN);
+ cdCanvasBegin(canvas, CD_CLOSED_LINES);
+ cdCanvasVertex(canvas, rect[0], rect[1]);
+ cdCanvasVertex(canvas, rect[2], rect[3]);
+ cdCanvasVertex(canvas, rect[4], rect[5]);
+ cdCanvasVertex(canvas, rect[6], rect[7]);
+ cdCanvasEnd(canvas);
}
/* reference point */
- cdForeground(CD_BLUE);
- cdMarkType(CD_PLUS);
- cdMarkSize(30);
- cdMark(x, y);
+ cdCanvasForeground(canvas, CD_BLUE);
+ cdCanvasMarkType(canvas, CD_PLUS);
+ cdCanvasMarkSize(canvas, 30);
+ cdCanvasMark(canvas, x, y);
- cdForeground(CD_BLACK);
- cdText(x, y, text);
+ cdCanvasForeground(canvas, CD_BLACK);
+ cdCanvasText(canvas, x, y, text);
}
-int SimpleDrawTextAlign(void)
+void SimpleDrawTextAlign(cdCanvas* canvas)
{
int w, h, i, xoff, yoff, use_vector;
int text_aligment[] = {
- CD_NORTH,
- CD_SOUTH,
- CD_EAST,
- CD_WEST,
- CD_NORTH_EAST,
- CD_NORTH_WEST,
- CD_SOUTH_EAST,
- CD_SOUTH_WEST,
- CD_CENTER,
- CD_BASE_CENTER,
- CD_BASE_RIGHT,
- CD_BASE_LEFT
+ CD_NORTH,
+ CD_SOUTH,
+ CD_EAST,
+ CD_WEST,
+ CD_NORTH_EAST,
+ CD_NORTH_WEST,
+ CD_SOUTH_EAST,
+ CD_SOUTH_WEST,
+ CD_CENTER,
+ CD_BASE_CENTER,
+ CD_BASE_RIGHT,
+ CD_BASE_LEFT
};
#if 1
char* text_aligment_str[] = {
- "North (Ãyj)\nSecond Line (Ãyj)",
- "South (Ãyj)\nSecond Line (Ãyj)",
- "East (Ãyj)\nSecond Line (Ãyj)",
- "West (Ãyj)\nSecond Line (Ãyj)",
- "North East (Ãyj)\nSecond Line (Ãyj)",
- "North West (Ãyj)\nSecond Line (Ãyj)",
- "South East (Ãyj)\nSecond Line (Ãyj)",
- "South West (Ãyj)\nSecond Line (Ãyj)",
- "Center (Ãyj)\nSecond Line (Ãyj)",
- "Base Center (Ãyj)\nSecond Line (Ãyj)",
- "Base Right (Ãyj)\nSecond Line (Ãyj)",
- "Base Left (Ãyj)\nSecond Line (Ãyj)"
+ "North (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "South (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "East (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "West (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "North East (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "North West (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "South East (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "South West (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "Center (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "Base Center (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "Base Right (Ãyj)\nSecond Line (Ãyj)\nThird Line",
+ "Base Left (Ãyj)\nSecond Line (Ãyj)\nThird Line"
};
#else
char* text_aligment_str[] = {
@@ -978,90 +1112,83 @@ int SimpleDrawTextAlign(void)
};
#endif
- cdGetCanvasSize(&w, &h, 0, 0);
-
- cdBackground(CD_WHITE);
- cdClear();
+ cdCanvasGetSize(canvas, &w, &h, 0, 0);
- simple_draw = DRAW_TEXTALIGN;
+ cdCanvasBackground(canvas, CD_WHITE);
+ cdCanvasClear(canvas);
use_vector = 0;
#if 0
if (use_vector)
- cdVectorTextDirection(0, 0, 1, 1);
+ cdCanvasVectorTextDirection(canvas, 0, 0, 1, 1);
else
- cdTextOrientation(45);
+ cdCanvasTextOrientation(canvas, 45);
#endif
xoff = w/4;
yoff = h/7;
if (use_vector)
- cdVectorCharSize(30);
+ cdCanvasVectorCharSize(canvas, 30);
else
{
- //cdFont(CD_TIMES_ROMAN, CD_PLAIN, 14);
- cdFont(CD_HELVETICA, CD_PLAIN, 24);
+ //cdCanvasFont(canvas, "Times", CD_PLAIN, 14);
+ cdCanvasFont(canvas, "Helvetica", CD_PLAIN, 24);
}
for (i = 0; i < 12; i++)
{
- cdTextAlignment(text_aligment[i]);
+ cdCanvasTextAlignment(canvas, text_aligment[i]);
if (i < 6)
{
if (use_vector)
- DrawVectorTextBox(xoff, yoff*(i+1), text_aligment_str[i]);
+ DrawVectorTextBox(canvas, xoff, yoff*(i+1), text_aligment_str[i]);
else
- DrawTextBox(xoff, yoff*(i+1), text_aligment_str[i]);
+ DrawTextBox(canvas, xoff, yoff*(i+1), text_aligment_str[i]);
}
else
{
if (use_vector)
- DrawVectorTextBox(3*xoff, yoff*(i-5), text_aligment_str[i]);
+ DrawVectorTextBox(canvas, 3*xoff, yoff*(i-5), text_aligment_str[i]);
else
- DrawTextBox(3*xoff, yoff*(i-5), text_aligment_str[i]);
+ DrawTextBox(canvas, 3*xoff, yoff*(i-5), text_aligment_str[i]);
}
}
-
- cdFlush();
- return 0;
}
-void DrawTextFont(int font, int size, int xoff, int yoff, char* text)
+void DrawTextFont(cdCanvas* canvas, const char* font, int size, int xoff, int yoff, char* text)
{
- cdFont(font, CD_PLAIN, size);
- DrawTextBox(xoff, yoff, text);
+ cdCanvasFont(canvas, font, CD_PLAIN, size);
+ DrawTextBox(canvas, xoff, yoff, text);
- cdFont(font, CD_BOLD, size);
- DrawTextBox(2*xoff, yoff, text);
+ cdCanvasFont(canvas, font, CD_BOLD, size);
+ DrawTextBox(canvas, 2*xoff, yoff, text);
- cdFont(font, CD_ITALIC, size);
- DrawTextBox(3*xoff, yoff, text);
+ cdCanvasFont(canvas, font, CD_ITALIC, size);
+ DrawTextBox(canvas, 3*xoff, yoff, text);
- cdFont(font, CD_BOLD_ITALIC, size);
- DrawTextBox(4*xoff, yoff, text);
+ cdCanvasFont(canvas, font, CD_BOLD_ITALIC, size);
+ DrawTextBox(canvas, 4*xoff, yoff, text);
}
-int SimpleDrawTextFonts(void)
+void SimpleDrawTextFonts(cdCanvas* canvas)
{
int xoff, yoff, size;
- cdBackground(CD_WHITE);
- cdClear();
-
- simple_draw = DRAW_TEXTFONTS;
+ cdCanvasBackground(canvas, CD_WHITE);
+ cdCanvasClear(canvas);
xoff = 470;
yoff = 150;
size = -30;
- cdTextAlignment(CD_CENTER);
+ cdCanvasTextAlignment(canvas, CD_CENTER);
- DrawTextFont(CD_COURIER, size, xoff, yoff, "Courier");
- DrawTextFont(CD_TIMES_ROMAN, size, xoff, 2*yoff, "Times Roman");
- DrawTextFont(CD_HELVETICA, size, xoff, 3*yoff, "Helvetica");
- DrawTextFont(CD_SYSTEM, size, xoff, 4*yoff, "System");
+ DrawTextFont(canvas, "Courier", size, xoff, yoff, "Courier");
+ DrawTextFont(canvas, "Times", size, xoff, 2*yoff, "Times Roman");
+ DrawTextFont(canvas, "Helvetica", size, xoff, 3*yoff, "Helvetica");
+ DrawTextFont(canvas, "System", size, xoff, 4*yoff, "System");
{
// static char native[50] = "Tecmedia, -60";
@@ -1094,26 +1221,21 @@ int SimpleDrawTextFonts(void)
//cdText(10, 160, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
//cdText(10, 260, "1234567890");
//cdText(500, 360, "'\"!@#$%¨&*()_+-=[]^/;.,");
-
- cdFlush();
- return 0;
}
-//void SimpleDrawTest(void)
-void SimpleDrawMainTest(void)
+void SimpleDrawTest(cdCanvas* canvas)
+//void SimpleDrawMainTest(cdCanvas* canvas)
{
long pattern[16]; /* 4x4 pattern */
int w, h;
int xmin, xmax, ymin, ymax;
- simple_draw = DRAW_TEST;
-
/* notice that if we are not using world coordinates
it is harder to position all the objetcs we want. */
- cdGetCanvasSize(&w, &h, 0, 0);
+ cdCanvasGetSize(canvas, &w, &h, 0, 0);
- cdBackground(CD_WHITE);
- cdClear();
+ cdCanvasBackground(canvas, CD_WHITE);
+ cdCanvasClear(canvas);
/* pattern initialization */
pattern[0] = CD_RED; pattern[1] = CD_RED; /* first line */
@@ -1126,55 +1248,55 @@ void SimpleDrawMainTest(void)
pattern[14] = CD_YELLOW; pattern[15] = CD_YELLOW;
/* set the line attributes */
- cdLineWidth(4);
- cdLineStyle(CD_CONTINUOUS);
+ cdCanvasLineWidth(canvas, 4);
+ cdCanvasLineStyle(canvas, CD_CONTINUOUS);
/* in the center draw a pattern pizza
with a slice mising */
- cdPattern(4, 4, pattern);
- cdSector(w/2, h/2, w/2, h/2, 45, 0);
+ cdCanvasPattern(canvas, 4, 4, pattern);
+ cdCanvasSector(canvas, w/2, h/2, w/2, h/2, 45, 0);
/* draws a dark red border */
- cdForeground(CD_DARK_RED);
- cdInteriorStyle(CD_HOLLOW);
- cdSector(w/2, h/2, w/2, h/2, 45, 0);
+ cdCanvasForeground(canvas, CD_DARK_RED);
+ cdCanvasInteriorStyle(canvas, CD_HOLLOW);
+ cdCanvasSector(canvas, w/2, h/2, w/2, h/2, 45, 0);
/* on the left a red hash diamond */
/* notice the the default back opacity is transparent
and the pattern of the sector will still be visible
inside the hatch where the two objects intersect */
- cdForeground(CD_RED);
- cdHatch(CD_DIAGCROSS);
- cdBegin(CD_FILL);
- cdVertex(w/4, h/4);
- cdVertex(w/2-w/8, h/2);
- cdVertex(w/4, 3*h/4);
- cdVertex(w/8, h/2);
- cdEnd();
+ cdCanvasForeground(canvas, CD_RED);
+ cdCanvasHatch(canvas, CD_DIAGCROSS);
+ cdCanvasBegin(canvas, CD_FILL);
+ cdCanvasVertex(canvas, w/4, h/4);
+ cdCanvasVertex(canvas, w/2-w/8, h/2);
+ cdCanvasVertex(canvas, w/4, 3*h/4);
+ cdCanvasVertex(canvas, w/8, h/2);
+ cdCanvasEnd(canvas);
/* draws a blue roof.*/
- cdForeground(CD_BLUE);
- cdLine(w/8, h/2, w/4, 3*h/4);
- cdLine(w/4, 3*h/4, w/2-w/8, h/2);
+ cdCanvasForeground(canvas, CD_BLUE);
+ cdCanvasLine(canvas, w/8, h/2, w/4, 3*h/4);
+ cdCanvasLine(canvas, w/4, 3*h/4, w/2-w/8, h/2);
/* draws a dashed ribbon on the right
with a custom color */
- cdForeground(cdEncodeColor(100, 25, 200));
- cdLineStyle(CD_DASH_DOT);
- cdBegin(CD_BEZIER);
- cdVertex(3*w/4-20, h/2-50);
- cdVertex(3*w/4+150, 3*h/4-50);
- cdVertex(3*w/4-150, 3*h/4-50);
- cdVertex(3*w/4+20, h/2-50);
- cdEnd();
-
- cdFont(CD_HELVETICA, CD_BOLD, 40);
- cdTextAlignment(CD_CENTER);
- cdText(w/2, h/4-50, "Canvas Draw");
- cdTextBox(w/2, h/4-50, "Canvas Draw", &xmin, &xmax, &ymin, &ymax);
- cdRect(xmin, xmax, ymin, ymax);
- cdFlush();
+ cdCanvasForeground(canvas, cdEncodeColor(100, 25, 200));
+ cdCanvasLineStyle(canvas, CD_DASH_DOT);
+ cdCanvasBegin(canvas, CD_BEZIER);
+ cdCanvasVertex(canvas, 3*w/4-20, h/2-50);
+ cdCanvasVertex(canvas, 3*w/4+150, 3*h/4-50);
+ cdCanvasVertex(canvas, 3*w/4-150, 3*h/4-50);
+ cdCanvasVertex(canvas, 3*w/4+20, h/2-50);
+ cdCanvasEnd(canvas);
+
+ cdCanvasFont(canvas, "Helvetica", CD_BOLD, 40);
+ cdCanvasTextAlignment(canvas, CD_CENTER);
+ cdCanvasText(canvas, w/2, h/4-50, "Canvas Draw");
+ cdCanvasGetTextBox(canvas, w/2, h/4-50, "Canvas Draw", &xmin, &xmax, &ymin, &ymax);
+ cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
}
+#if 0
void draw_wd(void)
{
char* text;
@@ -1214,18 +1336,14 @@ void draw_wd(void)
wdVertex(rect[4], rect[5]);
wdVertex(rect[6], rect[7]);
cdEnd();
-
- cdFlush();
}
-//void SimpleDrawTest(void)
-void SimpleDrawTestHardCopy(void)
+//void SimpleDrawTest(cdCanvas* canvas)
+void SimpleDrawTestHardCopy(cdCanvas* canvas)
{
int w, h;
cdGetCanvasSize(&w, &h, 0, 0);
- simple_draw = DRAW_ALL;
-
wdViewport(0,w-1,0,h-1);
if (w>h)
wdWindow(0,(double)w/(double)h,0,1);
@@ -1235,19 +1353,16 @@ void SimpleDrawTestHardCopy(void)
draw_wd();
//wdHardcopy(CD_CLIPBOARD, "800x600", cdActiveCanvas(), draw_wd );
- //cdFlush();
}
-//void SimpleDrawTest(void)
-void SimpleDrawTestImageRGB(void)
+//void SimpleDrawTest(cdCanvas* canvas)
+void SimpleDrawTestImageRGB(cdCanvas* canvas)
{
int size = 2048*2048;
unsigned char *red, *green, *blue;
cdCanvas* canvas = cdCreateCanvas(CD_IMAGERGB, "2048x2048");
cdActivate(canvas);
- simple_draw = DRAW_TEST;
-
red = calloc(size, 1);
green = calloc(size, 1);
blue = calloc(size, 1);
@@ -1259,14 +1374,11 @@ void SimpleDrawTestImageRGB(void)
free(blue);
cdKillCanvas(canvas);
- cdFlush();
}
-//void SimpleDrawTest(void)
-void SimpleDrawVectorFont(void)
+//void SimpleDrawTest(cdCanvas* canvas)
+void SimpleDrawVectorFont(cdCanvas* canvas)
{
- simple_draw = DRAW_TEST;
-
cdBackground(CD_WHITE);
cdClear();
cdLineStyle(CD_CONTINUOUS);
@@ -1321,26 +1433,35 @@ void SimpleDrawVectorFont(void)
// }
// }
}
- cdFlush();
}
-void SimpleDrawTest(void)
-//void SimpleDrawPoly(void)
+//void SimpleDrawTest(cdCanvas* canvas)
+void SimpleDrawPoly(cdCanvas* canvas)
{
int w, h;
cdGetCanvasSize(&w, &h, 0, 0);
- simple_draw = DRAW_TEST;
-
cdBackground(CD_WHITE);
cdClear();
- cdInteriorStyle(CD_SOLID);
- cdBegin(CD_FILL);
- cdVertex(w/4, h/4);
- cdVertex(w/2-w/8, h/4);
- cdVertex(w/2, h/2);
- cdVertex(w/2-w/8, h/2);
+ //cdSetAttribute("ANTIALIAS", "0");
+ cdForeground(cdEncodeAlpha(cdEncodeColor(255, 0, 0), 100));
+
+ cdfCanvasArc(cdActiveCanvas(), 255, 255, 100, 100, 0, 360);
+
+ cdLine(0, 0, 200, 200);
+
+ cdBegin(CD_BEZIER);
+ cdVertex(100, 100);
+ cdVertex(150, 200);
+ cdVertex(180, 250);
+ cdVertex(180, 200);
+ cdVertex(180, 150);
+ cdVertex(150, 100);
+ cdVertex(300, 100);
+ cdEnd();
+
cdEnd();
}
+#endif
diff --git a/cd/test/simple/simple.h b/cd/test/simple/simple.h
index 933b714..a69c69d 100755
--- a/cd/test/simple/simple.h
+++ b/cd/test/simple/simple.h
@@ -7,6 +7,9 @@
void SimpleCreateCanvas(char* data);
void SimpleKillCanvas(void);
+void SimpleUpdateSize(cdCanvas* cnv);
+void SimpleFlush(void);
+
int SimplePlayClipboard(void);
int SimplePlayCGMBin(void);
int SimplePlayCGMText(void);
@@ -35,6 +38,7 @@ int SimpleDrawClipboardEMF(void);
int SimpleDrawImage(void);
int SimpleDrawImageRGB(void);
int SimpleDrawSimulate(void);
+int SimpleDrawGL(void);
int SimpleNotXor(void);
int SimpleXor(void);
@@ -46,10 +50,10 @@ int SimpleClippingRegion(void);
int SimpleTransform(void);
int SimpleContextPlus(void);
-int SimpleDrawAll(void);
-int SimpleDrawTextAlign(void);
-int SimpleDrawTextFonts(void);
-void SimpleDrawTest(void);
-int SimpleDrawRepaint(void);
+int SimpleAll(void);
+int SimpleTextAlign(void);
+int SimpleTextFonts(void);
+int SimpleTest(void);
+int SimpleRepaint(void);
#endif
diff --git a/cd/test/simple/simple.led b/cd/test/simple/simple.led
index 63f3dc2..d7ec30d 100755
--- a/cd/test/simple/simple.led
+++ b/cd/test/simple/simple.led
@@ -70,15 +70,16 @@ mnSurface = MENU
(
ITEM("Window", SimpleDrawWindow),
ITEM("Server Image", SimpleDrawImage),
- ITEM("Image RGB", SimpleDrawImageRGB)
+ ITEM("Image RGB", SimpleDrawImageRGB),
+ ITEM("OpenGL", SimpleDrawGL)
)
mnPrimitives = MENU
(
- ITEM("All", SimpleDrawAll),
- ITEM("Text Align", SimpleDrawTextAlign),
- ITEM("Text Fonts", SimpleDrawTextFonts),
- ITEM("Test", SimpleDrawTest)
+ ITEM("All", SimpleAll),
+ ITEM("Text Align", SimpleTextAlign),
+ ITEM("Text Fonts", SimpleTextFonts),
+ ITEM("Test", SimpleTest)
)
mnSimpleMenu = MENU
diff --git a/cd/test/simple/simple_led.c b/cd/test/simple/simple_led.c
index 626b849..db06a72 100755
--- a/cd/test/simple/simple_led.c
+++ b/cd/test/simple/simple_led.c
@@ -1,4 +1,4 @@
-/* Automatically generated by Iup ledc 2.6 */
+/* Automatically generated by Iup 3.0 LED Compiler to C. */
#include <stdlib.h>
#include <stdarg.h>
@@ -6,34 +6,17 @@
static Ihandle* named[ 13 ];
-static Ihandle* decl( char* name, Ihandle* elem, char* first, ...)
-{
- char *attr, *val;
- va_list arg;
- va_start (arg, first);
- attr = first;
- while (attr)
- {
- val = va_arg(arg,char*);
- IupSetAttribute( elem, attr, val );
- attr = va_arg(arg,char*);
- }
- va_end (arg);
- if(name) IupSetHandle( name, elem );
- return elem;
-}
-
void simple_loadled (void)
{
- named[0] = decl( "mnOpen", IupMenu(
+ named[0] = IupSetAtt( "mnOpen", IupMenu(
IupItem( "CGM - Binary", "SimplePlayCGMBin" ),
IupItem( "CGM - Text", "SimplePlayCGMText" ),
IupItem( "METAFILE", "SimplePlayMetafile" ),
IupItem( "WMF", "SimplePlayWMF" ),
IupItem( "EMF", "SimplePlayEMF" ),
NULL), NULL );
- named[1] = decl( "mnSaveAs", IupMenu(
+ named[1] = IupSetAtt( "mnSaveAs", IupMenu(
IupItem( "DEBUG", "SimpleDrawDebug" ),
IupItem( "CGM - Binary", "SimpleDrawCGMBin" ),
IupItem( "CGM - Text", "SimpleDrawCGMText" ),
@@ -47,7 +30,7 @@ void simple_loadled (void)
IupItem( "SVG", "SimpleDrawSVG" ),
IupItem( "WMF", "SimpleDrawWMF" ),
NULL), NULL );
- named[2] = decl( "mnFile", IupMenu(
+ named[2] = IupSetAtt( "mnFile", IupMenu(
IupSubmenu( "Open",
named[0] /* mnOpen */
),
@@ -60,24 +43,24 @@ void simple_loadled (void)
IupSeparator(),
IupItem( "Exit", "cmdExit" ),
NULL), NULL );
- named[3] = decl( "mnEdit", IupMenu(
+ named[3] = IupSetAtt( "mnEdit", IupMenu(
IupItem( "Copy as Metafile", "SimpleDrawClipboardMetafile" ),
IupItem( "Copy as EMF", "SimpleDrawClipboardEMF" ),
IupItem( "Copy as Bitmap", "SimpleDrawClipboardBitmap" ),
IupItem( "Paste", "SimplePlayClipboard" ),
NULL), NULL );
- named[4] = decl( "mnClipping", IupMenu(
+ named[4] = IupSetAtt( "mnClipping", IupMenu(
IupItem( "Off", "SimpleClippingOff" ),
IupItem( "Area", "SimpleClippingArea" ),
IupItem( "Polygon", "SimpleClippingPolygon" ),
IupItem( "Region", "SimpleClippingRegion" ),
NULL), NULL );
- named[5] = decl( "mnWriteMode", IupMenu(
+ named[5] = IupSetAtt( "mnWriteMode", IupMenu(
IupItem( "Replace", "SimpleReplace" ),
IupItem( "Xor", "SimpleXor" ),
IupItem( "Not Xor", "SimpleNotXor" ),
NULL), NULL );
- named[6] = decl( "mnOptions", IupMenu(
+ named[6] = IupSetAtt( "mnOptions", IupMenu(
IupSubmenu( "Clipping",
named[4] /* mnClipping */
),
@@ -88,18 +71,19 @@ void simple_loadled (void)
IupItem( "Transform", "SimpleTransform" ),
IupItem( "Context Plus", "SimpleContextPlus" ),
NULL), NULL );
- named[7] = decl( "mnSurface", IupMenu(
+ named[7] = IupSetAtt( "mnSurface", IupMenu(
IupItem( "Window", "SimpleDrawWindow" ),
IupItem( "Server Image", "SimpleDrawImage" ),
IupItem( "Image RGB", "SimpleDrawImageRGB" ),
+ IupItem( "OpenGL", "SimpleDrawGL" ),
NULL), NULL );
- named[8] = decl( "mnPrimitives", IupMenu(
- IupItem( "All", "SimpleDrawAll" ),
- IupItem( "Text Align", "SimpleDrawTextAlign" ),
- IupItem( "Text Fonts", "SimpleDrawTextFonts" ),
- IupItem( "Test", "SimpleDrawTest" ),
+ named[8] = IupSetAtt( "mnPrimitives", IupMenu(
+ IupItem( "All", "SimpleAll" ),
+ IupItem( "Text Align", "SimpleTextAlign" ),
+ IupItem( "Text Fonts", "SimpleTextFonts" ),
+ IupItem( "Test", "SimpleTest" ),
NULL), NULL );
- named[9] = decl( "mnSimpleMenu", IupMenu(
+ named[9] = IupSetAtt( "mnSimpleMenu", IupMenu(
IupSubmenu( "File",
named[2] /* mnFile */
),
@@ -116,9 +100,9 @@ void simple_loadled (void)
named[8] /* mnPrimitives */
),
NULL), NULL );
- named[10] = decl( "SimpleCanvas", IupCanvas( "SimpleRepaint" ),
+ named[10] = IupSetAtt( "SimpleCanvas", IupCanvas( "SimpleRepaint" ),
"BORDER", "0", NULL );
- named[11] = decl( "SimpleDialog", IupDialog(
+ named[11] = IupSetAtt( "SimpleDialog", IupDialog(
named[10] /* SimpleCanvas */
),
"TITLE", "Simple Draw",