void GhFMAMode(int hcp, int animate) { /* 0 off, 1 on, 2 no change, 3 toggle */ if (hcp&2) hcpOn^= (hcp&1); /* if 2 bit, XOR operation */ else hcpOn= (hcp&1); /* else, COPY operation */ if ((animate&3)!=2) { Engine *display= currentDevice<0? 0 : ghDevices[currentDevice].display; if (!display) return; if ((animate&2) || (!animateOn)!=(!(animate&1))) { /* animation mode will actually change */ animateOn= !animateOn; if (animateOn) { GpBox aport; GpBox *port= GdClearSystem(); /* Can only animate using GdClearSystem if there is a current system; GdClearSystem returns appropriate box to animate, or 0 if can't. If no current system, then animate entire picture using ordinary GpClear. */ aport.xmin= 0.0; aport.xmax= 2.0; aport.ymin= 0.0; aport.ymax= 2.0; /* if (!port) { just animate everything */ port= &aport; animateOn= 2; /* } */ if (GxAnimate(display, port)) animateOn= 0; } else { GxDirect(display); } } } }
int GxAnimate(Engine *engine, GpBox *viewport) { XEngine *xeng = GisXEngine(engine); int x, y, 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; */ x1 = xeng->wtop; y1 = xeng->htop; /* 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; }