X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-osx%2Ftrunk%2Flauncher%2Frootless-gc.c;fp=synfig-osx%2Ftrunk%2Flauncher%2Frootless-gc.c;h=0000000000000000000000000000000000000000;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=dea17e9e37cb454c3799acf06e2f01766b03ac94;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-osx/trunk/launcher/rootless-gc.c b/synfig-osx/trunk/launcher/rootless-gc.c deleted file mode 100644 index dea17e9..0000000 --- a/synfig-osx/trunk/launcher/rootless-gc.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* - * Graphics Context support for Mac OS X rootless X server - */ -/* - * Copyright (c) 2001 Greg Parker. All Rights Reserved. - * Copyright (c) 2002 Torrey T. Lyons. All Rights Reserved. - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ -/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessGC.c,v 1.3 2002/07/24 05:58:33 torrey Exp $ */ - -#include "mi.h" -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "dixfontstr.h" -#include "mivalidate.h" -#include "fb.h" - -#include -#include -#include - -#include "rootless-common.h" - - -// GC functions -static void -RootlessValidateGC(GCPtr pGC, unsigned long changes, - DrawablePtr pDrawable); -static void RootlessChangeGC(GCPtr pGC, unsigned long mask); -static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); -static void RootlessDestroyGC(GCPtr pGC); -static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, - int nrects); -static void RootlessDestroyClip(GCPtr pGC); -static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc); - -GCFuncs rootlessGCFuncs = { - RootlessValidateGC, - RootlessChangeGC, - RootlessCopyGC, - RootlessDestroyGC, - RootlessChangeClip, - RootlessDestroyClip, - RootlessCopyClip, -}; - -// GC operations -static void RootlessFillSpans(); -static void RootlessSetSpans(); -static void RootlessPutImage(); -static RegionPtr RootlessCopyArea(); -static RegionPtr RootlessCopyPlane(); -static void RootlessPolyPoint(); -static void RootlessPolylines(); -static void RootlessPolySegment(); -static void RootlessPolyRectangle(); -static void RootlessPolyArc(); -static void RootlessFillPolygon(); -static void RootlessPolyFillRect(); -static void RootlessPolyFillArc(); -static int RootlessPolyText8(); -static int RootlessPolyText16(); -static void RootlessImageText8(); -static void RootlessImageText16(); -static void RootlessImageGlyphBlt(); -static void RootlessPolyGlyphBlt(); -static void RootlessPushPixels(); - -static GCOps rootlessGCOps = { - RootlessFillSpans, - RootlessSetSpans, - RootlessPutImage, - RootlessCopyArea, - RootlessCopyPlane, - RootlessPolyPoint, - RootlessPolylines, - RootlessPolySegment, - RootlessPolyRectangle, - RootlessPolyArc, - RootlessFillPolygon, - RootlessPolyFillRect, - RootlessPolyFillArc, - RootlessPolyText8, - RootlessPolyText16, - RootlessImageText8, - RootlessImageText16, - RootlessImageGlyphBlt, - RootlessPolyGlyphBlt, - RootlessPushPixels -#ifdef NEED_LINEHELPER - , NULL -#endif -}; - - -Bool -RootlessCreateGC(GCPtr pGC) -{ - RootlessGCRec *gcrec; - RootlessScreenRec *s; - Bool result; - - SCREEN_UNWRAP(pGC->pScreen, CreateGC); - s = (RootlessScreenRec *) pGC->pScreen-> - devPrivates[rootlessScreenPrivateIndex].ptr; - result = s->CreateGC(pGC); - gcrec = (RootlessGCRec *) pGC->devPrivates[rootlessGCPrivateIndex].ptr; - gcrec->originalOps = NULL; // don't wrap ops yet - gcrec->originalFuncs = pGC->funcs; - pGC->funcs = &rootlessGCFuncs; - - SCREEN_WRAP(pGC->pScreen, CreateGC); - return result; -} - - -// GC func wrapping -// ValidateGC wraps gcOps iff dest is viewable. All others just unwrap&call. - -// GCFUN_UNRAP assumes funcs have been wrapped and -// does not assume ops have been wrapped -#define GCFUNC_UNWRAP(pGC) \ - RootlessGCRec *gcrec = (RootlessGCRec *) \ - (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \ - (pGC)->funcs = gcrec->originalFuncs; \ - if (gcrec->originalOps) { \ - (pGC)->ops = gcrec->originalOps; \ -} - -#define GCFUNC_WRAP(pGC) \ - gcrec->originalFuncs = (pGC)->funcs; \ - (pGC)->funcs = &rootlessGCFuncs; \ - if (gcrec->originalOps) { \ - gcrec->originalOps = (pGC)->ops; \ - (pGC)->ops = &rootlessGCOps; \ -} - -/* Turn drawing on the root into a no-op */ -#define GC_IS_ROOT(pDst) ((pDst)->type == DRAWABLE_WINDOW \ - && IsRoot ((WindowPtr) (pDst)) \ - && WINREC ((WindowPtr) (pDst)) == NULL) - -#define GC_SKIP_ROOT(pDst) \ - do { \ - if (GC_IS_ROOT (pDst)) \ - return; \ - } while (0) - -/* Our main problem when drawing is that we have to make sure that - the alpha channel of the windows we're drawing in is always opaque. - - fb makes this harder than it would otherwise be by noticing that a - planemask of 0x00ffffff includes all bits when depth=24, and so - "optimizes" the pm to 0xffffffff. We work around that by temporarily - setting depth=bpp while changing the GC. - - Anyway, so the normal situation (in 32 bit mode) is that the - planemask is 0x00ffffff and thus fb leaves the alpha channel alone - (and it's opaque initially, so things work out). - - But there's a problem with drawing with a planemask that doesn't - have all bits set - it normally causes fb to fall off its fastest - paths when blitting and filling. - - So my solution to that is to try to recognize when we can relax the - planemask back to ~0, and do that for the duration of the drawing - operation, setting the alpha channel in fg/bg pixels to opaque at - the same time. We can do this when drawing op is GXcopy. We can also - do it when copying from another window (since its alpha channel must - also be opaque). - - Note that even when we can't set planemask to all ones, fbBlt may - still choose altivec'd code if it's GXcopy and a forwards copy. This - is mainly intended for copying from pixmaps to windows. The copy - operation used sets alpha to opaque. - - The three macros below are used to implement this, drawing ops look - something like this: - - OP { - GC_SAVE (gc); - GCFUNC_UNWRAP (gc); - - ... - - if (can_accel_xxx (..) && otherwise-suitable) - GC_UNSET_PM (gc, dst); - - gc->funcs->OP (gc, ...); - - GC_RESTORE (gc, dst); - GCFUNC_WRAP (gc); - } - - */ - -#define GC_SAVE(pGC) \ - unsigned long _save_fg = (pGC)->fgPixel; \ - unsigned long _save_bg = (pGC)->bgPixel; \ - unsigned long _save_pm = (pGC)->planemask; \ - Bool _changed = FALSE - -#define GC_RESTORE(pGC, pDraw) \ - do { \ - if (_changed) { \ - unsigned int depth = (pDraw)->depth; \ - (pGC)->fgPixel = _save_fg; \ - (pGC)->bgPixel = _save_bg; \ - (pGC)->planemask = _save_pm; \ - (pDraw)->depth = (pDraw)->bitsPerPixel; \ - validate_gc (pGC, GCForeground | GCBackground \ - | GCPlaneMask, pDraw); \ - (pDraw)->depth = depth; \ - } \ - } while (0) - -#define GC_UNSET_PM(pGC, pDraw) \ - do { \ - unsigned int mask = RootlessAlphaMask ((pDraw)->bitsPerPixel); \ - if (((pGC)->planemask & mask) != mask) { \ - unsigned int depth = (pDraw)->depth; \ - (pGC)->fgPixel |= mask; \ - (pGC)->bgPixel |= mask; \ - (pGC)->planemask |= mask; \ - (pDraw)->depth = (pDraw)->bitsPerPixel; \ - validate_gc (pGC, GCForeground \ - | GCBackground | GCPlaneMask, pDraw); \ - (pDraw)->depth = depth; \ - _changed = TRUE; \ - } \ - } while (0) - -static void -validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) -{ - RootlessGCRec *gcrec = (RootlessGCRec *) - (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; - - pGC->funcs->ValidateGC(pGC, changes, pDrawable); - - if (((WindowPtr) pDrawable)->viewable) - { - gcrec->originalOps = pGC->ops; - } -} - -static RootlessWindowRec * -can_accel_blit (DrawablePtr pDraw, GCPtr pGC) -{ - WindowPtr pTop; - RootlessWindowRec *winRec; - unsigned int pm; - - if (pGC->alu != GXcopy) - return NULL; - - if (pDraw->type != DRAWABLE_WINDOW) - return NULL; - - pm = ~RootlessAlphaMask (pDraw->bitsPerPixel); - if ((pGC->planemask & pm) != pm) - return NULL; - - pTop = TopLevelParent ((WindowPtr) pDraw); - if (pTop == NULL) - return NULL; - - winRec = WINREC(pTop); - if (winRec == NULL) - return NULL; - - return winRec; -} - -static inline RootlessWindowRec * -can_accel_fill (DrawablePtr pDraw, GCPtr pGC) -{ - if (pGC->fillStyle != FillSolid) - return NULL; - - return can_accel_blit (pDraw, pGC); -} - -static unsigned int -box_bytes (DrawablePtr pDraw, BoxRec *box) -{ - unsigned int pixels; - - pixels = (box->x2 - box->x1) * (box->y2 - box->y1); - - return pixels * (pDraw->bitsPerPixel >> 3); -} - -static void -RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) -{ - GCFUNC_UNWRAP(pGC); - - gcrec->originalOps = NULL; - - if (pDrawable->type == DRAWABLE_WINDOW) - { - /* Prevent fb relaxing planemask by telling it we use all - bits temporarily. */ - - unsigned int depth = pDrawable->depth; - pDrawable->depth = pDrawable->bitsPerPixel; - pGC->planemask &= ~RootlessAlphaMask (pDrawable->bitsPerPixel); - validate_gc (pGC, changes | GCPlaneMask, pDrawable); - pDrawable->depth = depth; - } - else - pGC->funcs->ValidateGC(pGC, changes, pDrawable); - - GCFUNC_WRAP(pGC); -} - -static void RootlessChangeGC(GCPtr pGC, unsigned long mask) -{ - GCFUNC_UNWRAP(pGC); - pGC->funcs->ChangeGC(pGC, mask); - GCFUNC_WRAP(pGC); -} - -static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) -{ - GCFUNC_UNWRAP(pGCDst); - pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst); - GCFUNC_WRAP(pGCDst); -} - -static void RootlessDestroyGC(GCPtr pGC) -{ - GCFUNC_UNWRAP(pGC); - pGC->funcs->DestroyGC(pGC); - GCFUNC_WRAP(pGC); -} - -static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) -{ - GCFUNC_UNWRAP(pGC); - pGC->funcs->ChangeClip(pGC, type, pvalue, nrects); - GCFUNC_WRAP(pGC); -} - -static void RootlessDestroyClip(GCPtr pGC) -{ - GCFUNC_UNWRAP(pGC); - pGC->funcs->DestroyClip(pGC); - GCFUNC_WRAP(pGC); -} - -static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - GCFUNC_UNWRAP(pgcDst); - pgcDst->funcs->CopyClip(pgcDst, pgcSrc); - GCFUNC_WRAP(pgcDst); -} - - -// GC ops -// We can't use shadowfb because shadowfb assumes one pixmap -// and our root window is a special case. -// So much of this code is copied from shadowfb. - -// assumes both funcs and ops are wrapped -#define GCOP_UNWRAP(pGC) \ - RootlessGCRec *gcrec = (RootlessGCRec *) \ - (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \ - GCFuncs *saveFuncs = pGC->funcs; \ - (pGC)->funcs = gcrec->originalFuncs; \ - (pGC)->ops = gcrec->originalOps; - -#define GCOP_WRAP(pGC) \ - gcrec->originalOps = (pGC)->ops; \ - (pGC)->funcs = saveFuncs; \ - (pGC)->ops = &rootlessGCOps; - - -static void -RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, - DDXPointPtr pptInit, int *pwidthInit, int sorted) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("fill spans start\n"); - - 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++; - pwidthInit++; - 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 (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - 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); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - - 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) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("set spans start\n"); - - 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); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - GCOP_WRAP(pGC); - RL_DEBUG_MSG("set spans end\n"); -} - -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; - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("put image start\n"); - - 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); - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("put image 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); - Bool src_drawing = FALSE; - - if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc)) - return NULL; /* nothing exposed */ - - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)\n", pSrc, dst); - - if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) - { - unsigned int bytes; - - /* 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) */ - - bytes = w * h * (pSrc->depth >> 3); - - if (bytes >= xp_copy_bytes_threshold && can_accel_blit (pSrc, pGC)) - { - GC_UNSET_PM (pGC, dst); - } - - RootlessStartDrawing((WindowPtr) pSrc); - src_drawing = TRUE; - } - 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); - - RootlessFinishedDrawing ((WindowPtr) dst); - if (src_drawing) - RootlessFinishedDrawing ((WindowPtr) pSrc); - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("copy area end\n"); - return result; -} - -/* 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; - Bool src_drawing = FALSE; - - if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc)) - return NULL; /* nothing exposed */ - - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("copy plane start\n"); - - if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) { - RootlessStartDrawing((WindowPtr) pSrc); - src_drawing = TRUE; - } - 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); - - RootlessFinishedDrawing ((WindowPtr) dst); - if (src_drawing) - RootlessFinishedDrawing ((WindowPtr) pSrc); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("copy plane end\n"); - return result; -} - -// Options for size of changed area: -// 0 = box per point -// 1 = big box around all points -// 2 = accumulate point in 20 pixel radius -#define ROOTLESS_CHANGED_AREA 1 -#define abs(a) ((a) > 0 ? (a) : -(a)) - -/* changed area is box around all points */ -static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("polypoint start\n"); - - 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 */ - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("polypoint end\n"); -} - -#undef ROOTLESS_CHANGED_AREA - -/* changed area is box around each line */ -static void RootlessPolylines(DrawablePtr dst, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("poly lines start\n"); - - 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); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("poly lines end\n"); -} - -/* changed area is box around each line segment */ -static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC, - int nseg, xSegment *pSeg) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("poly segment start (win 0x%x)\n", dst); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->PolySegment(dst, pGC, nseg, pSeg); - - if (nseg > 0) { - BoxRec box; - int extra = pGC->lineWidth; - - if(pGC->capStyle != CapProjecting) - extra >>= 1; - - if(pSeg->x2 > pSeg->x1) { - box.x1 = pSeg->x1; - box.x2 = pSeg->x2; - } else { - box.x2 = pSeg->x1; - box.x1 = pSeg->x2; - } - - if(pSeg->y2 > pSeg->y1) { - box.y1 = pSeg->y1; - box.y2 = pSeg->y2; - } else { - box.y2 = pSeg->y1; - box.y1 = pSeg->y2; - } - - while(--nseg) { - pSeg++; - if(pSeg->x2 > pSeg->x1) { - if(pSeg->x1 < box.x1) box.x1 = pSeg->x1; - if(pSeg->x2 > box.x2) box.x2 = pSeg->x2; - } else { - if(pSeg->x2 < box.x1) box.x1 = pSeg->x2; - if(pSeg->x1 > box.x2) box.x2 = pSeg->x1; - } - if(pSeg->y2 > pSeg->y1) { - if(pSeg->y1 < box.y1) box.y1 = pSeg->y1; - if(pSeg->y2 > box.y2) box.y2 = pSeg->y2; - } else { - if(pSeg->y2 < box.y1) box.y1 = pSeg->y2; - if(pSeg->y1 > box.y2) box.y2 = pSeg->y1; - } - } - - 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); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("poly segment end\n"); -} - -/* changed area is box around each line (not entire rects) */ -static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC, - int nRects, xRectangle *pRects) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("poly rectangle start\n"); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->PolyRectangle(dst, pGC, nRects, pRects); - - if (nRects > 0) { - BoxRec box; - int offset1, offset2, offset3; - - offset2 = pGC->lineWidth; - if(!offset2) offset2 = 1; - offset1 = offset2 >> 1; - offset3 = offset2 - offset1; - - while(nRects--) { - box.x1 = pRects->x - offset1; - box.y1 = pRects->y - offset1; - box.x2 = box.x1 + pRects->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - box.x1 = pRects->x - offset1; - box.y1 = pRects->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - box.x1 = pRects->x + pRects->width - offset1; - box.y1 = pRects->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - box.x1 = pRects->x - offset1; - box.y1 = pRects->y + pRects->height - offset1; - box.x2 = box.x1 + pRects->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - pRects++; - } - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("poly rectangle end\n"); -} - - -/* changed area is box around each arc (assumes all arcs are 360 degrees) */ -static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("poly arc start\n"); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->PolyArc(dst, pGC, narcs, parcs); - - if (narcs > 0) { - int extra = pGC->lineWidth >> 1; - BoxRec box; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - while(--narcs) { - parcs++; - if(box.x1 > parcs->x) - box.x1 = parcs->x; - if(box.x2 < (parcs->x + parcs->width)) - box.x2 = parcs->x + parcs->width; - if(box.y1 > parcs->y) - box.y1 = parcs->y; - if(box.y2 < (parcs->y + parcs->height)) - box.y2 = parcs->y + parcs->height; - } - - if(extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("poly arc end\n"); -} - - -/* changed area is box around each poly */ -static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC, - int shape, int mode, int count, - DDXPointPtr pptInit) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("fill poly start (win 0x%x, fillStyle 0x%x)\n", dst, - pGC->fillStyle); - - if (count <= 2) { - pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); - } else { - DDXPointPtr ppt = pptInit; - int i = count; - BoxRec box; - - box.x2 = box.x1 = ppt->x; - box.y2 = box.y1 = ppt->y; - - if(mode != CoordModeOrigin) { - int x = box.x1; - int y = box.y1; - - while(--i) { - ppt++; - x += ppt->x; - y += ppt->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(--i) { - ppt++; - if(box.x1 > ppt->x) - box.x1 = ppt->x; - else if(box.x2 < ppt->x) - box.x2 = ppt->x; - if(box.y1 > ppt->y) - box.y1 = ppt->y; - else if(box.y2 < ppt->y) - box.y2 = ppt->y; - } - } - - box.x2++; - box.y2++; - - RootlessStartDrawing((WindowPtr) dst); - - if (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - GC_UNSET_PM (pGC, dst); - } - - pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); - - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("fill poly end\n"); -} - -/* changed area is the rects */ -static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC, - int nRectsInit, xRectangle *pRectsInit) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("fill rect start (win 0x%x, fillStyle 0x%x)\n", dst, - pGC->fillStyle); - - if (nRectsInit <= 0) { - pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit); - } else { - BoxRec box; - xRectangle *pRects = pRectsInit; - int nRects = nRectsInit; - - box.x1 = pRects->x; - box.x2 = box.x1 + pRects->width; - box.y1 = pRects->y; - box.y2 = box.y1 + pRects->height; - - while(--nRects) { - pRects++; - if(box.x1 > pRects->x) - box.x1 = pRects->x; - if(box.x2 < (pRects->x + pRects->width)) - box.x2 = pRects->x + pRects->width; - if(box.y1 > pRects->y) - box.y1 = pRects->y; - if(box.y2 < (pRects->y + pRects->height)) - box.y2 = pRects->y + pRects->height; - } - - /* cfb messes with the pRectsInit so we have to do our - calculations first */ - - RootlessStartDrawing((WindowPtr) dst); - - if (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - GC_UNSET_PM (pGC, dst); - } - - pGC->ops->PolyFillRect (dst, pGC, nRectsInit, pRectsInit); - - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("fill rect end\n"); -} - - -/* changed area is box around each arc (assuming arcs are all 360 degrees) */ -static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC, - int narcs, xArc *parcs) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("fill arc start\n"); - - if (narcs > 0) { - BoxRec box; - int i; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - for (i = 0; i < narcs; i++) - { - if(box.x1 > parcs[i].x) - box.x1 = parcs[i].x; - if(box.x2 < (parcs[i].x + parcs[i].width)) - box.x2 = parcs[i].x + parcs[i].width; - if(box.y1 > parcs[i].y) - box.y1 = parcs[i].y; - if(box.y2 < (parcs[i].y + parcs[i].height)) - box.y2 = parcs[i].y + parcs[i].height; - } - - RootlessStartDrawing((WindowPtr) dst); - - if (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - GC_UNSET_PM (pGC, dst); - } - - pGC->ops->PolyFillArc(dst, pGC, narcs, parcs); - - TRIM_AND_TRANSLATE_BOX(box, dst, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - else - pGC->ops->PolyFillArc(dst, pGC, narcs, parcs); - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("fill arc end\n"); -} - - -static void RootlessImageText8(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, char *chars) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("imagetext8 start\n"); - - RootlessStartDrawing((WindowPtr) dst); - - if (count > 0) { - int top, bot, Min, Max; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if(Min > 0) Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if(Max < 0) Max = 0; - - /* ugh */ - box.x1 = dst->x + x + Min + - FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = dst->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = dst->y + y - top; - box.y2 = dst->y + y + bot; - - if (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - GC_UNSET_PM (pGC, dst); - } - - pGC->ops->ImageText8(dst, pGC, x, y, count, chars); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - else - pGC->ops->ImageText8(dst, pGC, x, y, count, chars); - - RootlessFinishedDrawing ((WindowPtr) dst); - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("imagetext8 end\n"); -} - -static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, char *chars) -{ - int width; // the result, sorta - - if (GC_IS_ROOT (dst)) - return 0; /* FIXME: ok? */ - - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("polytext8 start\n"); - - RootlessStartDrawing((WindowPtr) dst); - width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars); - width -= x; - - if(width > 0) { - BoxRec box; - - /* ugh */ - box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); - - if(count > 1) { - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("polytext8 end\n"); - return (width + x); -} - -static void RootlessImageText16(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, unsigned short *chars) -{ - GC_SAVE (pGC); - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("imagetext16 start\n"); - - if (count > 0) { - int top, bot, Min, Max; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if(Min > 0) Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if(Max < 0) Max = 0; - - /* ugh */ - box.x1 = dst->x + x + Min + - FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = dst->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = dst->y + y - top; - box.y2 = dst->y + y + bot; - - RootlessStartDrawing((WindowPtr) dst); - - if (can_accel_fill (dst, pGC) - && box_bytes (dst, &box) >= xp_fill_bytes_threshold) - { - GC_UNSET_PM (pGC, dst); - } - - pGC->ops->ImageText16(dst, pGC, x, y, count, chars); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - RootlessFinishedDrawing ((WindowPtr) dst); - } - else - pGC->ops->ImageText16(dst, pGC, x, y, count, chars); - - GC_RESTORE (pGC, dst); - GCOP_WRAP(pGC); - RL_DEBUG_MSG("imagetext16 end\n"); -} - -static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, unsigned short *chars) -{ - int width; // the result, sorta - - if (GC_IS_ROOT (dst)) - return 0; /* FIXME: ok? */ - - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("polytext16 start\n"); - - RootlessStartDrawing((WindowPtr) dst); - width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars); - width -= x; - - if (width > 0) { - BoxRec box; - - /* ugh */ - box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); - - if(count > 1) { - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("polytext16 end\n"); - return width + x; -} - -static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer unused) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("imageglyph start\n"); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyph, ppci, unused); - - if (nglyph > 0) { - int top, bot, width = 0; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - box.x1 = ppci[0]->metrics.leftSideBearing; - if(box.x1 > 0) box.x1 = 0; - box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing - - ppci[nglyph - 1]->metrics.characterWidth; - if(box.x2 < 0) box.x2 = 0; - - box.x2 += dst->x + x; - box.x1 += dst->x + x; - - while(nglyph--) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if(width > 0) - box.x2 += width; - else - box.x1 += width; - - box.y1 = dst->y + y - top; - box.y2 = dst->y + y + bot; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("imageglyph end\n"); -} - -static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("polyglyph start\n"); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase); - - if (nglyph > 0) { - BoxRec box; - - /* ugh */ - box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing; - box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing; - - if(nglyph > 1) { - int width = 0; - - while(--nglyph) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - } - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("polyglyph end\n"); -} - - -/* changed area is in dest */ -static void -RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst, - int dx, int dy, int xOrg, int yOrg) -{ - BoxRec box; - - GC_SKIP_ROOT (dst); - GCOP_UNWRAP(pGC); - RL_DEBUG_MSG("push pixels start\n"); - - RootlessStartDrawing((WindowPtr) dst); - pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg); - - box.x1 = xOrg + dst->x; - box.x2 = box.x1 + dx; - box.y1 = yOrg + dst->y; - box.y2 = box.y1 + dy; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - RootlessDamageBox ((WindowPtr) dst, &box); - - RootlessFinishedDrawing ((WindowPtr) dst); - - GCOP_WRAP(pGC); - RL_DEBUG_MSG("push pixels end\n"); -}