diff options
-rw-r--r-- | src/cairo/cdcairo.c | 52 | ||||
-rw-r--r-- | src/drv/cdirgb.c | 79 | ||||
-rw-r--r-- | src/drv/cdpdf.c | 52 | ||||
-rw-r--r-- | src/lua5/cdvoid5.c | 6 | ||||
-rw-r--r-- | src/win32/cdwdib.c | 38 | ||||
-rw-r--r-- | src/win32/cdwin.c | 27 | ||||
-rw-r--r-- | src/win32/cdwin.h | 1 | ||||
-rw-r--r-- | test/simple/simple.c | 4 |
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(); |