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);
}
Exemple #4
0
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;
}
Exemple #5
0
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;,
Exemple #9
0
/* 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;
}
Exemple #10
0
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++;
		}
	}
}