Bool fbGlyphIn (RegionPtr pRegion, int x, int y, int width, int height) { BoxRec box; BoxPtr pExtents = REGION_EXTENTS (dummyScreen, pRegion); /* * Check extents by hand to avoid 16 bit overflows */ if (x < (int) pExtents->x1) return FALSE; if ((int) pExtents->x2 < x + width) return FALSE; if (y < (int) pExtents->y1) return FALSE; if ((int) pExtents->y2 < y + height) return FALSE; box.x1 = x; box.x2 = x + width; box.y1 = y; box.y2 = y + height; return RECT_IN_REGION (dummyScreen, pRegion, &box) == rgnIN; }
void CreatorPolyFillArcSolid (DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { RegionPtr cclip; xArc *arc; BoxRec box; int i, x2, y2; FFBLOG(("CreatorPolyFillArcSolid: narcs(%d)\n", narcs)); cclip = cfbGetCompositeClip(pGC); for(arc = parcs, i = narcs; --i >= 0; arc++) { if(miFillArcEmpty(arc)) continue; if(miCanFillArc(arc)) { box.x1 = arc->x + pDrawable->x; box.y1 = arc->y + pDrawable->y; box.x2 = x2 = box.x1 + (int)arc->width + 1; box.y2 = y2 = box.y1 + (int)arc->height + 1; if((x2 & ~0x7ff) == 0 && (y2 & ~0x7ff) == 0 && (RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN)) { if(arc->angle2 >= FULLCIRCLE || arc->angle2 <= -FULLCIRCLE) CreatorFillEllipseSolid(pDrawable, pGC, arc); else CreatorFillArcSliceSolid(pDrawable, pGC, arc); continue; } } /* Use slow mi code if we can't handle it simply. */ miPolyFillArc(pDrawable, pGC, 1, arc); } }
static void update_screen(struct omap_screen_info *omaps) { BoxPtr tmp; int i; if (region_is_null(omaps)) return; if (!omaps->block_updates) { /* Remove the video region from our active area. */ if (omaps->video_region && REGION_NOTEMPTY(omaps->screen->pScreen, omaps->video_region) && RECT_IN_REGION(omaps->screen->pScreen, omaps->video_region, &omaps->dirty_area)) { REGION_INIT(omaps->screen->pScreen, omaps->tmp_region, &omaps->dirty_area, 1); REGION_SUBTRACT(omaps->screen->pScreen, omaps->tmp_region, omaps->tmp_region, omaps->video_region); tmp = REGION_RECTS(omaps->tmp_region); for (i = 0; i < REGION_NUM_RECTS(omaps->tmp_region); i++, tmp++) push_box(omaps, tmp); REGION_EMPTY(omaps->screen->pScreen, omaps->tmp_region); } else { push_box(omaps, &omaps->dirty_area); } } reset_damage(omaps); }
/* * Compute the visibility of a shaped window */ int RootlessShapedWindowIn (ScreenPtr pScreen, RegionPtr universe, RegionPtr bounding, BoxPtr rect, int x, int y) { BoxRec box; register BoxPtr boundBox; int nbox; Bool someIn, someOut; register int t, x1, y1, x2, y2; nbox = REGION_NUM_RECTS (bounding); boundBox = REGION_RECTS (bounding); someIn = someOut = FALSE; x1 = rect->x1; y1 = rect->y1; x2 = rect->x2; y2 = rect->y2; while (nbox--) { if ((t = boundBox->x1 + x) < x1) t = x1; box.x1 = t; if ((t = boundBox->y1 + y) < y1) t = y1; box.y1 = t; if ((t = boundBox->x2 + x) > x2) t = x2; box.x2 = t; if ((t = boundBox->y2 + y) > y2) t = y2; box.y2 = t; if (box.x1 > box.x2) box.x2 = box.x1; if (box.y1 > box.y2) box.y2 = box.y1; switch (RECT_IN_REGION(pScreen, universe, &box)) { case rgnIN: if (someOut) return rgnPART; someIn = TRUE; break; case rgnOUT: if (someIn) return rgnPART; someOut = TRUE; break; default: return rgnPART; } boundBox++; } if (someIn) return rgnIN; return rgnOUT; }
static void miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) { ScreenPtr pScreen = closure; miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; if (pScreenPriv->isUp && RECT_IN_REGION (pScreen, pRegion, &pScreenPriv->saved) != rgnOUT) { SPRITE_DEBUG(("Damage remove\n")); miSpriteRemoveCursor (pScreen); } }
Bool miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) { BoxPtr box; WindowPtr pChild, pLast; Bool anyMarked = FALSE; MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; ScreenPtr pScreen; pScreen = pWin->drawable.pScreen; /* single layered systems are easy */ if (ppLayerWin) *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight * overkill if there are mapped windows that outside pWin's border, * but it's better than wasting time on RectIn checks. */ pChild = pWin; while (1) { if (pChild->viewable) { if (REGION_BROKEN (pScreen, &pChild->winSize)) SetWinSize (pChild); if (REGION_BROKEN (pScreen, &pChild->borderSize)) SetBorderSize (pChild); (* MarkWindow)(pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } anyMarked = TRUE; pFirst = pFirst->nextSib; } if ( (pChild = pFirst) ) { box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize); pLast = pChild->parent->lastChild; while (1) { if (pChild->viewable) { if (REGION_BROKEN (pScreen, &pChild->winSize)) SetWinSize (pChild); if (REGION_BROKEN (pScreen, &pChild->borderSize)) SetBorderSize (pChild); if (RECT_IN_REGION(pScreen, &pChild->borderSize, box)) { (* MarkWindow)(pChild); anyMarked = TRUE; if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } } while (!pChild->nextSib && (pChild != pLast)) pChild = pChild->parent; if (pChild == pLast) break; pChild = pChild->nextSib; } } if (anyMarked) (* MarkWindow)(pWin->parent); return anyMarked; }
void CreatorFillPolygon (DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr ppt) { WindowPtr pWin = (WindowPtr) pDrawable; CreatorPrivGCPtr gcPriv = CreatorGetGCPrivate (pGC); FFBPtr pFfb = GET_FFB_FROM_SCREEN (pGC->pScreen); ffb_fbcPtr ffb = pFfb->regs; BoxRec box; int lx, rx, ty, by; int t, b, i, j, k, l, tt; int xy[12] FFB_ALIGN64; int xOrg, yOrg; FFBLOG(("CreatorFillPolygon: ALU(%x) PMSK(%08x) shape(%d) mode(%d) count(%d)\n", pGC->alu, pGC->planemask, shape, mode, count)); if (count < 3) return; if (shape != Convex && count > 3) { miFillPolygon (pDrawable, pGC, shape, mode, count, ppt); return; } xOrg = pDrawable->x; yOrg = pDrawable->y; ppt->x += xOrg; ppt->y += yOrg; lx = ppt->x; rx = ppt->x; ty = ppt->y; by = ppt->y; t = b = 0; tt = 1; for (i = 1; i < count; i++) { if (mode == CoordModeOrigin) { ppt[i].x += xOrg; ppt[i].y += yOrg; } else { ppt[i].x += ppt[i-1].x; ppt[i].y += ppt[i-1].y; } if (ppt[i].x < lx) lx = ppt[i].x; if (ppt[i].x > rx) rx = ppt[i].x; if (ppt[i].y < ty) { ty = ppt[i].y; t = i; tt = 1; } else if (ppt[i].y == ty) tt++; if (ppt[i].y > by) { by = ppt[i].y; b = i; } } if (tt > 2) { miFillConvexPoly(pDrawable, pGC, count, ppt); return; } else if (tt == 2) { i = t - 1; if (i < 0) i = count - 1; if (ppt[i].y == ppt[t].y) t = i; } box.x1 = lx; box.x2 = rx + 1; box.y1 = ty; box.y2 = by + 1; switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &box)) { case rgnPART: miFillConvexPoly(pDrawable, pGC, count, ppt); case rgnOUT: return; } if(gcPriv->stipple == NULL) { FFB_ATTR_GC(pFfb, pGC, pWin, FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST, FFB_DRAWOP_POLYGON); } else { unsigned int fbc; FFBSetStipple(pFfb, ffb, gcPriv->stipple, FFB_PPC_CS_CONST, FFB_PPC_CS_MASK); FFB_WRITE_PMASK(pFfb, ffb, pGC->planemask); FFB_WRITE_DRAWOP(pFfb, ffb, FFB_DRAWOP_POLYGON); fbc = FFB_FBC_WIN(pWin); fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_OFF; FFB_WRITE_FBC(pFfb, ffb, fbc); } xy[0] = ppt[t].y; xy[1] = ppt[t].x; j = t + 1; if (j == count) j = 0; xy[2] = ppt[j].y; xy[3] = ppt[j].x; j = t + 2; if (j >= count) j -= count; for (i = 2 * count - 4; i; i -= k) { b = 2; for (k = 0; k < i && k < 8; k+=2) { xy[4 + k] = ppt[j].y; xy[4 + k + 1] = ppt[j].x; if (xy[4 + k] > xy[b]) b = 4 + k; j++; if (j == count) j = 0; } FFBFifo(pFfb, 4 + k); for (l = 0; l < b - 2; l+=2) FFB_WRITE64P(&ffb->by, &xy[l]); FFB_WRITE64P(&ffb->bh, &xy[l]); for (l+=2; l <= k; l+=2) FFB_WRITE64P(&ffb->by, &xy[l]); FFB_WRITE64P(&ffb->ebyi, &xy[l]); xy[2] = xy[l]; xy[3] = xy[l+1]; } pFfb->rp_active = 1; FFBSync(pFfb, ffb); }
void fbPolyArc (DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { FbArc arc; if (pGC->lineWidth == 0) { #ifndef FBNOPIXADDR arc = 0; if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) { switch (pDrawable->bitsPerPixel) { case 8: arc = fbArc8; break; case 16: arc = fbArc16; break; #ifdef FB_24BIT case 24: arc = fbArc24; break; #endif case 32: arc = fbArc32; break; } } if (arc) { FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; BoxRec box; int x2, y2; RegionPtr cclip; cclip = fbGetCompositeClip (pGC); fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (narcs--) { if (miCanZeroArc (parcs)) { box.x1 = parcs->x + pDrawable->x; box.y1 = parcs->y + pDrawable->y; /* * Because box.x2 and box.y2 get truncated to 16 bits, and the * RECT_IN_REGION test treats the resulting number as a signed * integer, the RECT_IN_REGION test alone can go the wrong way. * This can result in a server crash because the rendering * routines in this file deal directly with cpu addresses * of pixels to be stored, and do not clip or otherwise check * that all such addresses are within their respective pixmaps. * So we only allow the RECT_IN_REGION test to be used for * values that can be expressed correctly in a signed short. */ x2 = box.x1 + (int)parcs->width + 1; box.x2 = x2; y2 = box.y1 + (int)parcs->height + 1; box.y2 = y2; if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && (RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) ) (*arc) (dst, dstStride, dstBpp, parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, pPriv->and, pPriv->xor); else miZeroPolyArc(pDrawable, pGC, 1, parcs); } else miPolyArc(pDrawable, pGC, 1, parcs); parcs++; } } else #endif miZeroPolyArc (pDrawable, pGC, narcs, parcs); } else miPolyArc (pDrawable, pGC, narcs, parcs); }
Bool xglSyncBits (DrawablePtr pDrawable, BoxPtr pExtents) { RegionRec region; BoxRec box; XGL_DRAWABLE_PIXMAP (pDrawable); XGL_PIXMAP_PRIV (pPixmap); if (pPixmapPriv->allBits) return xglMapPixmapBits (pPixmap); if (pPixmapPriv->target == xglPixmapTargetIn && pExtents) { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; if (pExtents->x1 > box.x1) box.x1 = pExtents->x1; if (pExtents->y1 > box.y1) box.y1 = pExtents->y1; if (pExtents->x2 < box.x2) box.x2 = pExtents->x2; if (pExtents->y2 < box.y2) box.y2 = pExtents->y2; if (box.x2 <= box.x1 || box.y2 <= box.y1) return xglMapPixmapBits (pPixmap); if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion)) { switch (RECT_IN_REGION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box)) { case rgnIN: REGION_INIT (pDrawable->pScreen, ®ion, NullBox, 0); break; case rgnOUT: REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_UNION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion, ®ion); break; case rgnPART: REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, ®ion, ®ion, &pPixmapPriv->bitRegion); REGION_UNION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion, ®ion); break; } } else { REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, &pPixmapPriv->bitRegion, ®ion, &pPixmapPriv->bitRegion); } if (REGION_NUM_RECTS (&pPixmapPriv->bitRegion) == 1) { BoxPtr pBox; pBox = REGION_RECTS (&pPixmapPriv->bitRegion); if (pBox->x1 <= 0 && pBox->y1 <= 0 && pBox->x2 >= pPixmap->drawable.width && pBox->y2 >= pPixmap->drawable.height) pPixmapPriv->allBits = TRUE; } } else { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, ®ion, ®ion, &pPixmapPriv->bitRegion); pPixmapPriv->allBits = TRUE; } if (!pPixmapPriv->buffer) if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT)) return FALSE; if (REGION_NOTEMPTY (pDrawable->pScreen, ®ion) && pPixmapPriv->surface) { glitz_pixel_format_t format; BoxPtr pBox; BoxPtr pExt; int nBox; if (!xglSyncSurface (pDrawable)) FatalError (XGL_SW_FAILURE_STRING); xglUnmapPixmapBits (pPixmap); pBox = REGION_RECTS (®ion); nBox = REGION_NUM_RECTS (®ion); pExt = REGION_EXTENTS (pDrawable->pScreen, ®ion); format.fourcc = GLITZ_FOURCC_RGB; format.masks = pPixmapPriv->pVisual->pPixel->masks; format.xoffset = pExt->x1; if (pPixmapPriv->stride < 0) { format.skip_lines = pPixmap->drawable.height - pExt->y2; format.bytes_per_line = -pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; } else { format.skip_lines = pExt->y1; format.bytes_per_line = pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; } glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, (glitz_box_t *) pBox, nBox); glitz_get_pixels (pPixmapPriv->surface, pExt->x1, pExt->y1, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &format, pPixmapPriv->buffer); glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, NULL, 0); } REGION_UNINIT (pDrawable->pScreen, ®ion); if (pPixmapPriv->allBits) { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion); REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box, 1); } return xglMapPixmapBits (pPixmap); }
void LeoPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pGlyphBase) { LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; RegionPtr clip; CharInfoPtr pci; int w, h, x0, y0, i; unsigned int *bits; BoxRec box; int curw = -1; unsigned int *fbf; unsigned char *fb; int height, width; clip = cfbGetCompositeClip(pGC); /* compute an approximate (but covering) bounding box */ box.x1 = 0; if (ppci[0]->metrics.leftSideBearing < 0) box.x1 = ppci[0]->metrics.leftSideBearing; h = nglyph - 1; w = ppci[h]->metrics.rightSideBearing; while (--h >= 0) w += ppci[h]->metrics.characterWidth; box.x2 = w; box.y1 = -FONTMAXBOUNDS(pGC->font,ascent); box.y2 = FONTMAXBOUNDS(pGC->font,descent); box.x1 += pDrawable->x + x; box.x2 += pDrawable->x + x; box.y1 += pDrawable->y + y; box.y2 += pDrawable->y + y; switch (RECT_IN_REGION(pGC->pScreen, clip, &box)) { case rgnPART: if (REGION_NUM_RECTS(clip) == 1) { ld0->vclipmin = (clip->extents.y1 << 16) | clip->extents.x1; ld0->vclipmax = ((clip->extents.y2 - 1) << 16) | (clip->extents.x2 - 1); break; } cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pGlyphBase); case rgnOUT: return; default: clip = NULL; break; } x += pDrawable->x; y += pDrawable->y; lc0->fontt = 1; lc0->addrspace = LEO_ADDRSPC_FONT_OBGR; ld0->fg = pGC->fgPixel; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; height = pLeo->height; width = pLeo->width; fb = (unsigned char *)pLeo->fb; while (nglyph--) { pci = *ppci++; w = GLYPHWIDTHPIXELS (pci); h = GLYPHHEIGHTPIXELS (pci); if (!w || !h) goto next_glyph; x0 = x + pci->metrics.leftSideBearing; y0 = y - pci->metrics.ascent; /* We're off the screen to the left, making our way * back onto the screen. */ if((x0 >> 31) == -1) goto next_glyph; /* We walked off the screen (to the right or downwards) * or we started there, we're never going to work our * way back so stop now. */ if(x0 >= width || y0 >= height) break; bits = (unsigned int *) pci->bits; if (w != curw) { curw = w; if (w) lc0->fontmsk = 0xffffffff << (32 - w); else lc0->fontmsk = 0; } fbf = (unsigned *)(fb + (y0 << 13) + (x0 << 2)); if (y0 + h <= height) for (i = 0; i < h; i++) { *fbf = *bits++; fbf += 2048; } else for (i = 0; i < h && y0 + i < height; i++) { *fbf = *bits++; fbf += 2048; } next_glyph: x += pci->metrics.characterWidth; } lc0->addrspace = LEO_ADDRSPC_OBGR; if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; if (clip) { ld0->vclipmin = 0; ld0->vclipmax = pLeo->vclipmax; } }
void LeoTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pGlyphBase) { LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; RegionPtr clip; int h, hTmp; int widthGlyph, widthGlyphs; BoxRec bbox; FontPtr pfont = pGC->font; int curw = -1; unsigned int *fbf; unsigned char *fb; int height, width; widthGlyph = FONTMAXBOUNDS(pfont,characterWidth); h = FONTASCENT(pfont) + FONTDESCENT(pfont); clip = cfbGetCompositeClip(pGC); bbox.x1 = x + pDrawable->x; bbox.x2 = bbox.x1 + (widthGlyph * nglyph); bbox.y1 = y + pDrawable->y - FONTASCENT(pfont); bbox.y2 = bbox.y1 + h; /* If fully out of range, and we have no chance of getting back * in range, no work to do. */ y = y + pDrawable->y - FONTASCENT(pfont); x += pDrawable->x; height = pLeo->height; width = pLeo->width; if (x >= width) return; switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox)) { case rgnPART: if (REGION_NUM_RECTS(clip) == 1) { ld0->vclipmin = (clip->extents.y1 << 16) | clip->extents.x1; ld0->vclipmax = ((clip->extents.y2 - 1) << 16) | (clip->extents.x2 - 1); break; } x -= pDrawable->x; y = y - pDrawable->y + FONTASCENT(pfont); if (pGlyphBase) cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, NULL); else miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pGlyphBase); case rgnOUT: return; default: clip = NULL; break; } lc0->addrspace = LEO_ADDRSPC_FONT_OBGR; ld0->fg = pGC->fgPixel; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; fb = (unsigned char *)pLeo->fb; if(pGlyphBase) lc0->fontt = 1; else { lc0->fontt = 0; ld0->bg = pGC->bgPixel; } #define LoopIt(count, w, loadup, fetch) \ if (w != curw) { \ curw = w; \ lc0->fontmsk = 0xffffffff << (32 - w); \ } \ while (nglyph >= count) { \ loadup \ nglyph -= count; \ fbf = (unsigned *)(fb + (y << 13) + (x << 2)); \ hTmp = h; \ if (y + h <= height) \ while (hTmp--) { \ *fbf = fetch; \ fbf += 2048; \ } \ else \ for (hTmp = 0; hTmp < h && y + hTmp < height; hTmp++) { \ *fbf = fetch; \ fbf += 2048; \ } \ x += w; \ if(x >= width) \ goto out; \ } if (widthGlyph <= 8) { widthGlyphs = widthGlyph << 2; LoopIt(4, widthGlyphs, unsigned int *char1 = (unsigned int *) (*ppci++)->bits; unsigned int *char2 = (unsigned int *) (*ppci++)->bits; unsigned int *char3 = (unsigned int *) (*ppci++)->bits; unsigned int *char4 = (unsigned int *) (*ppci++)->bits;,
/* *----------------------------------------------------------------------- * RootlessComputeClips -- * Recompute the clipList, borderClip, exposed and borderExposed * regions for pParent and its children. Only viewable windows are * taken into account. * * Results: * None. * * Side Effects: * clipList, borderClip, exposed and borderExposed are altered. * A VisibilityNotify event may be generated on the parent window. * *----------------------------------------------------------------------- */ static void RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, RegionPtr universe, VTKind kind, RegionPtr exposed) { int dx, dy; RegionRec childUniverse; register WindowPtr pChild; int oldVis, newVis; BoxRec borderSize; RegionRec childUnion; Bool overlap; RegionPtr borderVisible; Bool resized; /* * Figure out the new visibility of this window. * The extent of the universe should be the same as the extent of * the borderSize region. If the window is unobscured, this rectangle * will be completely inside the universe (the universe will cover it * completely). If the window is completely obscured, none of the * universe will cover the rectangle. */ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); if (dx > 32767) dx = 32767; borderSize.x2 = dx; dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); if (dy > 32767) dy = 32767; borderSize.y2 = dy; oldVis = pParent->visibility; switch (RECT_IN_REGION( pScreen, universe, &borderSize)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnPART: newVis = VisibilityPartiallyObscured; { RegionPtr pBounding; if ((pBounding = wBoundingShape (pParent))) { switch (RootlessShapedWindowIn (pScreen, universe, pBounding, &borderSize, pParent->drawable.x, pParent->drawable.y)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnOUT: newVis = VisibilityFullyObscured; break; } } } break; default: newVis = VisibilityFullyObscured; break; } pParent->visibility = newVis; if (oldVis != newVis && ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) SendVisibilityNotify(pParent); dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; /* * avoid computations when dealing with simple operations */ switch (kind) { case VTMap: case VTStack: case VTUnmap: break; case VTMove: if ((oldVis == newVis) && ((oldVis == VisibilityFullyObscured) || (oldVis == VisibilityUnobscured))) { pChild = pParent; while (1) { if (pChild->viewable) { if (pChild->visibility != VisibilityFullyObscured) { REGION_TRANSLATE( pScreen, &pChild->borderClip, dx, dy); REGION_TRANSLATE( pScreen, &pChild->clipList, dx, dy); pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pChild, dx, dy); } if (pChild->valdata) { REGION_NULL(pScreen, &pChild->valdata->after.borderExposed); if (HasParentRelativeBorder(pChild)) { REGION_SUBTRACT(pScreen, &pChild->valdata->after.borderExposed, &pChild->borderClip, &pChild->winSize); } REGION_NULL(pScreen, &pChild->valdata->after.exposed); } if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pParent)) pChild = pChild->parent; if (pChild == pParent) break; pChild = pChild->nextSib; } return; } /* fall through */ default: /* * To calculate exposures correctly, we have to translate the old * borderClip and clipList regions to the window's new location so there * is a correspondence between pieces of the new and old clipping regions. */ if (dx || dy) { /* * We translate the old clipList because that will be exposed or copied * if gravity is right. */ REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy); REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy); } break; case VTBroken: REGION_EMPTY (pScreen, &pParent->borderClip); REGION_EMPTY (pScreen, &pParent->clipList); break; } borderVisible = pParent->valdata->before.borderVisible; resized = pParent->valdata->before.resized; REGION_NULL(pScreen, &pParent->valdata->after.borderExposed); REGION_NULL(pScreen, &pParent->valdata->after.exposed); /* * Since the borderClip must not be clipped by the children, we do * the border exposure first... * * 'universe' is the window's borderClip. To figure the exposures, remove * the area that used to be exposed from the new. * This leaves a region of pieces that weren't exposed before. */ if (HasBorder (pParent)) { if (borderVisible) { /* * when the border changes shape, the old visible portions * of the border will be saved by DIX in borderVisible -- * use that region and destroy it */ REGION_SUBTRACT( pScreen, exposed, universe, borderVisible); REGION_DESTROY( pScreen, borderVisible); } else { REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip); } if (HasParentRelativeBorder(pParent) && (dx || dy)) { REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed, universe, &pParent->winSize); } else { REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed, exposed, &pParent->winSize); } REGION_COPY( pScreen, &pParent->borderClip, universe); /* * To get the right clipList for the parent, and to make doubly sure * that no child overlaps the parent's border, we remove the parent's * border from the universe before proceeding. */ REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize); } else REGION_COPY( pScreen, &pParent->borderClip, universe); if ((pChild = pParent->firstChild) && pParent->mapped) { REGION_NULL(pScreen, &childUniverse); REGION_NULL(pScreen, &childUnion); if ((pChild->drawable.y < pParent->lastChild->drawable.y) || ((pChild->drawable.y == pParent->lastChild->drawable.y) && (pChild->drawable.x < pParent->lastChild->drawable.x))) { for (; pChild; pChild = pChild->nextSib) { if (pChild->viewable) REGION_APPEND( pScreen, &childUnion, &pChild->borderSize); } } else { for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { if (pChild->viewable) REGION_APPEND( pScreen, &childUnion, &pChild->borderSize); } } REGION_VALIDATE( pScreen, &childUnion, &overlap); for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->viewable) { /* * If the child is viewable, we want to remove its extents * from the current universe, but we only re-clip it if * it's been marked. */ if (pChild->valdata) { /* * Figure out the new universe from the child's * perspective and recurse. */ REGION_INTERSECT( pScreen, &childUniverse, universe, &pChild->borderSize); RootlessComputeClips (pChild, pScreen, &childUniverse, kind, exposed); } /* * Once the child has been processed, we remove its extents * from the current universe, thus denying its space to any * other sibling. */ if (overlap) REGION_SUBTRACT( pScreen, universe, universe, &pChild->borderSize); } } if (!overlap) REGION_SUBTRACT( pScreen, universe, universe, &childUnion); REGION_UNINIT( pScreen, &childUnion); REGION_UNINIT( pScreen, &childUniverse); } /* if any children */ /* * 'universe' now contains the new clipList for the parent window. * * To figure the exposure of the window we subtract the old clip from the * new, just as for the border. */ if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe); } else if (newVis != VisibilityFullyObscured && newVis != VisibilityNotViewable) { REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed, universe, &pParent->clipList); } /* * One last thing: backing storage. We have to try to save what parts of * the window are about to be obscured. We can just subtract the universe * from the old clipList and get the areas that were in the old but aren't * in the new and, hence, are about to be obscured. */ if (pParent->backStorage && !resized) { REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe); (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy); } /* HACK ALERT - copying contents of regions, instead of regions */ { RegionRec tmp; tmp = pParent->clipList; pParent->clipList = *universe; *universe = tmp; } #ifdef NOTDEF REGION_COPY( pScreen, &pParent->clipList, universe); #endif pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pParent, dx, dy); }