/* changed area is *dest* rect */ static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long plane) { RegionPtr result; BoxRec box; GCOP_UNWRAP(pGC); RL_DEBUG_MSG("copy plane start "); if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) { RootlessStartDrawing((WindowPtr) pSrc); } RootlessStartDrawing((WindowPtr) dst); result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty, plane); box.x1 = dstx + dst->x; box.x2 = box.x1 + w; box.y1 = dsty + dst->y; box.y2 = box.y1 + h; TRIM_BOX(box, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); GCOP_WRAP(pGC); RL_DEBUG_MSG("copy plane end\n"); return result; }
static void RootlessPutImage(DrawablePtr dst, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { BoxRec box; GCOP_UNWRAP(pGC); RL_DEBUG_MSG("put image start "); RootlessStartDrawing((WindowPtr) dst); pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits); box.x1 = x + dst->x; box.x2 = box.x1 + w; box.y1 = y + dst->y; box.y2 = box.y1 + h; TRIM_BOX(box, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); GCOP_WRAP(pGC); RL_DEBUG_MSG("put image end\n"); }
static void RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int sorted) { GC_SAVE(pGC); GCOP_UNWRAP(pGC); RL_DEBUG_MSG("fill spans start "); if (nInit <= 0) { pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); } else { DDXPointPtr ppt = pptInit; int *pwidth = pwidthInit; int i = nInit; BoxRec box; box.x1 = ppt->x; box.x2 = box.x1 + *pwidth; box.y2 = box.y1 = ppt->y; while (--i) { ppt++; pwidth++; if (box.x1 > ppt->x) box.x1 = ppt->x; if (box.x2 < (ppt->x + *pwidth)) box.x2 = ppt->x + *pwidth; if (box.y1 > ppt->y) box.y1 = ppt->y; else if (box.y2 < ppt->y) box.y2 = ppt->y; } box.y2++; RootlessStartDrawing((WindowPtr) dst); if (canAccelFill(dst, pGC)) { GC_UNSET_PM(pGC, dst); } pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); } GC_RESTORE(pGC, dst); GCOP_WRAP(pGC); RL_DEBUG_MSG("fill spans end\n"); }
static void RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc, DDXPointPtr pptInit, int *pwidthInit, int nspans, int sorted) { GCOP_UNWRAP(pGC); RL_DEBUG_MSG("set spans start "); if (nspans <= 0) { pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); } else { DDXPointPtr ppt = pptInit; int *pwidth = pwidthInit; int i = nspans; BoxRec box; box.x1 = ppt->x; box.x2 = box.x1 + *pwidth; box.y2 = box.y1 = ppt->y; while (--i) { ppt++; pwidth++; if (box.x1 > ppt->x) box.x1 = ppt->x; if (box.x2 < (ppt->x + *pwidth)) box.x2 = ppt->x + *pwidth; if (box.y1 > ppt->y) box.y1 = ppt->y; else if (box.y2 < ppt->y) box.y2 = ppt->y; } box.y2++; RootlessStartDrawing((WindowPtr) dst); pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); } GCOP_WRAP(pGC); RL_DEBUG_MSG("set spans end\n"); }
/* changed area is *dest* rect */ static RegionPtr RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { RegionPtr result; BoxRec box; GC_SAVE(pGC); GCOP_UNWRAP(pGC); RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)", pSrc, dst); if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) { /* If both source and dest are windows, and we're doing a simple copy operation, we can remove the alpha-protecting planemask (since source has opaque alpha as well) */ if (canAccelBlit(pSrc, pGC)) { GC_UNSET_PM(pGC, dst); } RootlessStartDrawing((WindowPtr) pSrc); } RootlessStartDrawing((WindowPtr) dst); result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty); box.x1 = dstx + dst->x; box.x2 = box.x1 + w; box.y1 = dsty + dst->y; box.y2 = box.y1 + h; TRIM_BOX(box, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); GC_RESTORE(pGC, dst); GCOP_WRAP(pGC); RL_DEBUG_MSG("copy area end\n"); return result; }
static void RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); int x, y; int n; GlyphPtr glyph; WindowPtr srcWin, dstWin; srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? (WindowPtr)pSrc->pDrawable : NULL; dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? (WindowPtr)pDst->pDrawable : NULL; if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); //SCREEN_UNWRAP(ps, Glyphs); ps->Glyphs = SCREENREC(pScreen)->Glyphs; ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); ps->Glyphs = RootlessGlyphs; //SCREEN_WRAP(ps, Glyphs); if (dstWin && IsFramedWindow(dstWin)) { x = xSrc; y = ySrc; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; /* Calling DamageRect for the bounding box of each glyph is inefficient. So compute the union of all glyphs in a list and damage that. */ if (n > 0) { BoxRec box; glyph = *glyphs++; box.x1 = x - glyph->info.x; box.y1 = y - glyph->info.y; box.x2 = box.x1 + glyph->info.width; box.y2 = box.y1 + glyph->info.height; x += glyph->info.xOff; y += glyph->info.yOff; while (--n > 0) { short x1, y1, x2, y2; glyph = *glyphs++; x1 = x - glyph->info.x; y1 = y - glyph->info.y; x2 = x1 + glyph->info.width; y2 = y1 + glyph->info.height; box.x1 = max (box.x1, x1); box.y1 = max (box.y1, y1); box.x2 = max (box.x2, x2); box.y2 = max (box.y2, y2); x += glyph->info.xOff; y += glyph->info.yOff; } RootlessDamageBox(dstWin, &box); } list++; } } }
/* changed area is box around each line */ static void RootlessPolylines(DrawablePtr dst, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { GCOP_UNWRAP(pGC); RL_DEBUG_MSG("poly lines start "); RootlessStartDrawing((WindowPtr) dst); pGC->ops->Polylines(dst, pGC, mode, npt, pptInit); if (npt > 0) { BoxRec box; int extra = pGC->lineWidth >> 1; box.x2 = box.x1 = pptInit->x; box.y2 = box.y1 = pptInit->y; if (npt > 1) { if (pGC->joinStyle == JoinMiter) extra = 6 * pGC->lineWidth; else if (pGC->capStyle == CapProjecting) extra = pGC->lineWidth; } if (mode == CoordModePrevious) { int x = box.x1; int y = box.y1; while (--npt) { pptInit++; x += pptInit->x; y += pptInit->y; if (box.x1 > x) box.x1 = x; else if (box.x2 < x) box.x2 = x; if (box.y1 > y) box.y1 = y; else if (box.y2 < y) box.y2 = y; } } else { while (--npt) { pptInit++; if (box.x1 > pptInit->x) box.x1 = pptInit->x; else if (box.x2 < pptInit->x) box.x2 = pptInit->x; if (box.y1 > pptInit->y) box.y1 = pptInit->y; else if (box.y2 < pptInit->y) box.y2 = pptInit->y; } } box.x2++; box.y2++; if (extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); }
/* changed area is box around all points */ static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { GCOP_UNWRAP(pGC); RL_DEBUG_MSG("polypoint start "); RootlessStartDrawing((WindowPtr) dst); pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit); if (npt > 0) { #if ROOTLESS_CHANGED_AREA==0 // box per point BoxRec box; while (npt) { box.x1 = pptInit->x; box.y1 = pptInit->y; box.x2 = box.x1 + 1; box.y2 = box.y1 + 1; TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); npt--; pptInit++; } #elif ROOTLESS_CHANGED_AREA==1 // one big box BoxRec box; box.x2 = box.x1 = pptInit->x; box.y2 = box.y1 = pptInit->y; while (--npt) { pptInit++; if (box.x1 > pptInit->x) box.x1 = pptInit->x; else if (box.x2 < pptInit->x) box.x2 = pptInit->x; if (box.y1 > pptInit->y) box.y1 = pptInit->y; else if (box.y2 < pptInit->y) box.y2 = pptInit->y; } box.x2++; box.y2++; TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); #elif ROOTLESS_CHANGED_AREA==2 // clever(?) method: accumulate point in 20-pixel radius BoxRec box; int firstx, firsty; box.x2 = box.x1 = firstx = pptInit->x; box.y2 = box.y1 = firsty = pptInit->y; while (--npt) { pptInit++; if (abs(pptInit->x - firstx) > 20 || abs(pptInit->y - firsty) > 20) { box.x2++; box.y2++; TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); box.x2 = box.x1 = firstx = pptInit->x; box.y2 = box.y1 = firsty = pptInit->y; } else { if (box.x1 > pptInit->x) box.x1 = pptInit->x; else if (box.x2 < pptInit->x) box.x2 = pptInit->x; if (box.y1 > pptInit->y) box.y1 = pptInit->y; else if (box.y2 < pptInit->y) box.y2 = pptInit->y; } } box.x2++; box.y2++; TRIM_AND_TRANSLATE_BOX(box, dst, pGC); if (BOX_NOT_EMPTY(box)) RootlessDamageBox((WindowPtr) dst, &box); #endif /* ROOTLESS_CHANGED_AREA */ } GCOP_WRAP(pGC); RL_DEBUG_MSG("polypoint end\n"); }