summaryrefslogtreecommitdiff
path: root/cd/src/drv
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/drv')
-rwxr-xr-xcd/src/drv/cd0emf.c8
-rwxr-xr-xcd/src/drv/cd0prn.c8
-rwxr-xr-xcd/src/drv/cdcgm.c14
-rwxr-xr-xcd/src/drv/cddebug.c125
-rwxr-xr-xcd/src/drv/cddgn.c13
-rwxr-xr-xcd/src/drv/cddxf.c206
-rw-r--r--cd/src/drv/cdgl.c1559
-rwxr-xr-xcd/src/drv/cdirgb.c235
-rwxr-xr-xcd/src/drv/cdmf.c93
-rwxr-xr-xcd/src/drv/cdpdf.c399
-rwxr-xr-xcd/src/drv/cdpicture.c284
-rwxr-xr-xcd/src/drv/cdps.c486
-rwxr-xr-xcd/src/drv/cgm.c4
13 files changed, 3018 insertions, 416 deletions
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 );
}
}