static void chk_clipping(XEngine *xeng) { p_win *w = xeng->win; if (!xeng->clipping) { int x0, y0, x1, y1; int lm = xeng->leftMargin; int tm = xeng->topMargin; if (xeng->e.damaged) { GpBox *box = DamageClip(&xeng->e.damage); GpXYMap map; if (xeng->w != w) GpSetMap(&xeng->swapped.viewport, &xeng->swapped.window, &map); else map = xeng->e.devMap; GetXRectangle(&map, box, &x0, &y0, &x1, &y1); /* additional restriction for vignetting by window borders */ if (x0 < lm) x0 = lm; if (x1 > lm+xeng->wtop) x1 = lm+xeng->wtop; if (y0 < tm) y0 = tm; if (y1 > tm+xeng->htop) y1 = tm+xeng->htop; } else { x0 = lm; x1 = lm+xeng->wtop; y0 = tm; y1 = tm+xeng->htop; } xeng->clipping = 1; if (x1<=x0) x1 = x0+1; if (y1<=y0) y1 = y0+1; p_clip(w, x0, y0, x1, y1); } }
static void ChangeMap(Engine *engine) { XEngine *xeng = (XEngine *)engine; p_win *w = xeng->w; int landscape = xeng->width > xeng->height; int x0, y0, x1, y1; GpBox *clipport; if (!w) return; /* check to be sure that landscape/portrait mode hasn't changed */ if (landscape!=xeng->e.landscape) { /* this is probably insane if in animation mode... */ SetXTransform(&xeng->e.transform, xeng->e.landscape, xeng->dpi); xeng->width = (int)xeng->e.transform.window.xmax; xeng->height = (int)xeng->e.transform.window.ymin; xeng->swapped = xeng->e.transform; /* make adjustments to allow for SetXTransform, then recenter */ if (xeng->w != xeng->win) { xeng->a_x += xeng->x+1; xeng->a_y += xeng->y+1; } xeng->x = xeng->y = -1; GxRecenter(xeng, xeng->wtop+xeng->leftMargin, xeng->htop+xeng->topMargin); } /* do generic change map */ GpComposeMap(engine); /* get current clip window */ if (xeng->e.damaged) clipport = DamageClip(&xeng->e.damage); else clipport = &gistT.viewport; if (clipport) { /* set clipping rectangle for this XEngine */ GetXRectangle(&engine->devMap, clipport, &x0, &y0, &x1, &y1); if (xeng->w == xeng->win) { /* additional restriction for vignetting by window borders */ int lm = xeng->leftMargin; int tm = xeng->topMargin; if (x0 < lm) x0 = lm; if (x1 > lm+xeng->wtop) x1 = lm+xeng->wtop; if (y0 < tm) y0 = tm; if (y1 > tm+xeng->htop) y1 = tm+xeng->htop; xeng->clipping = 1; } else { if (x0 < 0) x0 = 0; if (x1 > xeng->a_width) x1 = xeng->a_width; if (y0 < 0) y0 = 0; if (y1 > xeng->a_height) y1 = xeng->a_height; if (x0==0 && x1==xeng->a_width && y0==0 && y1==xeng->a_height) x0 = x1 = y0 = y1 = 0; } if (x0 || x1 || y0 || y1) { if (x1<=x0) x1 = x0+1; if (y1<=y0) y1 = y0+1; } p_clip(xeng->w, x0, y0, x1, y1); } }
static void ClearArea(Engine *engine, GpBox *box) { XEngine *xeng= (XEngine *)engine; p_win *w = xeng->w; int x0, y0, x1, y1; if (!w) return; /* if this is animation mode, do not try to clear window */ if (w==xeng->win) { int lm = xeng->leftMargin; int tm = xeng->topMargin; GetXRectangle(&engine->devMap, box, &x0, &y0, &x1, &y1); if (x0 < lm) x0 = lm; if (x1 > lm+xeng->wtop) x1 = lm+xeng->wtop; if (y0 < tm) y0 = tm; if (y1 > tm+xeng->htop) y1 = tm+xeng->htop; p_color(w, P_BG); p_rect(w, x0, y0, x1, y1, 0); } }
int GxAnimate(Engine *engine, GpBox *viewport) { XEngine *xeng = GisXEngine(engine); int x, y, x0, y0, x1, y1; GpBox *v, *w; GpReal xmin, xmax, ymin, ymax; GpReal scalx, offx, scaly, offy; if (!xeng || !xeng->w) return 1; if (xeng->w!=xeng->win) GxDirect(engine); v = &xeng->e.transform.viewport; /* NDC */ w = &xeng->e.transform.window; /* pixels */ /* get NDC-->pixel mapping coefficients */ scalx = xeng->e.devMap.x.scale; offx = xeng->e.devMap.x.offset; scaly = xeng->e.devMap.y.scale; offy = xeng->e.devMap.y.offset; /* clip given viewport to portion of NDC space which is actually * visible now -- note that v is either gLandscape or gPortrait, * so that min<max for v; must also be true for input viewport */ GetVisibleNDC(xeng, &xmin, &xmax, &ymin, &ymax); if (viewport->xmin>xmin) xmin = viewport->xmin; if (viewport->xmax<xmax) xmax = viewport->xmax; if (viewport->ymin>ymin) ymin = viewport->ymin; if (viewport->ymax<ymax) ymax = viewport->ymax; /* install NDC-->pixel transform for animation pixmap */ v->xmin = xmin; v->xmax = xmax; v->ymin = ymin; v->ymax = ymax; /* set the engine transform to map the specified viewport into * offscreen pixels, and get (x,y) offset from full window pixels * to offscreen pixels */ w->xmin = scalx*xmin+offx; w->xmax = scalx*xmax+offx; if (w->xmax > w->xmin) { x = (int)w->xmin; w->xmax -= w->xmin; w->xmin = 0.0; } else { x = (int)w->xmax; w->xmin -= w->xmax; w->xmax = 0.0; } w->ymin = scaly*ymin+offy; w->ymax = scaly*ymax+offy; if (w->ymax > w->ymin) { y = (int)w->ymin; w->ymax -= w->ymin; w->ymin = 0.0; } else { y = (int)w->ymax; w->ymin -= w->ymax; w->ymax = 0.0; } GpDeviceMap((Engine *)xeng); GetXRectangle(&xeng->e.devMap, v, &x0, &y0, &x1, &y1); x1 -= x0; y1 -= y0; /* create the offscreen pixmap */ xeng->w = p_offscreen(xeng->win, x1, y1); if (!xeng->w) { xeng->w = xeng->win; xeng->e.transform = xeng->swapped; GpDeviceMap((Engine *)xeng); return 2; } xeng->a_width = x1; xeng->a_height = y1; xeng->a_x = x; xeng->a_y = y; /* set coordinate mapping for offscreen */ ChangeMap((Engine *)xeng); /* reset mapping clip to whole visible window */ if (xeng->wtop>0) x1 = xeng->wtop+xeng->leftMargin; else x1 = xeng->leftMargin+1; if (xeng->htop>0) y1 = xeng->htop+xeng->topMargin; else y1 = xeng->topMargin+1; xeng->clipping = 1; p_clip(xeng->win, xeng->leftMargin, xeng->topMargin, x1, y1); p_clear(xeng->w); return 0; }