void cdfCanvasBox(cdCanvas* canvas, double xmin, double xmax, double ymin, double ymax) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (canvas->interior_style == CD_HOLLOW) { cdfCanvasRect(canvas, xmin, xmax, ymin, ymax); return; } if (!cdfCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; if (canvas->use_origin) { xmin += canvas->forigin.x; xmax += canvas->forigin.x; ymin += canvas->forigin.y; ymax += canvas->forigin.y; } if (canvas->invert_yaxis) { ymin = _cdInvertYAxis(canvas, ymin); ymax = _cdInvertYAxis(canvas, ymax); _cdSwapDouble(ymin, ymax); } if (canvas->cxFBox) canvas->cxFBox(canvas->ctxcanvas, xmin, xmax, ymin, ymax); else canvas->cxBox(canvas->ctxcanvas, _cdRound(xmin), _cdRound(xmax), _cdRound(ymin), _cdRound(ymax)); }
void cdCanvasScrollArea(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, int dx, int dy) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (!canvas->cxScrollArea) return; if (!cdCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; if (dx == 0 && dy == 0) return; if (canvas->use_origin) { xmin += canvas->origin.x; xmax += canvas->origin.x; ymin += canvas->origin.y; ymax += canvas->origin.y; } if (canvas->invert_yaxis) { dy = -dy; ymin = _cdInvertYAxis(canvas, ymin); ymax = _cdInvertYAxis(canvas, ymax); _cdSwapInt(ymin, ymax); } canvas->cxScrollArea(canvas->ctxcanvas, xmin, xmax, ymin, ymax, dx, dy); }
void cdCanvasBox(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (canvas->interior_style == CD_HOLLOW) { cdCanvasRect(canvas, xmin, xmax, ymin, ymax); return; } if (!cdCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; if (canvas->use_origin) { xmin += canvas->origin.x; xmax += canvas->origin.x; ymin += canvas->origin.y; ymax += canvas->origin.y; } if (canvas->invert_yaxis) { ymin = _cdInvertYAxis(canvas, ymin); ymax = _cdInvertYAxis(canvas, ymax); _cdSwapInt(ymin, ymax); } canvas->cxBox(canvas->ctxcanvas, xmin, xmax, ymin, ymax); }
void cdCanvasLine(cdCanvas* canvas, int x1, int y1, int x2, int y2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (x1 == x2 && y1 == y2) { cdCanvasPixel(canvas, x1, y1, canvas->foreground); return; } if (canvas->use_origin) { x1 += canvas->origin.x; y1 += canvas->origin.y; x2 += canvas->origin.x; y2 += canvas->origin.y; } if (canvas->invert_yaxis) { y1 = _cdInvertYAxis(canvas, y1); y2 = _cdInvertYAxis(canvas, y2); } canvas->cxLine(canvas->ctxcanvas, x1, y1, x2, y2); }
void cdfCanvasLine(cdCanvas* canvas, double x1, double y1, double x2, double y2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (x1 == x2 && y1 == y2) { cdCanvasPixel(canvas, _cdRound(x1), _cdRound(y1), canvas->foreground); return; } if (canvas->use_origin) { x1 += canvas->forigin.x; y1 += canvas->forigin.y; x2 += canvas->forigin.x; y2 += canvas->forigin.y; } if (canvas->invert_yaxis) { y1 = _cdInvertYAxis(canvas, y1); y2 = _cdInvertYAxis(canvas, y2); } if (canvas->cxFLine) canvas->cxFLine(canvas->ctxcanvas, x1, y1, x2, y2); else canvas->cxLine(canvas->ctxcanvas, _cdRound(x1), _cdRound(y1), _cdRound(x2), _cdRound(y2)); }
void cdSimTextFT(cdCtxCanvas* ctxcanvas, int x, int y, const char* s, int len) { cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas; cdSimulation* simulation = canvas->simulation; FT_Face face; FT_GlyphSlot slot; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ FT_Error error; int i = 0; if (!simulation->tt_text->face) return; face = simulation->tt_text->face; slot = face->glyph; /* the pen position is in cartesian space coordinates */ if (simulation->canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); /* y is already inverted, invert back to cartesian space */ /* move the reference point to the baseline-left */ simGetPenPos(simulation->canvas, x, y, s, len, &matrix, &pen); while(i<len) { /* set transformation */ FT_Set_Transform(face, &matrix, &pen); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char(face, (unsigned char)s[i], FT_LOAD_RENDER); if (error) {i++; continue;} /* ignore errors */ x = slot->bitmap_left; y = slot->bitmap_top-slot->bitmap.rows; /* CD image reference point is at bottom-left */ if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); /* now, draw to our target surface (convert position) */ simDrawTextBitmap(simulation, &slot->bitmap, x, y); /* increment pen position */ pen.x += slot->advance.x; pen.y += slot->advance.y; i++; } }
void cdCanvasPutImageRectMap(cdCanvas* canvas, int iw, int ih, const unsigned char *index, const long *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) { assert(canvas); assert(index); assert(iw>0); assert(ih>0); if (!_cdCheckCanvas(canvas)) return; if (w == 0) w = iw; if (h == 0) h = ih; if (xmax == 0) xmax = iw - 1; if (ymax == 0) ymax = ih - 1; if (!cdCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; cdNormalizeLimits(iw, ih, &xmin, &xmax, &ymin, &ymax); if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); if (colors == NULL) colors = cd_getgraycolormap(); canvas->cxPutImageRectMap(canvas->ctxcanvas, iw, ih, index, colors, x, y, w, h, xmin, xmax, ymin, ymax); }
void cdCanvasPutImageRect(cdCanvas* canvas, cdImage* image, int x, int y, int xmin, int xmax, int ymin, int ymax) { assert(canvas); assert(image); if (!_cdCheckCanvas(canvas)) return; if (!image) return; if (image->cxPutImageRect != canvas->cxPutImageRect) return; if (xmax == 0) xmax = image->w - 1; if (ymax == 0) ymax = image->h - 1; if (!cdCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; cdNormalizeLimits(image->w, image->h, &xmin, &xmax, &ymin, &ymax); if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); canvas->cxPutImageRect(canvas->ctxcanvas, image->ctximage, x, y, xmin, xmax, ymin, ymax); }
void cdfCanvasArc(cdCanvas* canvas, double xc, double yc, double w, double h, double angle1, double angle2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (angle1 == angle2 || w == 0 || h == 0) return; sNormAngles(&angle1, &angle2); if (canvas->use_origin) { xc += canvas->forigin.x; yc += canvas->forigin.y; } if (canvas->invert_yaxis) yc = _cdInvertYAxis(canvas, yc); if (canvas->cxFArc) canvas->cxFArc(canvas->ctxcanvas, xc, yc, w, h, angle1, angle2); else canvas->cxArc(canvas->ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), angle1, angle2); }
void cdCanvasPutImageRectRGB(cdCanvas* canvas, 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) { assert(canvas); assert(iw>0); assert(ih>0); assert(r); assert(g); assert(b); if (!_cdCheckCanvas(canvas)) return; if (w == 0) w = iw; if (h == 0) h = ih; if (xmax == 0) xmax = iw - 1; if (ymax == 0) ymax = ih - 1; if (!cdCheckBoxSize(&xmin, &xmax, &ymin, &ymax)) return; cdNormalizeLimits(iw, ih, &xmin, &xmax, &ymin, &ymax); if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); if (canvas->cxPutImageRectMap && (canvas->bpp <= 8 || !canvas->cxPutImageRectRGB)) cdSimPutImageRectRGB(canvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax); else if (canvas->cxPutImageRectRGB) canvas->cxPutImageRectRGB(canvas->ctxcanvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax); }
double cdfCanvasInvertYAxis(cdCanvas* canvas, double y) { double yi; assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; yi = _cdInvertYAxis(canvas, y); if (canvas->use_origin) yi -= 2*canvas->origin.y; return yi; }
void cdCanvasPixel(cdCanvas* canvas, int x, int y, long color) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); canvas->cxPixel(canvas->ctxcanvas, x, y, color); }
double cdfCanvasUpdateYAxis(cdCanvas* canvas, double* y) { assert(canvas); assert(y); if (!_cdCheckCanvas(canvas)) return CD_ERROR; if(!(canvas->context->caps&CD_CAP_YAXIS)) { *y = _cdInvertYAxis(canvas, *y); if (canvas->use_origin) *y -= 2*canvas->origin.y; } return *y; }
void cdfCanvasSector(cdCanvas* canvas, double xc, double yc, double w, double h, double angle1, double angle2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (angle1 == angle2 || w == 0 || h == 0) return; sNormAngles(&angle1, &angle2); if (canvas->interior_style == CD_HOLLOW) { cdfCanvasArc(canvas, xc, yc, w, h, angle1, angle2); if (fabs(angle2-angle1) < 360) { double xi,yi,xf,yf; xi = xc + w*cos(CD_DEG2RAD*angle1)/2.0; yi = yc + h*sin(CD_DEG2RAD*angle1)/2.0; xf = xc + w*cos(CD_DEG2RAD*angle2)/2.0; yf = yc + h*sin(CD_DEG2RAD*angle2)/2.0; cdfCanvasLine(canvas, xi, yi, xc, yc); cdfCanvasLine(canvas, xc, yc, xf, yf); } return; } if (canvas->use_origin) { xc += canvas->forigin.x; yc += canvas->forigin.y; } if (canvas->invert_yaxis) yc = _cdInvertYAxis(canvas, yc); if (canvas->cxFSector) canvas->cxFSector(canvas->ctxcanvas, xc, yc, w, h, angle1, angle2); else canvas->cxSector(canvas->ctxcanvas, _cdRound(xc), _cdRound(yc), _cdRound(w), _cdRound(h), angle1, angle2); }
void cdfCanvasVertex(cdCanvas* canvas, double x, double y) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (!canvas->cxFPoly) { cdCanvasVertex(canvas, _cdRound(x), _cdRound(y)); return; } if (canvas->use_fpoly == 0) return; /* real vertex inside a integer polygon */ if (!canvas->fpoly) { canvas->fpoly = (cdfPoint*)malloc(sizeof(cdfPoint)*(_CD_POLY_BLOCK+1)); canvas->fpoly_size = _CD_POLY_BLOCK; } canvas->use_fpoly = 1; if (!sCheckPathArc(canvas)) { if (canvas->use_origin) { x += canvas->forigin.x; y += canvas->forigin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); } if (canvas->poly_n == canvas->fpoly_size) { canvas->fpoly_size += _CD_POLY_BLOCK; canvas->fpoly = (cdfPoint*)realloc(canvas->fpoly, sizeof(cdfPoint) * (canvas->fpoly_size+1)); } canvas->fpoly[canvas->poly_n].x = x; canvas->fpoly[canvas->poly_n].y = y; canvas->poly_n++; }
void cdCanvasGetImage(cdCanvas* canvas, cdImage* image, int x, int y) { assert(canvas); assert(image); if (!_cdCheckCanvas(canvas)) return; if (!image) return; if (image->cxGetImage != canvas->cxGetImage) return; if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); canvas->cxGetImage(canvas->ctxcanvas, image->ctximage, x, y); }
void cdCanvasVertex(cdCanvas* canvas, int x, int y) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (canvas->use_fpoly == 1) return; /* integer vertex inside a real polygon */ if (!canvas->poly) { canvas->poly = (cdPoint*)malloc(sizeof(cdPoint)*(_CD_POLY_BLOCK+1)); /* always add 1 so we add another point at the end if necessary */ canvas->poly_size = _CD_POLY_BLOCK; } canvas->use_fpoly = 0; if (!sCheckPathArc(canvas)) { if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); } if (canvas->poly_n == canvas->poly_size) { canvas->poly_size += _CD_POLY_BLOCK; canvas->poly = (cdPoint*)realloc(canvas->poly, sizeof(cdPoint) * (canvas->poly_size+1)); } if (canvas->poly_mode != CD_BEZIER && canvas->poly_mode != CD_PATH && canvas->poly_n > 0 && canvas->poly[canvas->poly_n-1].x == x && canvas->poly[canvas->poly_n-1].y == y) return; /* avoid duplicate points, if not a bezier */ canvas->poly[canvas->poly_n].x = x; canvas->poly[canvas->poly_n].y = y; canvas->poly_n++; }
void cdCanvasSector(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1, double angle2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (angle1 == angle2 || w == 0 || h == 0) return; sNormAngles(&angle1, &angle2); if (canvas->interior_style == CD_HOLLOW) { cdCanvasArc(canvas, xc, yc, w, h, angle1, angle2); if (fabs(angle2-angle1) < 360) { int xi,yi,xf,yf; xi = xc + cdRound(w*cos(CD_DEG2RAD*angle1)/2.0); yi = yc + cdRound(h*sin(CD_DEG2RAD*angle1)/2.0); xf = xc + cdRound(w*cos(CD_DEG2RAD*angle2)/2.0); yf = yc + cdRound(h*sin(CD_DEG2RAD*angle2)/2.0); cdCanvasLine(canvas, xi, yi, xc, yc); cdCanvasLine(canvas, xc, yc, xf, yf); } return; } if (canvas->use_origin) { xc += canvas->origin.x; yc += canvas->origin.y; } if (canvas->invert_yaxis) yc = _cdInvertYAxis(canvas, yc); canvas->cxSector(canvas->ctxcanvas, xc, yc, w, h, angle1, angle2); }
void cdCanvasArc(cdCanvas* canvas, int xc, int yc, int w, int h, double angle1, double angle2) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (angle1 == angle2 || w == 0 || h == 0) return; sNormAngles(&angle1, &angle2); if (canvas->use_origin) { xc += canvas->origin.x; yc += canvas->origin.y; } if (canvas->invert_yaxis) yc = _cdInvertYAxis(canvas, yc); canvas->cxArc(canvas->ctxcanvas, xc, yc, w, h, angle1, angle2); }
void cdCanvasMark(cdCanvas* canvas, int x, int y) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; if (canvas->mark_size == 1) { cdCanvasPixel(canvas, x, y, canvas->foreground); return; } if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); cdSimMark(canvas, x, y); }
void cdCanvasGetImageRGB(cdCanvas* canvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h) { assert(canvas); assert(r); assert(g); assert(b); assert(w>0); assert(h>0); if (!_cdCheckCanvas(canvas)) return; if (canvas->use_origin) { x += canvas->origin.x; y += canvas->origin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); if (canvas->cxGetImageRGB) canvas->cxGetImageRGB(canvas->ctxcanvas, r, g, b, x, y, w, h); }
void cdfSimMark(cdCanvas* canvas, double x, double y) { int oldinteriorstyle = canvas->interior_style; int oldlinestyle = canvas->line_style; int oldlinewidth = canvas->line_width; double size, half_size, bottom, top, left, right; if (canvas->mark_type == CD_DIAMOND || canvas->mark_type == CD_HOLLOW_DIAMOND) { if (canvas->use_origin) { x += canvas->forigin.x; y += canvas->forigin.y; } if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); } size = (double)canvas->mark_size; half_size = size / 2; bottom = y - half_size; top = y + half_size; left = x - half_size; right = x + half_size; if (canvas->interior_style != CD_SOLID && (canvas->mark_type == CD_CIRCLE || canvas->mark_type == CD_BOX || canvas->mark_type == CD_DIAMOND)) cdCanvasInteriorStyle(canvas, CD_SOLID); if (canvas->line_style != CD_CONTINUOUS && (canvas->mark_type == CD_STAR || canvas->mark_type == CD_PLUS || canvas->mark_type == CD_X || canvas->mark_type == CD_HOLLOW_BOX || canvas->mark_type == CD_HOLLOW_CIRCLE || canvas->mark_type == CD_HOLLOW_DIAMOND)) cdCanvasLineStyle(canvas, CD_CONTINUOUS); if (canvas->line_width != 1 && (canvas->mark_type == CD_STAR || canvas->mark_type == CD_PLUS || canvas->mark_type == CD_X || canvas->mark_type == CD_HOLLOW_BOX || canvas->mark_type == CD_HOLLOW_CIRCLE || canvas->mark_type == CD_HOLLOW_DIAMOND)) cdCanvasLineWidth(canvas, 1); switch (canvas->mark_type) { case CD_STAR: cdfCanvasLine(canvas, left, bottom, right, top); cdfCanvasLine(canvas, left, top, right, bottom); /* continue */ case CD_PLUS: cdfCanvasLine(canvas, left, y, right, y); cdfCanvasLine(canvas, x, bottom, x, top); break; case CD_X: cdfCanvasLine(canvas, left, bottom, right, top); cdfCanvasLine(canvas, left, top, right, bottom); break; case CD_HOLLOW_CIRCLE: cdfCanvasArc(canvas, x, y, size, size, 0, 360); break; case CD_HOLLOW_BOX: cdfCanvasRect(canvas, left, right, bottom, top); break; case CD_CIRCLE: cdfCanvasSector(canvas, x, y, size, size, 0, 360); break; case CD_BOX: cdfCanvasBox(canvas, left, right, bottom, top); break; case CD_HOLLOW_DIAMOND: case CD_DIAMOND: /* Do not use Begin/End here so Mark can be used inside a regular BeginEnd loop */ if (!canvas->cxFPoly) { cdPoint poly[5]; /* leave room for one more point */ poly[0].x = _cdRound(left); poly[0].y = _cdRound(y); poly[1].x = _cdRound(x); poly[1].y = _cdRound(top); poly[2].x = _cdRound(right); poly[2].y = _cdRound(y); poly[3].x = _cdRound(x); poly[3].y = _cdRound(bottom); if (canvas->mark_type == CD_DIAMOND) cdPoly(canvas, CD_FILL, poly, 4); else cdPoly(canvas, CD_CLOSED_LINES, poly, 4); } else { cdfPoint poly[5]; /* leave room for one more point */ poly[0].x = left; poly[0].y = y; poly[1].x = x; poly[1].y = top; poly[2].x = right; poly[2].y = y; poly[3].x = x; poly[3].y = bottom; if (canvas->mark_type == CD_DIAMOND) canvas->cxFPoly(canvas->ctxcanvas, CD_FILL, poly, 4); else canvas->cxFPoly(canvas->ctxcanvas, CD_CLOSED_LINES, poly, 4); } break; } if (canvas->interior_style != oldinteriorstyle && (canvas->mark_type == CD_CIRCLE || canvas->mark_type == CD_BOX || canvas->mark_type == CD_DIAMOND)) cdCanvasInteriorStyle(canvas, oldinteriorstyle); if (canvas->line_style != oldlinestyle && (canvas->mark_type == CD_STAR || canvas->mark_type == CD_PLUS || canvas->mark_type == CD_X || canvas->mark_type == CD_HOLLOW_BOX || canvas->mark_type == CD_HOLLOW_CIRCLE || canvas->mark_type == CD_HOLLOW_DIAMOND)) cdCanvasLineStyle(canvas, oldlinestyle); if (canvas->line_width != oldlinewidth && (canvas->mark_type == CD_STAR || canvas->mark_type == CD_PLUS || canvas->mark_type == CD_X || canvas->mark_type == CD_HOLLOW_BOX || canvas->mark_type == CD_HOLLOW_CIRCLE || canvas->mark_type == CD_HOLLOW_DIAMOND)) cdCanvasLineWidth(canvas, oldlinewidth); }
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, ew, eh, t_x, t_y, dst_offset, size, doff, rect[8]; float i_x, i_y, xfactor, yfactor; unsigned char *dst_index; double inv_matrix[6]; /* calculate the destination limits */ cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, rect); /* Setup inverse transform (use the original transform here, NOT ctxcanvas->xmatrix) */ cdImageRGBInitInverseTransform(w, h, xmin, xmax, ymin, ymax, &xfactor, &yfactor, ctxcanvas->canvas->matrix, inv_matrix); /* create an image for the destination area */ ew = (t_xmax-t_xmin+1); eh = (t_ymax-t_ymin+1); size = ew*eh; dst_index = malloc(size); if (!dst_index) return; memset(dst_index, 0, size); /* for all pixels in the destiny area */ for(t_y = t_ymin; t_y <= t_ymax; t_y++) { dst_offset = (t_y-t_ymin) * ew; for(t_x = t_xmin; t_x <= t_xmax; t_x++) { cdImageRGBInverseTransform(t_x, t_y, &i_x, &i_y, xfactor, yfactor, xmin, ymin, x, y, inv_matrix); if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1) { doff = (t_x-t_xmin) + dst_offset; *(dst_index+doff) = cdZeroOrderInterpolation(iw, ih, index, i_x, i_y); } } } { int ex = t_xmin, ey = t_ymin + eh-1; /* GdkPixbuf* origin is at top-left */ GdkPixbuf *pixbuf; GdkRegion *clip_polygon; GdkPoint pnt[4]; /* Since the transformation used was the original transformation, */ /* must invert the Y axis here. */ ey = _cdInvertYAxis(ctxcanvas->canvas, ey); /* use clipping to select only the transformed rectangle */ pnt[0].x = (short)rect[0]; pnt[0].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[1]); pnt[1].x = (short)rect[2]; pnt[1].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[3]); pnt[2].x = (short)rect[4]; pnt[2].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[5]); pnt[3].x = (short)rect[6]; pnt[3].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[7]); clip_polygon = gdk_region_polygon(pnt, 4, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE); /* combine with the existing clipping */ gdk_gc_set_function(ctxcanvas->gc, GDK_AND); gdk_gc_set_clip_region(ctxcanvas->gc, clip_polygon); cdwritemode(ctxcanvas, ctxcanvas->canvas->write_mode); /* reset gdk_gc_set_function */ pixbuf = cdgdkCreatePixbufMap(ew, eh, colors, dst_index, 0, 0, ew); if (!pixbuf) return; gdk_draw_pixbuf(ctxcanvas->wnd, ctxcanvas->gc, pixbuf, 0, 0, ex, ey, -1, -1, ctxcanvas->img_dither, 0, 0); /* reset clipping */ gdk_region_destroy(clip_polygon); cdclip(ctxcanvas, ctxcanvas->canvas->clip_mode); g_object_unref(pixbuf); } free(dst_index); }