int wdCanvasGetClipArea(cdCanvas* canvas, double *xmin, double *xmax, double *ymin, double *ymax) { int xminr, xmaxr, yminr, ymaxr, clip; assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; clip = cdCanvasGetClipArea(canvas, &xminr, &xmaxr, &yminr, &ymaxr); _wCanvas2World(canvas, xminr, yminr, *xmin, *ymin); _wCanvas2World(canvas, xmaxr, ymaxr, *xmax, *ymax); return clip; }
int cdCanvasActivate(cdCanvas *canvas) { assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; if (!canvas->cxActivate) return CD_OK; if (canvas->cxActivate(canvas->ctxcanvas) == CD_ERROR) return CD_ERROR; return CD_OK; }
void wdCanvasSetTransform(cdCanvas* canvas, double sx, double sy, double tx, double ty) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; canvas->sx = sx; canvas->tx = tx; canvas->sy = sy; canvas->ty = ty; canvas->s = sqrt(canvas->sx * canvas->sx + canvas->sy * canvas->sy); }
void wdCanvasClipArea(cdCanvas* canvas, double xmin, double xmax, double ymin, double ymax) { int xminr, xmaxr, yminr, ymaxr; assert(canvas); if (!_cdCheckCanvas(canvas)) return; _wWorld2Canvas(canvas, xmin, ymin, xminr, yminr); _wWorld2Canvas(canvas, xmax, ymax, xmaxr, ymaxr); cdCanvasClipArea(canvas, xminr, xmaxr, yminr, ymaxr); }
void wdCanvasWindow(cdCanvas* canvas, double xmin, double xmax, double ymin, double ymax) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; canvas->window.xmin = xmin; canvas->window.xmax = xmax; canvas->window.ymin = ymin; canvas->window.ymax = ymax; wdUpdateTransformation(canvas); }
int cdCanvasPlay(cdCanvas* canvas, cdContext* context, int xmin, int xmax, int ymin, int ymax, void *data) { assert(context); assert(canvas); if (!_cdCheckCanvas(canvas) || !context || !context->cxPlay) return CD_ERROR; /* the all can be 0 here, do not use cdCheckBoxSize */ if (xmin > xmax) _cdSwapInt(xmin, xmax); if (ymin > ymax) _cdSwapInt(ymin, ymax); return context->cxPlay(canvas, xmin, xmax, ymin, ymax, data); }
void wdCanvasGetTextBox(cdCanvas* canvas, double x, double y, const char *s, double *xmin, double *xmax, double *ymin, double *ymax) { int rx, ry, rxmin, rxmax, rymin, rymax; assert(canvas); if (!_cdCheckCanvas(canvas)) return; _wWorld2Canvas(canvas, x, y, rx, ry); cdCanvasGetTextBox(canvas, rx, ry, s, &rxmin, &rxmax, &rymin, &rymax); _wCanvas2World(canvas, rxmin, rymin, *xmin, *ymin); _wCanvas2World(canvas, rxmax, rymax, *xmax, *ymax); }
void wdCanvasViewport(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax) { assert(canvas); if (!_cdCheckCanvas(canvas)) return; canvas->viewport.xmin = xmin; canvas->viewport.xmax = xmax; canvas->viewport.ymin = ymin; canvas->viewport.ymax = ymax; wdUpdateTransformation(canvas); }
char* cdCanvasGetAttribute(cdCanvas* canvas, const char* name) { cdAttribute* attrib; assert(canvas); if (!_cdCheckCanvas(canvas)) return NULL; attrib = cd_findattrib(canvas, name, NULL); if (attrib && attrib->get) return attrib->get(canvas->ctxcanvas); return NULL; }
/* hidden function to simply control invert_yaxis behavior. several features will NOT behave as expected, such as arc direction, text position, image position and vector text */ int cdCanvasYAxisMode(cdCanvas* canvas, int invert) { int old_invert_yaxis; assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; if (invert == CD_QUERY) return canvas->invert_yaxis; old_invert_yaxis = canvas->invert_yaxis; canvas->invert_yaxis = invert; return old_invert_yaxis; }
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 wdCanvasGetTextBounds(cdCanvas* canvas, double x, double y, const char *s, double *rect) { int rx, ry, rrect[8]; assert(canvas); if (!_cdCheckCanvas(canvas)) return; _wWorld2Canvas(canvas, x, y, rx, ry); cdCanvasGetTextBounds(canvas, rx, ry, s, rrect); _wCanvas2World(canvas, rrect[0], rrect[1], rect[0], rect[1]); _wCanvas2World(canvas, rrect[2], rrect[3], rect[2], rect[3]); _wCanvas2World(canvas, rrect[4], rrect[5], rect[4], rect[5]); _wCanvas2World(canvas, rrect[6], rrect[7], rect[6], rect[7]); }
void wdCanvasGetTextSize(cdCanvas* canvas, const char *s, double *width, double *height) { int text_width, text_height; double origin_x, origin_y; double text_x, text_y; assert(canvas); if (!_cdCheckCanvas(canvas)) return; _wCanvas2World(canvas, 0, 0, origin_x, origin_y); cdCanvasGetTextSize(canvas, s, &text_width, &text_height); _wCanvas2World(canvas, text_width, text_height, text_x, text_y); if (width) *width = fabs(text_x - origin_x); if (height) *height = fabs(text_y - origin_y); }
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 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); }
cdState* cdCanvasSaveState(cdCanvas* canvas) { cdState* state; assert(canvas); if (!_cdCheckCanvas(canvas)) return NULL; state = (cdState*)malloc(sizeof(cdState)); memcpy(state, canvas, sizeof(cdCanvas)); /* is actually a cdCanvas */ if (state->pattern) { int size = state->pattern_w*state->pattern_h*sizeof(long); state->pattern = (long*)malloc(size); memcpy(state->pattern, canvas->pattern, size); } if (state->stipple) { int size = state->stipple_w*state->stipple_h; state->stipple = (unsigned char*)malloc(size); memcpy(state->stipple, canvas->stipple, size); } if (state->clip_poly) { int size = state->clip_poly_n*sizeof(cdPoint); state->clip_poly = (cdPoint*)malloc(size); memcpy(state->clip_poly, canvas->clip_poly, size); } if (state->clip_fpoly) { int size = state->clip_poly_n*sizeof(cdfPoint); state->clip_fpoly = (cdfPoint*)malloc(size); memcpy(state->clip_fpoly, canvas->clip_fpoly, size); } if (state->line_dashes) { int size = state->line_dashes_count*sizeof(int); state->line_dashes = (int*)malloc(size); memcpy(state->line_dashes, canvas->line_dashes, size); } return state; }
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); }
double wdCanvasMarkSize(cdCanvas* canvas, double size_mm) { int size; double mark_size_mm; assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; mark_size_mm = canvas->mark_size/canvas->xres; if (size_mm == CD_QUERY) return mark_size_mm; size = cdRound(size_mm*canvas->xres); if (size < 1) size = 1; canvas->mark_size = size; return mark_size_mm; }
double wdCanvasLineWidth(cdCanvas* canvas, double width_mm) { int width; double line_width_mm; assert(canvas); if (!_cdCheckCanvas(canvas)) return CD_ERROR; line_width_mm = canvas->line_width/canvas->xres; if (width_mm == CD_QUERY) return line_width_mm; width = cdRound(width_mm*canvas->xres); if (width < 1) width = 1; cdCanvasLineWidth(canvas, width); return line_width_mm; }
void wdCanvasGetFontDim(cdCanvas* canvas, double *max_width, double *height, double *ascent, double *descent) { double origin_x, origin_y, tmp = 0; double distance_x, distance_y; int font_max_width, font_height, font_ascent, font_descent; assert(canvas); if (!_cdCheckCanvas(canvas)) return; cdCanvasGetFontDim(canvas, &font_max_width, &font_height, &font_ascent, &font_descent); _wCanvas2World(canvas, 0, 0, origin_x, origin_y); _wCanvas2World(canvas, font_max_width, font_height, distance_x, distance_y); if (max_width) *max_width = fabs(distance_x - origin_x); if (height) *height = fabs(distance_y - origin_y); _wCanvas2World(canvas, tmp, font_ascent, tmp, distance_y); if (ascent) *ascent = fabs(distance_y - origin_y); _wCanvas2World(canvas, tmp, font_descent, tmp, distance_y); if (descent) *descent = fabs(distance_y - origin_y); }
void cdCanvasPutImageRectRGBA(cdCanvas* canvas, 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) { 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->cxPutImageRectRGBA) { if (canvas->cxGetImageRGB) cdSimPutImageRectRGBA(canvas, iw, ih, r, g, b, a, x, y, w, h, xmin, xmax, ymin, ymax); else if (!canvas->cxPutImageRectRGB) { if (canvas->cxPutImageRectMap) cdSimPutImageRectRGB(canvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax); } else canvas->cxPutImageRectRGB(canvas->ctxcanvas, iw, ih, r, g, b, x, y, w, h, xmin, xmax, ymin, ymax); } else canvas->cxPutImageRectRGBA(canvas->ctxcanvas, iw, ih, r, g, b, a, x, y, w, h, xmin, xmax, ymin, ymax); }
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 cdRegisterAttribute(cdCanvas *canvas, cdAttribute* attrib) { cdAttribute* old_attrib; int a; assert(canvas); assert(attrib); if (!attrib || !_cdCheckCanvas(canvas)) return; old_attrib = cd_findattrib(canvas, attrib->name, &a); if (old_attrib) canvas->attrib_list[a] = attrib; else { canvas->attrib_list[canvas->attrib_n] = attrib; canvas->attrib_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 wdCanvasPattern(cdCanvas* canvas, int w, int h, const long *color, double w_mm, double h_mm) { long *pattern = NULL; int w_pxl, h_pxl, x, y, cx, cy; int wratio, hratio; int *XTab, *YTab; assert(canvas); if (!_cdCheckCanvas(canvas)) return; cdCanvasMM2Pixel(canvas, w_mm, h_mm, &w_pxl, &h_pxl); /* to preserve the pattern characteristics must be an integer number */ wratio = cdRound((double)w_pxl/(double)w); hratio = cdRound((double)h_pxl/(double)h); wratio = (wratio <= 0)? 1: wratio; hratio = (hratio <= 0)? 1: hratio; w_pxl = wratio * w; h_pxl = hratio * h; pattern = (long*)malloc(w_pxl*h_pxl*sizeof(long)); XTab = cdGetZoomTable(w_pxl, w, 0); YTab = cdGetZoomTable(h_pxl, h, 0); for (y=0; y<h_pxl; y++) { cy = YTab[y]; for (x=0; x<w_pxl; x++) { cx = XTab[x]; pattern[x + y*w_pxl] = color[cx + cy*w]; } } cdCanvasPattern(canvas, w_pxl, h_pxl, pattern); free(XTab); free(YTab); free(pattern); }
void wdCanvasStipple(cdCanvas* canvas, int w, int h, const unsigned char *fgbg, double w_mm, double h_mm) { unsigned char *stipple = NULL; int w_pxl, h_pxl, x, y, cx, cy; int wratio, hratio; int *XTab, *YTab; assert(canvas); if (!_cdCheckCanvas(canvas)) return; cdCanvasMM2Pixel(canvas, w_mm, h_mm, &w_pxl, &h_pxl); /* to preserve the pattern characteristics must be an integer number */ wratio = cdRound((double)w_pxl/(double)w); hratio = cdRound((double)h_pxl/(double)h); wratio = (wratio <= 0)? 1: wratio; hratio = (hratio <= 0)? 1: hratio; w_pxl = wratio * w; h_pxl = hratio * h; stipple = (unsigned char*)malloc(w_pxl*h_pxl); XTab = cdGetZoomTable(w_pxl, w, 0); YTab = cdGetZoomTable(h_pxl, h, 0); for (y=0; y<h_pxl; y++) { cy = YTab[y]; for (x=0; x<w_pxl; x++) { cx = XTab[x]; stipple[x + y*w_pxl] = fgbg[cx + cy*w]; } } cdCanvasStipple(canvas, w_pxl, h_pxl, stipple); free(XTab); free(YTab); free(stipple); }
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 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); }