summaryrefslogtreecommitdiff
path: root/cd/src/drv/cdps.c
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/drv/cdps.c')
-rwxr-xr-xcd/src/drv/cdps.c486
1 files changed, 387 insertions, 99 deletions
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;