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); } }
void CreatorPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg) { WindowPtr pWin = (WindowPtr) pDrawable; CreatorPrivGCPtr gcPriv = CreatorGetGCPrivate (pGC); FFBPtr pFfb = GET_FFB_FROM_SCREEN (pGC->pScreen); ffb_fbcPtr ffb = pFfb->regs; BoxPtr extent; int xorg, yorg, lpat; if (nseg == 0) return; FFBLOG(("CreatorPolySegment: ALU(%x) PMSK(%08x) nseg(%d) lpat(%08x)\n", pGC->alu, pGC->planemask, nseg, gcPriv->linepat)); if (gcPriv->stipple == NULL) { FFB_ATTR_GC(pFfb, pGC, pWin, FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST, SEG_DRAWOP(pGC)); } 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, SEG_DRAWOP(pGC)); fbc = FFB_FBC_WIN(pWin); fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_OFF; FFB_WRITE_FBC(pFfb, ffb, fbc); } pFfb->rp_active = 1; xorg = pDrawable->x; yorg = pDrawable->y; extent = REGION_RECTS(cfbGetCompositeClip(pGC)); lpat = gcPriv->linepat; if (lpat == 0) { FFBFifo(pFfb, 1); ffb->lpat = 0; if (pFfb->has_brline_bug) { while (nseg--) { register int x1 = pSeg->x1 + xorg; register int y1 = pSeg->y1 + yorg; register int x2 = pSeg->x2 + xorg; register int y2 = pSeg->y2 + yorg; if (x1 >= extent->x1 && x2 >= extent->x1 && x1 < extent->x2 && x2 < extent->x2 && y1 >= extent->y1 && y2 >= extent->y1 && y1 < extent->y2 && y2 < extent->y2) { FFBFifo(pFfb, 5); ffb->ppc = 0; FFB_WRITE64(&ffb->by, y1, x1); FFB_WRITE64_2(&ffb->bh, y2, x2); } else { gcPriv->PolySegment(pDrawable, pGC, 1, pSeg); ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin); pFfb->rp_active = 1; } pSeg++; } } else { while (nseg--) { register int x1 = pSeg->x1 + xorg; register int y1 = pSeg->y1 + yorg; register int x2 = pSeg->x2 + xorg; register int y2 = pSeg->y2 + yorg; if (x1 >= extent->x1 && x2 >= extent->x1 && x1 < extent->x2 && x2 < extent->x2 && y1 >= extent->y1 && y2 >= extent->y1 && y1 < extent->y2 && y2 < extent->y2) { FFBFifo(pFfb, 4); FFB_WRITE64(&ffb->by, y1, x1); FFB_WRITE64_2(&ffb->bh, y2, x2); } else { gcPriv->PolySegment(pDrawable, pGC, 1, pSeg); ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin); pFfb->rp_active = 1; } pSeg++; } } } else { /* No reason to optimize the non-brline bug case since * we have to write the line pattern register each loop * anyways. */ while (nseg--) { register int x1 = pSeg->x1 + xorg; register int y1 = pSeg->y1 + yorg; register int x2 = pSeg->x2 + xorg; register int y2 = pSeg->y2 + yorg; if (x1 >= extent->x1 && x2 >= extent->x1 && x1 < extent->x2 && x2 < extent->x2 && y1 >= extent->y1 && y2 >= extent->y1 && y1 < extent->y2 && y2 < extent->y2) { FFBFifo(pFfb, 5); ffb->lpat = lpat; FFB_WRITE64(&ffb->by, y1, x1); FFB_WRITE64_2(&ffb->bh, y2, x2); } else { gcPriv->PolySegment(pDrawable, pGC, 1, pSeg); ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin); pFfb->rp_active = 1; } pSeg++; } } FFBSync(pFfb, ffb); }
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 LeoPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, xRectangle *prectInit) { LeoPtr pLeo = LeoGetScreenPrivate (pDrawable->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; xRectangle *prect; RegionPtr prgnClip; register BoxPtr pbox; BoxPtr pextent; int n; int xorg, yorg; /* No garbage please. */ if(nrectFill <= 0) return; prgnClip = cfbGetCompositeClip(pGC); prect = prectInit; xorg = pDrawable->x; yorg = pDrawable->y; if (xorg || yorg) { prect = prectInit; n = nrectFill; while(n--) { prect->x += xorg; prect->y += yorg; prect++; } } prect = prectInit; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; ld0->fg = pGC->fgPixel; if (REGION_NUM_RECTS(prgnClip) == 1) { int x1, y1, x2, y2; int x, y, xx, yy; pextent = REGION_RECTS(prgnClip); x1 = pextent->x1; y1 = pextent->y1; x2 = pextent->x2; y2 = pextent->y2; while (nrectFill--) { x = prect->x; y = prect->y; xx = x + prect->width; yy = y + prect->height; if (x < x1) x = x1; if (y < y1) y = y1; prect++; if (xx > x2) xx = x2; if (yy > y2) yy = y2; if (x >= xx) continue; if (y >= yy) continue; lc0->extent = (xx - x - 1) | ((yy - y - 1) << 11); lc0->fill = x | (y << 11); while (lc0->csr & LEO_CSR_BLT_BUSY); } } else { int x1, y1, x2, y2, bx1, by1, bx2, by2; int x, y, w, h; pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); x1 = pextent->x1; y1 = pextent->y1; x2 = pextent->x2; y2 = pextent->y2; while (nrectFill--) { if ((bx1 = prect->x) < x1) bx1 = x1; if ((by1 = prect->y) < y1) by1 = y1; bx2 = (int) prect->x + (int) prect->width; if (bx2 > x2) bx2 = x2; by2 = (int) prect->y + (int) prect->height; if (by2 > y2) by2 = y2; prect++; if (bx1 >= bx2 || by1 >= by2) continue; n = REGION_NUM_RECTS (prgnClip); pbox = REGION_RECTS(prgnClip); /* clip the rectangle to each box in the clip region this is logically equivalent to calling Intersect() */ while(n--) { x = max(bx1, pbox->x1); y = max(by1, pbox->y1); w = min(bx2, pbox->x2) - x; h = min(by2, pbox->y2) - y; pbox++; /* see if clipping left anything */ if (w > 0 && h > 0) { lc0->extent = (w - 1) | ((h - 1) << 11); lc0->fill = x | (y << 11); while (lc0->csr & LEO_CSR_BLT_BUSY); } } } } if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; }
void LeoPolyFillRect1Rect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, xRectangle *prectInit) { LeoPtr pLeo = LeoGetScreenPrivate (pDrawable->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; xRectangle *prect; RegionPtr prgnClip; BoxPtr pextent; int n; int xorg, yorg; int x1, y1, x2, y2; int x, y, xx, yy; /* No garbage please. */ if(nrectFill <= 0) return; prgnClip = cfbGetCompositeClip(pGC); prect = prectInit; xorg = pDrawable->x; yorg = pDrawable->y; if (xorg || yorg) { prect = prectInit; n = nrectFill; while(n--) { prect->x += xorg; prect->y += yorg; prect++; } } prect = prectInit; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; ld0->fg = pGC->fgPixel; pextent = REGION_RECTS(prgnClip); x1 = pextent->x1; y1 = pextent->y1; x2 = pextent->x2; y2 = pextent->y2; while (nrectFill--) { x = prect->x; y = prect->y; xx = x + prect->width; yy = y + prect->height; if (x < x1) x = x1; if (y < y1) y = y1; prect++; if (xx > x2) xx = x2; if (x >= xx) continue; if (yy > y2) yy = y2; if (y >= yy) continue; lc0->extent = (xx - x - 1) | ((yy - y - 1) << 11); lc0->fill = x | (y << 11); while (lc0->csr & LEO_CSR_BLT_BUSY); } if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; }
void LeoFillSpansStippled (DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { LeoPrivGCPtr gcPriv = LeoGetGCPrivate (pGC); LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; int numRects, *pwidthFree; DDXPointPtr pptFree; RegionPtr clip; unsigned char *fb; unsigned int *bits, msk; int cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0; clip = cfbGetCompositeClip(pGC); numRects = REGION_NUM_RECTS(clip); if (!numRects) return; if (numRects == 1) { cx1 = clip->extents.x1; cx2 = clip->extents.x2; cy1 = clip->extents.y1; cy2 = clip->extents.y2; } else { int nTmp = n * miFindMaxBand(clip); pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int)); pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec)); if (!pptFree || !pwidthFree) { if (pptFree) DEALLOCATE_LOCAL(pptFree); if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); return; } n = miClipSpans(clip, ppt, pwidth, n, pptFree, pwidthFree, fSorted); pwidth = pwidthFree; ppt = pptFree; } if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; ld0->fg = gcPriv->stipple->fg; fb = (unsigned char *)pLeo->fb; lc0->addrspace = LEO_ADDRSPC_FONT_OBGR; if (gcPriv->stipple->alu & 0x80) { lc0->fontt = 1; } else { lc0->fontt = 0; ld0->bg = gcPriv->stipple->bg; } lc0->fontmsk = 0xffffffff; msk = 0xffffffff; bits = &gcPriv->stipple->bits[0]; while (n--) { int x, y, w; unsigned int *dst, s, i, sw, sm; w = *pwidth++; x = ppt->x; y = ppt->y; ppt++; if (numRects == 1) { if (y < cy1 || y >= cy2) continue; if (x < cx1) { w -= (cx1 - x); if (w <= 0) continue; x = cx1; } if (x + w > cx2) { if (x >= cx2) continue; w = cx2 - x; } } s = bits[y & 31]; dst = (unsigned int *)(fb + (y << 13) + ((x & ~31) << 2)); if (x & 31) { sw = 32 - (x & 31); sm = 0xffffffff >> (x & 31); w -= sw; if (w <= 0) { if (w) sm &= 0xffffffff << (32 - (w & 31)); if (msk != sm) { msk = sm; lc0->fontmsk = sm; } *dst = s; continue; } if (msk != sm) { msk = sm; lc0->fontmsk = sm; } *dst = s; dst += 32; } else {
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;,
/* cfbBitBltcfb == cfbCopyPlaneExpand */ RegionPtr cfbBitBlt ( register DrawablePtr pSrcDrawable, register DrawablePtr pDstDrawable, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, void (*doBitBlt)( DrawablePtr /*pSrc*/, DrawablePtr /*pDst*/, int /*alu*/, RegionPtr /*prgnDst*/, DDXPointPtr /*pptSrc*/, unsigned long /*planemask*/), unsigned long bitPlane) { RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ Bool freeSrcClip = FALSE; RegionPtr prgnExposed; RegionRec rgnDst; DDXPointPtr pptSrc; register DDXPointPtr ppt; register BoxPtr pbox; int i; register int dx; register int dy; xRectangle origSource; DDXPointRec origDest; int numRects; BoxRec fastBox; int fastClip = 0; /* for fast clipping with pixmap source */ int fastExpose = 0; /* for fast exposures with pixmap source */ origSource.x = srcx; origSource.y = srcy; origSource.width = width; origSource.height = height; origDest.x = dstx; origDest.y = dsty; if ((pSrcDrawable != pDstDrawable) && pSrcDrawable->pScreen->SourceValidate) { (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height); } srcx += pSrcDrawable->x; srcy += pSrcDrawable->y; /* clip the source */ if (pSrcDrawable->type == DRAWABLE_PIXMAP) { if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) { prgnSrcClip = cfbGetCompositeClip(pGC); } else { fastClip = 1; } } else { if (pGC->subWindowMode == IncludeInferiors) { /* * XFree86 DDX empties the border clip when the * VT is inactive */ if (!((WindowPtr) pSrcDrawable)->parent && REGION_NOTEMPTY (pSrcDrawable->pScreen, &((WindowPtr) pSrcDrawable)->borderClip)) { /* * special case bitblt from root window in * IncludeInferiors mode; just like from a pixmap */ fastClip = 1; } else if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) { prgnSrcClip = cfbGetCompositeClip(pGC); } else { prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); freeSrcClip = TRUE; } } else { prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; } } fastBox.x1 = srcx; fastBox.y1 = srcy; fastBox.x2 = srcx + width; fastBox.y2 = srcy + height; /* Don't create a source region if we are doing a fast clip */ if (fastClip) { fastExpose = 1; /* * clip the source; if regions extend beyond the source size, * make sure exposure events get sent */ if (fastBox.x1 < pSrcDrawable->x) { fastBox.x1 = pSrcDrawable->x; fastExpose = 0; } if (fastBox.y1 < pSrcDrawable->y) { fastBox.y1 = pSrcDrawable->y; fastExpose = 0; } if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; fastExpose = 0; } if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; fastExpose = 0; } } else { REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); } dstx += pDstDrawable->x; dsty += pDstDrawable->y; if (pDstDrawable->type == DRAWABLE_WINDOW) { if (!((WindowPtr)pDstDrawable)->realized) { if (!fastClip) REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return NULL; } } dx = srcx - dstx; dy = srcy - dsty; /* Translate and clip the dst to the destination composite clip */ if (fastClip) { RegionPtr cclip; /* Translate the region directly */ fastBox.x1 -= dx; fastBox.x2 -= dx; fastBox.y1 -= dy; fastBox.y2 -= dy; /* If the destination composite clip is one rectangle we can do the clip directly. Otherwise we have to create a full blown region and call intersect */ /* XXX because CopyPlane uses this routine for 8-to-1 bit * copies, this next line *must* also correctly fetch the * composite clip from an mfb gc */ cclip = cfbGetCompositeClip(pGC); if (REGION_NUM_RECTS(cclip) == 1) { BoxPtr pBox = REGION_RECTS(cclip); if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1; if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2; if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1; if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2; /* Check to see if the region is empty */ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) { REGION_NULL(pGC->pScreen, &rgnDst); } else { REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); } } else { /* We must turn off fastClip now, since we must create a full blown region. It is intersected with the composite clip below. */ fastClip = 0; REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1); } } else { REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); } if (!fastClip) { REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, cfbGetCompositeClip(pGC)); } /* Do bit blitting */ numRects = REGION_NUM_RECTS(&rgnDst); if (numRects && width && height) { if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec)))) { REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return NULL; } pbox = REGION_RECTS(&rgnDst); ppt = pptSrc; for (i = numRects; --i >= 0; pbox++, ppt++) { ppt->x = pbox->x1 + dx; ppt->y = pbox->y1 + dy; } (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask); DEALLOCATE_LOCAL(pptSrc); } prgnExposed = NULL; if (pGC->fExpose) { /* Pixmap sources generate a NoExposed (we return NULL to do this) */ if (!fastExpose) prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, origSource.x, origSource.y, (int)origSource.width, (int)origSource.height, origDest.x, origDest.y, bitPlane); } REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return prgnExposed; }
void CreatorSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pcharsrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { WindowPtr pWin = (WindowPtr) pDrawable; FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDrawable->pScreen); ffb_fbcPtr ffb = pFfb->regs; unsigned int *psrc = (unsigned int *)pcharsrc; BoxPtr pbox, pboxLast, pboxTest; DDXPointPtr pptLast; RegionPtr prgnDst; char *addrp; int xStart, xEnd, yMax; if(pDrawable->type != DRAWABLE_WINDOW) { if (pDrawable->bitsPerPixel == 8) cfbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted); else cfb32SetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted); return; } FFBLOG(("CreatorSetSpans: ALU(%x) PMSK(%08x) nspans(%d) fsorted(%d)\n", pGC->alu, pGC->planemask, nspans, fSorted)); if (pGC->alu == GXnoop) return; /* Get SFB ready. */ FFB_ATTR_SFB_VAR_WIN(pFfb, pGC->planemask, pGC->alu, pWin); FFBWait(pFfb, ffb); if (pGC->depth == 8) addrp = (char *) pFfb->sfb8r; else addrp = (char *) pFfb->sfb32; yMax = (int) pDrawable->y + (int) pDrawable->height; prgnDst = cfbGetCompositeClip(pGC); pbox = REGION_RECTS(prgnDst); pboxLast = pbox + REGION_NUM_RECTS(prgnDst); pptLast = ppt + nspans; if(fSorted) { pboxTest = pbox; while(ppt < pptLast) { pbox = pboxTest; if(ppt->y >= yMax) break; while(pbox < pboxLast) { if(pbox->y1 > ppt->y) { break; } else if(pbox->y2 <= ppt->y) { pboxTest = ++pbox; continue; } else if(pbox->x1 > ppt->x + *pwidth) { break; } else if(pbox->x2 <= ppt->x) { pbox++; continue; } xStart = max(pbox->x1, ppt->x); xEnd = min(ppt->x + *pwidth, pbox->x2); CreatorSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, addrp, pGC->depth); if(ppt->x + *pwidth <= pbox->x2) break; else pbox++; } ppt++; psrc += *pwidth++; } } else { while(ppt < pptLast) { if(ppt->y >= 0 && ppt->y < yMax) { for(pbox = REGION_RECTS(prgnDst); pbox < pboxLast; pbox++) { if(pbox->y1 > ppt->y) { break; } else if(pbox->y2 <= ppt->y) { pbox++; break; } if(pbox->x1 <= ppt->x + *pwidth && pbox->x2 > ppt->x) { xStart = max(pbox->x1, ppt->x); xEnd = min(pbox->x2, ppt->x + *pwidth); CreatorSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, addrp, pGC->depth); } } } ppt++; psrc += *pwidth++; } } }