diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cairo/cdcairo.c | 393 | ||||
| -rw-r--r-- | src/cairo/cdcairoctx.h | 2 | ||||
| -rw-r--r-- | src/cairo/cdcairodbuf.c | 2 | ||||
| -rw-r--r-- | src/cairo/cdcairoimg.c | 2 | ||||
| -rw-r--r-- | src/drv/cdirgb.c | 18 | ||||
| -rw-r--r-- | src/drv/cdpdf.c | 47 | ||||
| -rw-r--r-- | src/gdiplus/cdwinp.cpp | 2 | 
7 files changed, 236 insertions, 230 deletions
diff --git a/src/cairo/cdcairo.c b/src/cairo/cdcairo.c index 83cf088..0561c08 100644 --- a/src/cairo/cdcairo.c +++ b/src/cairo/cdcairo.c @@ -207,40 +207,62 @@ static int cdclip(cdCtxCanvas *ctxcanvas, int mode)  /******************************************************/ -static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* data, int (*data2rgb)(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a)) +#define CD_ALPHAPRE(_src, _alpha) (((_src)*(_alpha))/255) + +static unsigned long sEncodeRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ +  /* Pre-multiplied alpha */ +  if (a != 255) +  { +    r = CD_ALPHAPRE(r, a); +    g = CD_ALPHAPRE(g, a); +    b = CD_ALPHAPRE(b, a); +  } + +  return (((unsigned long)a) << 24) | +         (((unsigned long)r) << 16) | +         (((unsigned long)g) <<  8) | +         (((unsigned long)b) <<  0); +} + +static void make_pattern(cdCtxCanvas *ctxcanvas, int n, int m, void* userdata, int (*data2rgb)(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* userdata, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a))  { -  int i, j; +  int i, j, offset;    unsigned char r, g, b, a;    cairo_surface_t* pattern_surface; -  cairo_t* cr; +  unsigned long* data; -  pattern_surface = cairo_surface_create_similar(cairo_get_target(ctxcanvas->cr), CAIRO_CONTENT_COLOR_ALPHA, n, m); +  pattern_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, n, m); -  cr = cairo_create(pattern_surface); +  data = (unsigned long*)cairo_image_surface_get_data(pattern_surface); +  offset = cairo_image_surface_get_stride(pattern_surface)/4 - n;    for (j = 0; j < m; j++)    {      for (i = 0; i < n; i++)      { -      int ret = data2rgb(ctxcanvas, n, i, j, data, &r, &g, &b, &a); +      int ret = data2rgb(ctxcanvas, n, i, m-1-j, userdata, &r, &g, &b, &a);        if (ret == -1) +      { +        data++;  /* already transparent */          continue; +      } -      cairo_set_source_rgba(cr, (double)r/255.0, (double)g/255.0, (double)b/255.0, (double)a/255.0); - -      cairo_rectangle(cr, i, m-1-j, 1.0, 1.0); -      cairo_fill(cr); +      *data++ = sEncodeRGBA(r, g, b, a);      } + +    if (offset) +      data += offset;    }    if (ctxcanvas->pattern)      cairo_pattern_destroy(ctxcanvas->pattern);    ctxcanvas->pattern = cairo_pattern_create_for_surface(pattern_surface); +  cairo_pattern_reference(ctxcanvas->pattern);    cairo_pattern_set_extend(ctxcanvas->pattern, CAIRO_EXTEND_REPEAT);    cairo_surface_destroy(pattern_surface); -  cairo_destroy(cr);  }  static int long2rgb(cdCtxCanvas *ctxcanvas, int n, int i, int j, void* data, unsigned char*r, unsigned char*g, unsigned char*b, unsigned char*a) @@ -309,6 +331,9 @@ static int cdhatch(cdCtxCanvas *ctxcanvas, int style)    cairo_set_source_rgba(cr, cdCairoGetRed(ctxcanvas->canvas->foreground), cdCairoGetGreen(ctxcanvas->canvas->foreground), cdCairoGetBlue(ctxcanvas->canvas->foreground), cdCairoGetAlpha(ctxcanvas->canvas->foreground)); +  cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);  +  cairo_set_line_width(cr, 1); +    switch(style)    {    case CD_HORIZONTAL: @@ -540,6 +565,8 @@ static long int cdforeground(cdCtxCanvas *ctxcanvas, long int color)  static void cdclear(cdCtxCanvas* ctxcanvas)  {    cairo_save (ctxcanvas->cr); +  cairo_identity_matrix(ctxcanvas->cr); +  cairo_reset_clip(ctxcanvas->cr);    cairo_set_source_rgba(ctxcanvas->cr, cdCairoGetRed(ctxcanvas->canvas->background), cdCairoGetGreen(ctxcanvas->canvas->background), cdCairoGetBlue(ctxcanvas->canvas->background), cdCairoGetAlpha(ctxcanvas->canvas->background));    cairo_set_operator (ctxcanvas->cr, CAIRO_OPERATOR_SOURCE);    cairo_paint (ctxcanvas->cr);  /* paints the current source everywhere within the current clip region. */ @@ -560,13 +587,33 @@ static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)    cdfline(ctxcanvas, (double)x1, (double)y1, (double)x2, (double)y2);  } +static void sFixAngles(cdCtxCanvas* ctxcanvas, double *angle1, double *angle2) +{ +  if (ctxcanvas->canvas->invert_yaxis) +  { +    /* Cairo angles are clock-wise by default */ +    double t = *angle1; +    *angle1 = *angle2; +    *angle2 = t; +    *angle1 *= -CD_DEG2RAD; +    *angle2 *= -CD_DEG2RAD; +  } +  else +  { +    *angle1 *= CD_DEG2RAD; +    *angle2 *= CD_DEG2RAD; +  } +} +  static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2)  {    update_fill(ctxcanvas, 0); +  sFixAngles(ctxcanvas, &a1, &a2); +    if (w == h)    { -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);      cairo_stroke(ctxcanvas->cr);    }    else  /* Ellipse: change the scale to create from the circle */ @@ -577,7 +624,7 @@ static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, doubl      cairo_scale(ctxcanvas->cr, w/h, 1.0);      cairo_translate(ctxcanvas->cr, -xc, -yc); -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);      cairo_stroke(ctxcanvas->cr);      cairo_restore(ctxcanvas->cr);  /* restore from local */ @@ -593,10 +640,12 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do  {    update_fill(ctxcanvas, 1); +  sFixAngles(ctxcanvas, &a1, &a2); +    if (w == h)    {      cairo_move_to(ctxcanvas->cr, xc, yc); -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);      cairo_fill(ctxcanvas->cr);    }    else  /* Ellipse: change the scale to create from the circle */ @@ -608,16 +657,9 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do      cairo_translate(ctxcanvas->cr, -xc, -yc);      cairo_move_to(ctxcanvas->cr, xc, yc); -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*h, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2); -    if (ctxcanvas->canvas->interior_style == CD_SOLID || -      ctxcanvas->canvas->interior_style == CD_PATTERN) -      cairo_fill(ctxcanvas->cr); -    else -    { -      cairo_line_to(ctxcanvas->cr, xc, yc); -      cairo_stroke(ctxcanvas->cr); -    } +    cairo_fill(ctxcanvas->cr);      cairo_restore(ctxcanvas->cr);  /* restore from local */    } @@ -632,9 +674,11 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou  {    update_fill(ctxcanvas, 1); +  sFixAngles(ctxcanvas, &a1, &a2); +    if (w == h)    { -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*w, a1, a2);      cairo_fill_preserve(ctxcanvas->cr);      cairo_stroke(ctxcanvas->cr);    } @@ -644,9 +688,10 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou      /* local transform */      cairo_translate(ctxcanvas->cr, xc, yc); -    cairo_scale(ctxcanvas->cr, 1.0, w/h); +    cairo_scale(ctxcanvas->cr, w/h, 1.0); +    cairo_translate(ctxcanvas->cr, -xc, -yc); -    cairo_arc_negative(ctxcanvas->cr, xc, yc, 0.5*w, -a1*CD_DEG2RAD, -a2*CD_DEG2RAD); +    cairo_arc(ctxcanvas->cr, xc, yc, 0.5*h, a1, a2);      cairo_fill_preserve(ctxcanvas->cr);      cairo_stroke(ctxcanvas->cr); @@ -915,241 +960,225 @@ static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n)  static void cdgetimagergb(cdCtxCanvas *ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)  { -  int col, lin, pos; -  double red, green, blue; -  cairo_pattern_t *pattern; +  int i, j, pos, offset; +  unsigned long* data; +  cairo_surface_t* image_surface; +  cairo_t* cr;    cairo_save (ctxcanvas->cr);    /* reset to the identity. */    cairo_identity_matrix(ctxcanvas->cr); -  if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here +  if (ctxcanvas->canvas->invert_yaxis==0) /* if 0, invert because the transform was reset here */      y = _cdInvertYAxis(ctxcanvas->canvas, y); -  //TODO:fix -  pattern = cairo_get_source(ctxcanvas->cr); -  if (!pattern) -    return; +  /* y is the bottom-left of the image in CD, must be at upper-left */ +  y -= h-1; + +  image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h); +  cr = cairo_create(image_surface); + +  /* creates a pattern from the canvas and sets it as source in the image. */ +  cairo_set_source_surface(cr, cairo_get_target(ctxcanvas->cr), -x, -y); + +  cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_NONE);  +  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); +  cairo_paint(cr);  /* paints the current source everywhere within the current clip region. */ + +  data = (unsigned long*)cairo_image_surface_get_data(image_surface); +  offset = cairo_image_surface_get_stride(image_surface)/4 - w; -  for (lin = (y-h+1); lin < h; lin++) +  for (i=0; i<h; i++)    { -    for (col = x; col < w; col++) +    for (j=0; j<w; j++)      { -      pos = (h-lin-1) * w + col; -      cairo_pattern_get_color_stop_rgba(pattern, pos, NULL, &red, &green, &blue, NULL); -      *r = (unsigned char)(red*255.0); -      *g = (unsigned char)(green*255.0); -      *b = (unsigned char)(blue*255.0); +      pos = i*w+j; +      r[pos] = cdRed(*data); +      g[pos] = cdGreen(*data); +      b[pos] = cdBlue(*data); +      data++;      } + +    if (offset) +      data += offset;    } -  cairo_pattern_destroy(pattern); +  cairo_surface_destroy(image_surface); +  cairo_destroy(cr); +    cairo_restore (ctxcanvas->cr);  }  static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, rw, rh; -  unsigned char* rgb_data; -  int stride; -  cairo_surface_t* surface, *new_surface; -  cairo_t* cr; +  int i, j, rw, rh, pos, offset; +  unsigned long* data; +  cairo_surface_t* image_surface;    if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;    rw = xmax-xmin+1;    rh = ymax-ymin+1; -  y -= (h - 1);        /* Cairo image origin is at top-left */ - -  stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, rw); -  rgb_data = (unsigned char*)malloc(sizeof(unsigned char)*(stride * rh)); -  if (!rgb_data) return; +  image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, rw, rh); -  surface = cairo_image_surface_create_for_data(rgb_data, CAIRO_FORMAT_RGB24, rw, rh, stride); +  data = (unsigned long*)cairo_image_surface_get_data(image_surface); +  offset = cairo_image_surface_get_stride(image_surface)/4 - rw; -  d = 0;    for (i=ymax; i>=ymin; i--)    {      for (j=xmin; j<=xmax; j++)      { -      rgb_data[d] = b[i*iw+j]; d++; -      rgb_data[d] = g[i*iw+j]; d++; -      rgb_data[d] = r[i*iw+j]; d++; -      rgb_data[d] = (unsigned char)0; d++; +      pos = i*iw+j; +      *data++ = sEncodeRGBA(r[pos], g[pos], b[pos], 255);      } -  } - -  /* Scaling surface to fit into the image */ -//  if (w != rw || h != rh) -  { -    new_surface = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, w, h); -    cr = cairo_create (new_surface); -    /* Scale *before* setting the source surface (1) */ -    cairo_scale (cr, (double)w / rw, (double)h / rh); -    cairo_set_source_surface (cr, surface, 0, 0); +    if (offset) +      data += offset; +  } -    /* To avoid getting the edge pixels blended with 0 alpha, -    * which would occur with the default EXTEND_NONE */ -    cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT);  +  cairo_save (ctxcanvas->cr); -    /* Replace the destination with the source instead of overlaying */ -    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); +  y -= (h - 1);        /* Cairo image origin is at top-left */ -    cairo_paint (cr); +  cairo_rectangle(ctxcanvas->cr, x, y, w, h); +  cairo_clip(ctxcanvas->cr); -    cairo_destroy (cr); +  if (w != rw || h != rh) +  { +    /* Scale *before* setting the source surface (1) */ +    cairo_translate(ctxcanvas->cr, x, y); +    cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh); +    cairo_translate(ctxcanvas->cr, -x, -y);    } -  /* Put image rect */ -  cairo_set_source_surface(ctxcanvas->cr, new_surface, x, y); -  cairo_pattern_set_extend(cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);  +  cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y);    cairo_paint(ctxcanvas->cr); -  cairo_surface_destroy(surface); -  cairo_surface_destroy(new_surface); -  free(rgb_data); +  cairo_surface_destroy(image_surface); +  cairo_restore (ctxcanvas->cr);  }  static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, rw, rh; -  unsigned char* rgba_data; -  int stride; -  cairo_surface_t* surface, *new_surface, *new_alpha_surface; -  cairo_t* cr; +  int i, j, rw, rh, pos, offset; +  unsigned long* data; +  cairo_surface_t* image_surface;    if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;    rw = xmax-xmin+1;    rh = ymax-ymin+1; -  y -= (h - 1);        /* Cairo image origin is at top-left */ -  stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rw); -  rgba_data = (unsigned char*)malloc(sizeof(unsigned char)*(stride * rh)); -   -  if (!rgba_data) return; +  image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rw, rh); -  surface = cairo_image_surface_create_for_data(rgba_data, CAIRO_FORMAT_ARGB32, rw, rh, stride); +  data = (unsigned long*)cairo_image_surface_get_data(image_surface); +  offset = cairo_image_surface_get_stride(image_surface)/4 - rw; -  d = 0;    for (i=ymax; i>=ymin; i--)    {      for (j=xmin; j<=xmax; j++)      { -      rgba_data[d] = b[i*iw+j]; d++; -      rgba_data[d] = g[i*iw+j]; d++; -      rgba_data[d] = r[i*iw+j]; d++; -      rgba_data[d] = a[i*iw+j]; d++; +      pos = i*iw+j; +      *data++ = sEncodeRGBA(r[pos], g[pos], b[pos], a[pos]);      } + +    if (offset) +      data += offset;    } -  // TODO: use only one surface ????? +  cairo_save (ctxcanvas->cr); -  /* Scaling RGB surface to fit into the image */ -//  if (w != rw || h != rh) -  { -    new_surface = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, w, h); -    cr = cairo_create (new_surface); +  y -= (h - 1);        /* Cairo image origin is at top-left */ -    /* Scale *before* setting the source surface (1) */ -    cairo_scale (cr, (double)w / rw, (double)h / rh); -    cairo_set_source_surface (cr, surface, 0, 0); -    cairo_paint (cr); +  cairo_rectangle(ctxcanvas->cr, x, y, w, h); +  cairo_clip(ctxcanvas->cr); -    cairo_destroy (cr); +  if (w != rw || h != rh) +  { +    /* Scale *before* setting the source surface (1) */ +    cairo_translate(ctxcanvas->cr, x, y); +    cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh); +    cairo_translate(ctxcanvas->cr, -x, -y);    } -  /* Scaling ALPHA surface to fit into the image */ -  { -    new_alpha_surface = cairo_surface_create_similar(surface, CAIRO_CONTENT_ALPHA, w, h); -    cr = cairo_create (new_alpha_surface); +  cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y); +  cairo_paint(ctxcanvas->cr); -    /* Scale *before* setting the source surface (1) */ -    cairo_scale (cr, (double)w / rw, (double)h / rh); -    cairo_set_source_surface (cr, surface, 0, 0); -    cairo_paint (cr); +  cairo_surface_destroy(image_surface); +  cairo_restore (ctxcanvas->cr); +} -    cairo_destroy (cr); -  } +static int sCalcPalSize(int size, const unsigned char *index) +{ +  int i, pal_size = 0; -  /* Put image rect */ -  cairo_set_source_surface(ctxcanvas->cr, new_surface, x, y); -  cairo_mask_surface(ctxcanvas->cr, new_alpha_surface, x, y); -//  cairo_pattern_set_extend(cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);  -//  cairo_paint(ctxcanvas->cr); +  for (i = 0; i < size; i++) +  { +    if (index[i] > pal_size) +      pal_size = index[i]; +  } -  cairo_surface_destroy(surface); -  cairo_surface_destroy(new_surface); -  cairo_surface_destroy(new_alpha_surface); -  free(rgba_data); +  pal_size++; +  return pal_size;  }  static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, rw, rh; -  unsigned char* rgb_data; -  int stride; -  cairo_surface_t* surface, *new_surface; -  cairo_t* cr; +  int i, j, rw, rh, pos, offset, pal_size; +  unsigned long* data, cairo_colors[256], c; +  cairo_surface_t* image_surface;    if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return;    rw = xmax-xmin+1;    rh = ymax-ymin+1; -  y -= (h - 1);        /* Cairo image origin is at top-left */ -  stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, rw); -  rgb_data = (unsigned char*)malloc(sizeof(unsigned char)*(stride * rh)); +  image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, rw, rh); -  if (!rgb_data) return; +  data = (unsigned long*)cairo_image_surface_get_data(image_surface); +  offset = cairo_image_surface_get_stride(image_surface)/4 - rw; -  surface = cairo_image_surface_create_for_data(rgb_data, CAIRO_FORMAT_RGB24, rw, rh, stride); +  pal_size = sCalcPalSize(iw*ih, index); +  for (i=0; i<pal_size; i++) +  { +    c = colors[i]; +    cairo_colors[i] = sEncodeRGBA(cdRed(c), cdGreen(c), cdBlue(c), 255); +  } -  d = 0;    for (i=ymax; i>=ymin; i--)    {      for (j=xmin; j<=xmax; j++)      { -      long c = colors[index[i*iw+j]]; -      rgb_data[d] = cdRed(c); d++; -      rgb_data[d] = cdGreen(c); d++; -      rgb_data[d] = cdBlue(c); d++; -      rgb_data[d] = (unsigned char)0; d++; +      pos = i*iw+j; +      *data++ = cairo_colors[index[pos]];      } -  } - -  /* Scaling surface to fit into the image */ -//  if (w != rw || h != rh) -  { -    new_surface = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, w, h); -    cr = cairo_create (new_surface); -    /* Scale *before* setting the source surface (1) */ -    cairo_scale (cr, (double)w / rw, (double)h / rh); -    cairo_set_source_surface (cr, surface, 0, 0); +    if (offset) +      data += offset; +  } -    /* To avoid getting the edge pixels blended with 0 alpha, -    * which would occur with the default EXTEND_NONE */ -    cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT);  +  cairo_save (ctxcanvas->cr); -    /* Replace the destination with the source instead of overlaying */ -    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); +  y -= (h - 1);        /* Cairo image origin is at top-left */ -    cairo_paint (cr); +  cairo_rectangle(ctxcanvas->cr, x, y, w, h); +  cairo_clip(ctxcanvas->cr); -    cairo_destroy (cr); +  if (w != rw || h != rh) +  { +    /* Scale *before* setting the source surface (1) */ +    cairo_translate(ctxcanvas->cr, x, y); +    cairo_scale (ctxcanvas->cr, (double)w / rw, (double)h / rh); +    cairo_translate(ctxcanvas->cr, -x, -y);    } -  cairo_set_source_surface(ctxcanvas->cr, surface, x, y); -  cairo_pattern_set_extend(cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);  +  cairo_set_source_surface(ctxcanvas->cr, image_surface, x, y);    cairo_paint(ctxcanvas->cr); -  cairo_surface_destroy(surface); -  cairo_surface_destroy(new_surface); -  free(rgb_data); +  cairo_surface_destroy(image_surface); +  cairo_restore (ctxcanvas->cr);  }  static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color) @@ -1178,17 +1207,17 @@ static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)    ctximage->h_mm = ctximage->h / ctximage->yres;    img_surface = cairo_surface_create_similar(cairo_get_target(ctxcanvas->cr), CAIRO_CONTENT_COLOR_ALPHA, w, h); -  ctximage->img = cairo_create(img_surface); +  ctximage->cr = cairo_create(img_surface); -  if (!ctximage->img) +  if (!ctximage->cr)    {      free(ctximage);      return (void *)0;    } -  cairo_rectangle(ctximage->img, 0, 0, ctximage->w, ctximage->h); -  cairo_set_source_rgba(ctximage->img, 1.0, 1.0, 1.0, 1.0); /* white opaque */ -  cairo_fill(ctximage->img); +  cairo_rectangle(ctximage->cr, 0, 0, ctximage->w, ctximage->h); +  cairo_set_source_rgba(ctximage->cr, 1.0, 0.0, 0.0, 1.0); /* white opaque */ +  cairo_fill(ctximage->cr);    cairo_surface_destroy(img_surface); @@ -1197,18 +1226,18 @@ static cdCtxImage *cdcreateimage (cdCtxCanvas *ctxcanvas, int w, int h)  static void cdkillimage (cdCtxImage *ctximage)  { -  cairo_destroy(ctximage->img); +  cairo_destroy(ctximage->cr);    free(ctximage);  }  static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y)  { -  cairo_save (ctximage->img); +  cairo_save (ctximage->cr);    /* reset to the identity. */ -  cairo_identity_matrix(ctximage->img); +  cairo_identity_matrix(ctximage->cr); -  cairo_reset_clip(ctximage->img); +  cairo_reset_clip(ctximage->cr);    if (ctxcanvas->canvas->invert_yaxis==0)  /* if 0, invert because the transform was reset here */      y = _cdInvertYAxis(ctxcanvas->canvas, y); @@ -1217,14 +1246,14 @@ static void cdgetimage (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int    y -= ctximage->h-1;    /* creates a pattern from the canvas and sets it as source in the image. */ -  cairo_set_source_surface(ctximage->img, cairo_get_target(ctxcanvas->cr), x, y); +  cairo_set_source_surface(ctximage->cr, cairo_get_target(ctxcanvas->cr), -x, -y); -  cairo_pattern_set_extend (cairo_get_source(ctximage->img), CAIRO_EXTEND_NONE);  -  cairo_set_operator (ctximage->img, CAIRO_OPERATOR_SOURCE); -  cairo_paint(ctximage->img);  /* paints the current source everywhere within the current clip region. */ +  cairo_pattern_set_extend (cairo_get_source(ctximage->cr), CAIRO_EXTEND_NONE);  +  cairo_set_operator (ctximage->cr, CAIRO_OPERATOR_SOURCE); +  cairo_paint(ctximage->cr);  /* paints the current source everywhere within the current clip region. */    /* must restore matrix, clipping and source */ -  cairo_restore (ctximage->img); +  cairo_restore (ctximage->cr);  }  static void cdputimagerect (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x, int y, int xmin, int xmax, int ymin, int ymax) @@ -1234,14 +1263,11 @@ static void cdputimagerect (cdCtxCanvas *ctxcanvas, cdCtxImage *ctximage, int x,    /* y is the bottom-left of the image region in CD */    y -= (ymax-ymin+1)-1; -  cairo_reset_clip(ctxcanvas->cr);    cairo_rectangle(ctxcanvas->cr, x, y, xmax-xmin+1, ymax-ymin+1);    cairo_clip(ctxcanvas->cr); -  ymin = (ctximage->h-1) - ymax; /* ymin starts at the bottom of the image in CD, we want ymax, but oriented top-down */ -    /* creates a pattern from the image and sets it as source in the canvas. */ -  cairo_set_source_surface(ctxcanvas->cr, cairo_get_target(ctximage->img), xmin, ymin); +  cairo_set_source_surface(ctxcanvas->cr, cairo_get_target(ctximage->cr), x, y);    cairo_pattern_set_extend (cairo_get_source(ctxcanvas->cr), CAIRO_EXTEND_NONE);     cairo_set_operator (ctxcanvas->cr, CAIRO_OPERATOR_SOURCE); @@ -1266,7 +1292,6 @@ static void cdscrollarea (cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin,      _cdSwapInt(ymin, ymax);    } -  cairo_reset_clip(ctxcanvas->cr);    cairo_rectangle(ctxcanvas->cr, xmin+dx, ymin+dy, xmax-xmin+1, ymax-ymin+1);    cairo_clip(ctxcanvas->cr); diff --git a/src/cairo/cdcairoctx.h b/src/cairo/cdcairoctx.h index 7516875..97a8707 100644 --- a/src/cairo/cdcairoctx.h +++ b/src/cairo/cdcairoctx.h @@ -18,7 +18,7 @@ struct _cdCtxImage {    double w_mm, h_mm;   /* size in mm                                  */                      double xres, yres;   /* resolution in pixels/mm                     */         int bpp; -  cairo_t* img; +  cairo_t* cr;  };  struct _cdCtxCanvas diff --git a/src/cairo/cdcairodbuf.c b/src/cairo/cdcairodbuf.c index 4861014..1395e8c 100644 --- a/src/cairo/cdcairodbuf.c +++ b/src/cairo/cdcairodbuf.c @@ -60,7 +60,7 @@ static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)    ctximage = image_dbuffer->ctximage;    /* Init the driver DBuffer */ -  ctxcanvas = cdcairoCreateCanvas(canvas, ctximage->img); +  ctxcanvas = cdcairoCreateCanvas(canvas, ctximage->cr);    if (!ctxcanvas)      return; diff --git a/src/cairo/cdcairoimg.c b/src/cairo/cdcairoimg.c index 4eda676..04b3f46 100644 --- a/src/cairo/cdcairoimg.c +++ b/src/cairo/cdcairoimg.c @@ -18,7 +18,7 @@ static void cdkillcanvas(cdCtxCanvas* ctxcanvas)  static void cdcreatecanvas(cdCanvas* canvas, void *data)  {    cdCtxImage *ctximage = ((cdImage*)data)->ctximage; -  cdcairoCreateCanvas(canvas, (cairo_t*)ctximage->img); +  cdcairoCreateCanvas(canvas, (cairo_t*)ctximage->cr);    canvas->w = ctximage->w;    canvas->h = ctximage->h;    canvas->w_mm = ctximage->w_mm; diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c index 8135fa1..f0eb98e 100644 --- a/src/drv/cdirgb.c +++ b/src/drv/cdirgb.c @@ -1341,7 +1341,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns  static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, pal_size, idx, img_topdown = 0; +  int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, idx, img_topdown = 0;    const unsigned char *src_index;    if (ctxcanvas->canvas->use_matrix) @@ -1371,22 +1371,6 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi    rw = xmax-xmin+1;    rh = ymax-ymin+1; -  /* Como nao sabemos o tamanho da palette a priori,  -  teremos que ver qual o maior indice usado na imagem. */ -  pal_size = 0; -   -  for (l=0; l<ih; l++)  -  { -    for (c=0; c<iw; c++)  -    { -      idx = index[l*iw + c]; -      if (idx > pal_size) -        pal_size = idx; -    } -  } -   -  pal_size++; -    /* testa se tem que fazer zoom */    if (rw != w || rh != h)    { diff --git a/src/drv/cdpdf.c b/src/drv/cdpdf.c index f2c608f..e6f3f73 100644 --- a/src/drv/cdpdf.c +++ b/src/drv/cdpdf.c @@ -360,7 +360,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do    if (w==h)    {      PDF_moveto(ctxcanvas->pdf, xc, yc); -    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2); +    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);      PDF_fill(ctxcanvas->pdf);    }    else /* Elipse: mudar a escala p/ criar a partir do circulo */ @@ -373,15 +373,7 @@ static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, do      PDF_moveto(ctxcanvas->pdf, xc, yc);      PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2); - -    if (ctxcanvas->canvas->interior_style == CD_SOLID || -        ctxcanvas->canvas->interior_style == CD_PATTERN) -      PDF_fill(ctxcanvas->pdf); -    else -    { -      PDF_lineto(ctxcanvas->pdf, xc, yc); -      PDF_stroke(ctxcanvas->pdf); -    } +    PDF_fill(ctxcanvas->pdf);      PDF_restore(ctxcanvas->pdf);  /* restore from local */    } @@ -398,7 +390,7 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou    if (w==h)    { -    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2); +    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);      PDF_fill_stroke(ctxcanvas->pdf);    }    else /* Elipse: mudar a escala p/ criar a partir do circulo */ @@ -407,9 +399,10 @@ static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, dou      /* local transform */      PDF_translate(ctxcanvas->pdf, xc, yc); -    PDF_scale(ctxcanvas->pdf, 1, w/h); +    PDF_scale(ctxcanvas->pdf, w/h, 1); +    PDF_translate(ctxcanvas->pdf, -xc, -yc); -    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*w, a1, a2); +    PDF_arc(ctxcanvas->pdf, xc, yc, 0.5*h, a1, a2);      PDF_fill_stroke(ctxcanvas->pdf);      PDF_restore(ctxcanvas->pdf);  /* restore from local */ @@ -964,7 +957,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)  static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, image, rw, rh, rgb_size; +  int i, j, d, image, rw, rh, rgb_size, pos;    char options[80];    unsigned char* rgb_data; @@ -981,9 +974,10 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi    for (i=ymax; i>=ymin; i--)      for (j=xmin; j<=xmax; j++)      { -      rgb_data[d] = r[i*iw+j]; d++; -      rgb_data[d] = g[i*iw+j]; d++; -      rgb_data[d] = b[i*iw+j]; d++; +      pos = i*iw+j; +      rgb_data[d] = r[pos]; d++; +      rgb_data[d] = g[pos]; d++; +      rgb_data[d] = b[pos]; d++;      }    PDF_create_pvf(ctxcanvas->pdf, "cd_raw_rgb", 0, rgb_data, rgb_size, ""); @@ -1000,7 +994,7 @@ static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi  static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, image, image_mask, rw, rh, alpha_size, rgb_size; +  int i, j, d, image, image_mask, rw, rh, alpha_size, rgb_size, pos;    char options[80];    unsigned char *rgb_data, *alpha_data; @@ -1017,9 +1011,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns    for (i=ymax; i>=ymin; i--)      for (j=xmin; j<=xmax; j++)      { -      rgb_data[d] = r[i*iw+j]; d++; -      rgb_data[d] = g[i*iw+j]; d++; -      rgb_data[d] = b[i*iw+j]; d++; +      pos = i*iw+j; +      rgb_data[d] = r[pos]; d++; +      rgb_data[d] = g[pos]; d++; +      rgb_data[d] = b[pos]; d++;      }    alpha_size = rw*rh; @@ -1030,7 +1025,8 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns    for (i=ymax; i>=ymin; i--)      for (j=xmin; j<=xmax; j++)      { -      alpha_data[d] = a[i*iw+j]; d++; +      pos = i*iw+j; +      alpha_data[d] = a[pos]; d++;      }    PDF_create_pvf(ctxcanvas->pdf, "cd_raw_rgb", 0, rgb_data, rgb_size, ""); @@ -1053,9 +1049,10 @@ static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const uns  static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)  { -  int i, j, d, rw, rh, image, rgb_size; +  int i, j, d, rw, rh, image, rgb_size, pos;    char options[80];    unsigned char* rgb_data; +  unsigned char r, g, b;    if (xmin<0 || ymin<0 || xmax-xmin+1>iw || ymax-ymin+1>ih) return; @@ -1070,8 +1067,8 @@ static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsi    for (i=ymax; i>=ymin; i--)      for (j=xmin; j<=xmax; j++)      { -      unsigned char r, g, b; -      cdDecodeColor(colors[index[i*iw+j]], &r, &g, &b); +      pos = i*iw+j; +      cdDecodeColor(colors[index[pos]], &r, &g, &b);        rgb_data[d] = r; d++;        rgb_data[d] = g; d++;        rgb_data[d] = b; d++; diff --git a/src/gdiplus/cdwinp.cpp b/src/gdiplus/cdwinp.cpp index aba6c1e..ea14628 100644 --- a/src/gdiplus/cdwinp.cpp +++ b/src/gdiplus/cdwinp.cpp @@ -598,7 +598,7 @@ static void cdwpFixAngles(cdCtxCanvas* ctxcanvas, double *angle1, double *angle2  {    if (ctxcanvas->canvas->invert_yaxis)    { -    // GDI+ angle are clock-wise by default +    // GDI+ angles are clock-wise by default      *angle1 *= -1;      *angle2 *= -1;    }  | 
