diff options
| author | scuri <scuri> | 2010-06-04 17:36:53 +0000 | 
|---|---|---|
| committer | scuri <scuri> | 2010-06-04 17:36:53 +0000 | 
| commit | 1bad658bce4895bab21b2aab65c82544871fa551 (patch) | |
| tree | 53bc33a2e2bf442faa0c716ec59a29b0ed89124b | |
| parent | dd7a1955dbf538734dc54225eac5282e3ab35ff8 (diff) | |
*** empty log message ***
| -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(); | 
