summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo/cdcairo.c52
-rw-r--r--src/drv/cdirgb.c79
-rw-r--r--src/drv/cdpdf.c52
-rw-r--r--src/lua5/cdvoid5.c6
-rw-r--r--src/win32/cdwdib.c38
-rw-r--r--src/win32/cdwin.c27
-rw-r--r--src/win32/cdwin.h1
-rw-r--r--test/simple/simple.c4
8 files changed, 164 insertions, 95 deletions
diff --git a/src/cairo/cdcairo.c b/src/cairo/cdcairo.c
index 9589d74..67a778c 100644
--- a/src/cairo/cdcairo.c
+++ b/src/cairo/cdcairo.c
@@ -1210,12 +1210,23 @@ static void cdgetimagergb(cdCtxCanvas *ctxcanvas, unsigned char *r, unsigned cha
cairo_surface_destroy(image_surface);
cairo_destroy(cr);
- cairo_restore (ctxcanvas->cr);
+ cairo_restore(ctxcanvas->cr);
+}
+
+static void sFixImageY(cdCanvas* canvas, int *topdown, int *y, int h)
+{
+ if (canvas->invert_yaxis)
+ *topdown = 0;
+ else
+ *topdown = 1;
+
+ if (!(*topdown))
+ *y -= (h - 1); /* move Y to top-left corner, since it was at the bottom of the image */
}
static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
- int i, j, rw, rh, pos, offset;
+ int i, j, rw, rh, pos, offset, topdown;
unsigned long* data;
cairo_surface_t* image_surface;
@@ -1229,11 +1240,16 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
data = (unsigned long*)cairo_image_surface_get_data(image_surface);
offset = cairo_image_surface_get_stride(image_surface)/4 - rw;
- for (i=ymax; i>=ymin; i--)
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
{
for (j=xmin; j<=xmax; j++)
{
- pos = i*iw+j;
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
*data++ = sEncodeRGBA(r[pos], g[pos], b[pos], 255);
}
@@ -1243,8 +1259,6 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
cairo_save (ctxcanvas->cr);
- y -= (h - 1); /* Cairo image origin is at top-left */
-
cairo_rectangle(ctxcanvas->cr, x, y, w, h);
cairo_clip(ctxcanvas->cr);
@@ -1265,7 +1279,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, rw, rh, pos, offset;
+ int i, j, rw, rh, pos, offset, topdown;
unsigned long* data;
cairo_surface_t* image_surface;
@@ -1279,11 +1293,16 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
data = (unsigned long*)cairo_image_surface_get_data(image_surface);
offset = cairo_image_surface_get_stride(image_surface)/4 - rw;
- for (i=ymax; i>=ymin; i--)
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
{
for (j=xmin; j<=xmax; j++)
{
- pos = i*iw+j;
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
*data++ = sEncodeRGBA(r[pos], g[pos], b[pos], a[pos]);
}
@@ -1293,8 +1312,6 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns
cairo_save (ctxcanvas->cr);
- y -= (h - 1); /* Cairo image origin is at top-left */
-
cairo_rectangle(ctxcanvas->cr, x, y, w, h);
cairo_clip(ctxcanvas->cr);
@@ -1329,7 +1346,7 @@ static int sCalcPalSize(int size, const unsigned char *index)
static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
- int i, j, rw, rh, pos, offset, pal_size;
+ int i, j, rw, rh, pos, offset, pal_size, topdown;
unsigned long* data, cairo_colors[256], c;
cairo_surface_t* image_surface;
@@ -1350,11 +1367,16 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
cairo_colors[i] = sEncodeRGBA(cdRed(c), cdGreen(c), cdBlue(c), 255);
}
- for (i=ymax; i>=ymin; i--)
+ sFixImageY(ctxcanvas->canvas, &topdown, &y, h);
+
+ for (i=ymin; i<=ymax; i++)
{
for (j=xmin; j<=xmax; j++)
{
- pos = i*iw+j;
+ if (topdown)
+ pos = i*iw+j;
+ else
+ pos = (ymax+ymin - i)*iw+j;
*data++ = cairo_colors[index[pos]];
}
@@ -1364,8 +1386,6 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi
cairo_save (ctxcanvas->cr);
- y -= (h - 1); /* Cairo image origin is at top-left */
-
cairo_rectangle(ctxcanvas->cr, x, y, w, h);
cairo_clip(ctxcanvas->cr);
diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c
index 9f367e0..68a5766 100644
--- a/src/drv/cdirgb.c
+++ b/src/drv/cdirgb.c
@@ -961,20 +961,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);
@@ -993,7 +1000,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)
@@ -1016,17 +1023,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);
@@ -1045,7 +1047,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);
@@ -1057,7 +1059,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)
@@ -1066,12 +1068,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) ||
@@ -1099,7 +1096,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;
@@ -1126,7 +1123,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;
@@ -1141,7 +1138,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;
@@ -1159,7 +1156,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)
@@ -1168,12 +1165,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) ||
@@ -1201,7 +1193,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;
@@ -1229,7 +1221,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;
@@ -1245,7 +1237,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;
@@ -1265,7 +1257,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, 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)
@@ -1274,12 +1266,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) ||
@@ -1307,7 +1294,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;
@@ -1333,7 +1320,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;
@@ -1350,7 +1337,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;
diff --git a/src/drv/cdpdf.c b/src/drv/cdpdf.c
index bc91a15..e2482b7 100644
--- a/src/drv/cdpdf.c
+++ b/src/drv/cdpdf.c
@@ -541,11 +541,29 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
if (mode == CD_PATH)
{
- int p;
+ 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++)
{
@@ -612,18 +630,15 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
PDF_closepath(ctxcanvas->pdf);
break;
case CD_PATH_FILL:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_fill(ctxcanvas->pdf);
break;
case CD_PATH_STROKE:
PDF_stroke(ctxcanvas->pdf);
break;
case CD_PATH_FILLSTROKE:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_fill_stroke(ctxcanvas->pdf);
break;
case CD_PATH_CLIP:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_clip(ctxcanvas->pdf);
break;
}
@@ -638,6 +653,7 @@ static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
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,10 +711,28 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
if (mode == CD_PATH)
{
- int p;
+ int p, fill = 0;
/* if there is any current path, remove it */
- PDF_endpath(ctxcanvas->pdf);
+ /* 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++)
@@ -706,7 +740,7 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
switch(ctxcanvas->canvas->path[p])
{
case CD_PATH_NEW:
- PDF_endpath(ctxcanvas->pdf);
+ /* Don't use PDF_endpath because here usually there will be no path scope */
break;
case CD_PATH_MOVETO:
if (i+1 > n) return;
@@ -766,18 +800,15 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
PDF_closepath(ctxcanvas->pdf);
break;
case CD_PATH_FILL:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_fill(ctxcanvas->pdf);
break;
case CD_PATH_STROKE:
PDF_stroke(ctxcanvas->pdf);
break;
case CD_PATH_FILLSTROKE:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_fill_stroke(ctxcanvas->pdf);
break;
case CD_PATH_CLIP:
- PDF_set_parameter(ctxcanvas->pdf, "fillrule", ctxcanvas->canvas->fill_mode==CD_EVENODD? "evenodd": "winding");
PDF_clip(ctxcanvas->pdf);
break;
}
@@ -792,6 +823,7 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)
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
diff --git a/src/lua5/cdvoid5.c b/src/lua5/cdvoid5.c
index 2424e1d..67c2c99 100644
--- a/src/lua5/cdvoid5.c
+++ b/src/lua5/cdvoid5.c
@@ -80,9 +80,9 @@ void cdinittable(cdCanvas* canvas)
canvas->cxArc = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
canvas->cxSector = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
canvas->cxChord = (void ( *)(cdCtxCanvas*, int ,int ,int ,int ,double ,double ))cdvoid_error;
- canvas->cxText = (void (*)(cdCtxCanvas*, int ,int ,const char *))cdvoid_error;
+ canvas->cxText = (void (*)(cdCtxCanvas*, int ,int ,const char *, int))cdvoid_error;
canvas->cxGetFontDim = (void (*)(cdCtxCanvas*, int *,int *,int *,int *))cdvoid_error;
- canvas->cxGetTextSize = (void (*)(cdCtxCanvas*, const char *,int *,int *))cdvoid_error;
+ canvas->cxGetTextSize = (void (*)(cdCtxCanvas*, const char *,int,int *,int *))cdvoid_error;
canvas->cxPutImageRectRGB = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const unsigned char *,const unsigned char *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
canvas->cxPutImageRectRGBA = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
canvas->cxPutImageRectMap = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *,const long *,int ,int ,int ,int ,int ,int ,int ,int ))cdvoid_error;
@@ -93,7 +93,7 @@ void cdinittable(cdCanvas* canvas)
canvas->cxFBox = (void (*)(cdCtxCanvas*, double ,double ,double ,double ))cdvoid_error;
canvas->cxFArc = (void (*)(cdCtxCanvas*, double ,double ,double ,double ,double ,double ))cdvoid_error;
canvas->cxFSector = (void (*)(cdCtxCanvas*, double ,double ,double ,double ,double ,double ))cdvoid_error;
- canvas->cxFText = (void (*)(cdCtxCanvas*, double ,double ,const char *))cdvoid_error;
+ canvas->cxFText = (void (*)(cdCtxCanvas*, double ,double ,const char *,int))cdvoid_error;
canvas->cxStipple = (void (*)(cdCtxCanvas*, int ,int ,const unsigned char *))cdvoid_error;
canvas->cxPattern = (void (*)(cdCtxCanvas*, int ,int , const long *))cdvoid_error;
canvas->cxNativeFont = (int (*)(cdCtxCanvas*, const char*))cdvoid_error;
diff --git a/src/win32/cdwdib.c b/src/win32/cdwdib.c
index aff3f64..25851cd 100644
--- a/src/win32/cdwdib.c
+++ b/src/win32/cdwdib.c
@@ -323,6 +323,44 @@ void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned
}
}
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi)
+{
+ int x,y, resto1, resto2, offset, line_size;
+ BYTE* bits;
+
+ line_size = cdwDIBLineSize(dib->w, 32);
+
+ bits = dib->bits + line_size*(dib->h-1);
+ resto1 = line_size - dib->w * 4;
+ resto2 = wi - dib->w;
+
+ offset = wi * yi + xi;
+
+ red = red + offset;
+ green = green + offset;
+ blue = blue + offset;
+ alpha = alpha + offset;
+
+ for (y = 0; y < dib->h; y++)
+ {
+ for (x = 0; x < dib->w; x++)
+ {
+ *bits++ = CD_ALPHAPRE(*blue, *alpha); blue++;
+ *bits++ = CD_ALPHAPRE(*green, *alpha); green++;
+ *bits++ = CD_ALPHAPRE(*red, *alpha); red++;
+ *bits++ = *alpha++;
+ }
+
+ bits += resto1;
+ bits -= 2*line_size;
+
+ red += resto2;
+ green += resto2;
+ blue += resto2;
+ alpha += resto2;
+ }
+}
+
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi)
{
int x,y, resto1, resto2, offset;
diff --git a/src/win32/cdwin.c b/src/win32/cdwin.c
index 972f5a9..e2eb9ea 100644
--- a/src/win32/cdwin.c
+++ b/src/win32/cdwin.c
@@ -896,12 +896,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
old_arcmode = SetArcDirection(ctxcanvas->hDC, ctxcanvas->canvas->invert_yaxis? AD_CLOCKWISE: AD_COUNTERCLOCKWISE);
}
- Arc(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
+ ArcTo(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
if (old_arcmode) /* restore */
SetArcDirection(ctxcanvas->hDC, old_arcmode);
- MoveToEx(ctxcanvas->hDC, arc.XEndArc, arc.YEndArc, NULL);
current_set = 1;
i += 3;
@@ -1760,10 +1759,12 @@ static void sFixImageY(cdCanvas* canvas, int *y, int *h)
/* Here, y is from top to bottom,
is at the bottom-left corner of the image if h>0
is at the top-left corner of the image if h<0. (Undocumented feature)
+
cdCalcZoom expects Y at top-left if h>0
and Y at bottom-left if h<0
if h<0 then eh<0 to StretchDIBits mirror the image.
- BUT!!!!!! AlphaBlend will NOT mirror the image. */
+ BUT!!!!!! AlphaBlend will NOT mirror the image.
+ So it must be manually made there. */
if (!canvas->invert_yaxis)
*h = -(*h);
@@ -1879,26 +1880,16 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int width, int height, co
return;
}
- cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
-
if (eh < 0) /* must mirror the image */
{
- XFORM xForm;
-
+ /* Fix position */
eh = -eh;
+ ey = ey - eh;
- SetGraphicsMode(hDCMem, GM_ADVANCED);
- ModifyWorldTransform(hDCMem, NULL, MWT_IDENTITY);
-
- /* configure a bottom-up coordinate system */
- xForm.eM11 = (FLOAT)1;
- xForm.eM12 = (FLOAT)0;
- xForm.eM21 = (FLOAT)0;
- xForm.eM22 = (FLOAT)-1;
- xForm.eDx = (FLOAT)0;
- xForm.eDy = (FLOAT)(bh-1);
- ModifyWorldTransform(hDCMem, &xForm, MWT_LEFTMULTIPLY);
+ cdwDIBEncodeRGBARectMirror(&dib, red, green, blue, alpha, bx, by, width, height);
}
+ else
+ cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
hOldBitmap = SelectObject(hDCMem, hBitmap);
diff --git a/src/win32/cdwin.h b/src/win32/cdwin.h
index a8230e7..94ed62c 100644
--- a/src/win32/cdwin.h
+++ b/src/win32/cdwin.h
@@ -169,6 +169,7 @@ void cdwDIBEncodePattern(cdwDIB* dib, const long int *colors);
void cdwDIBEncodeMapRect(cdwDIB* dib, const unsigned char *index, const long int *colors, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBRect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARectZoom(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int w, int h, int xi, int yi, int wi, int hi);
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi);
diff --git a/test/simple/simple.c b/test/simple/simple.c
index 891caef..5f21d18 100644
--- a/test/simple/simple.c
+++ b/test/simple/simple.c
@@ -723,8 +723,8 @@ int SimpleDrawAll(void)
cdVertex(200, 100); /* width, height */
cdVertex(-30*1000, -170*1000); /* start angle, end angle (degrees / 1000) */
// cdCanvasPathSet(canvas, CD_PATH_CLOSE);
- cdCanvasPathSet(canvas, CD_PATH_STROKE);
-// cdCanvasPathSet(canvas, CD_PATH_FILL);
+// cdCanvasPathSet(canvas, CD_PATH_STROKE);
+ cdCanvasPathSet(canvas, CD_PATH_FILL);
// cdCanvasPathSet(canvas, CD_PATH_FILLSTROKE);
cdEnd();