diff options
Diffstat (limited to 'cd')
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;"d:\lng\gtk\include\atk-1.0";d:\lng\gtk\include\cairo;"d:\lng\gtk\include\glib-2.0";"d:\lng\gtk\include\pango-1.0";"d:\lng\gtk\include\gtk-2.0";"d:\lng\gtk\lib\glib-2.0\include";"d:\lng\gtk\lib\gtk-2.0\include"" - 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, ¤t); + 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, ¤t); + 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, ¤t); + 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", |