예제 #1
0
파일: fbimage.c 프로젝트: aosm/X11
void
fbPutImage (DrawablePtr	pDrawable,
	    GCPtr	pGC,
	    int		depth,
	    int		x,
	    int		y,
	    int		w,
	    int		h,
	    int		leftPad,
	    int		format,
	    char	*pImage)
{
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    unsigned long   i;
    FbStride	    srcStride;
    FbStip	    *src = (FbStip *) pImage;
    
    x += pDrawable->x;
    y += pDrawable->y;
    
    switch (format)
    {
    case XYBitmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	fbPutXYImage (pDrawable,
		      fbGetCompositeClip(pGC),
		      pPriv->fg,
		      pPriv->bg,
		      pPriv->pm,
		      pGC->alu,
		      TRUE,
		      x, y, w, h,
		      src,
		      srcStride,
		      leftPad);
	break;
    case XYPixmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	for (i = 1 << (pDrawable->depth - 1); i; i >>= 1)
	{
	    if (i & pGC->planemask)
	    {
		fbPutXYImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      FB_ALLONES,
			      0,
			      fbReplicatePixel (i, pDrawable->bitsPerPixel),
			      pGC->alu,
			      TRUE,
			      x, y, w, h,
			      src,
			      srcStride,
			      leftPad);
		src += srcStride * h;
	    }
	}
	break;
    case ZPixmap:
#ifdef FB_24_32BIT
	if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth);
	    fb24_32PutZImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      pGC->alu,
			      (FbBits) pGC->planemask,
			      x, y, w, h,
			      (CARD8 *) pImage,
			      srcStride);
	}
	else
#endif
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip);
	    fbPutZImage (pDrawable,
			 fbGetCompositeClip(pGC),
			 pGC->alu,
			 pPriv->pm,
			 x, y, w, h, 
			 src, srcStride);
	}
    }
}
예제 #2
0
파일: fbpush.c 프로젝트: aosm/X11
void
fbPushFill (DrawablePtr	pDrawable,
	    GCPtr	pGC,

	    FbStip	*src,
	    FbStride	srcStride,
	    int		srcX,
	    
	    int		x,
	    int		y,
	    int		width,
	    int		height)
{
    FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
    
    if (pGC->fillStyle == FillSolid)
    {
	FbBits	    *dst;
	FbStride    dstStride;
	int	    dstBpp;
	int	    dstXoff, dstYoff;
	int	    dstX;
	int	    dstWidth;

	fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
	dst = dst + (y + dstYoff) * dstStride;
	dstX = (x + dstXoff) * dstBpp;
	dstWidth = width * dstBpp;
	if (dstBpp == 1)
	{
	    fbBltStip (src,
		       srcStride,
		       srcX,
    
		       (FbStip *) dst,
		       FbBitsStrideToStipStride (dstStride),
		       dstX,
    
		       dstWidth,
		       height,
    
		       FbStipple1Rop(pGC->alu,pGC->fgPixel),
		       pPriv->pm,
		       dstBpp);
	}
	else
	{
	    fbBltOne (src,
		      srcStride,
		      srcX,
    
		      dst,
		      dstStride,
		      dstX,
		      dstBpp,
    
		      dstWidth,
		      height,
    
		      pPriv->and, pPriv->xor,
		      fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
		      fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
	}
    }
    else
    {
	fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
		       x, y, width, height);
    }
}
예제 #3
0
void
fbImageGlyphBlt (DrawablePtr	pDrawable,
		 GCPtr		pGC,
		 int		x, 
		 int		y,
		 unsigned int	nglyph,
		 CharInfoPtr	*ppciInit,
		 pointer	pglyphBase)
{
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    CharInfoPtr	    *ppci;
    CharInfoPtr	    pci;
    unsigned char   *pglyph;		/* pointer bits in glyph */
    int		    gWidth, gHeight;	/* width and height of glyph */
    FbStride	    gStride;		/* stride of glyph */
    Bool	    opaque;
    int		    n;
    int		    gx, gy;
#ifndef FBNOPIXADDR
    void	    (*glyph) (FbBits *,
			      FbStride,
			      int,
			      FbStip *,
			      FbBits,
			      int,
			      int);
    FbBits	    *dst = 0;
    FbStride	    dstStride = 0;
    int		    dstBpp = 0;
    int		    dstXoff = 0, dstYoff = 0;
    
    glyph = 0;
    if (pPriv->and == 0)
    {
	dstBpp = pDrawable->bitsPerPixel;
	switch (dstBpp) {
	case 8:	    glyph = fbGlyph8; break;
	case 16:    glyph = fbGlyph16; break;
#ifdef FB_24BIT
	case 24:    glyph = fbGlyph24; break;
#endif
	case 32:    glyph = fbGlyph32; break;
	}
    }
#endif
    
    x += pDrawable->x;
    y += pDrawable->y;

    if (TERMINALFONT (pGC->font)
#ifndef FBNOPIXADDR
	&& !glyph
#endif
	)
    {
	opaque = TRUE;
    }
    else
    {
	int		xBack, widthBack;
	int		yBack, heightBack;
	
	ppci = ppciInit;
	n = nglyph;
	widthBack = 0;
	while (n--)
	    widthBack += (*ppci++)->metrics.characterWidth;
	
        xBack = x;
	if (widthBack < 0)
	{
	    xBack += widthBack;
	    widthBack = -widthBack;
	}
	yBack = y - FONTASCENT(pGC->font);
	heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
	fbSolidBoxClipped (pDrawable,
			   fbGetCompositeClip(pGC),
			   xBack,
			   yBack,
			   xBack + widthBack,
			   yBack + heightBack,
			   fbAnd(GXcopy,pPriv->bg,pPriv->pm),
			   fbXor(GXcopy,pPriv->bg,pPriv->pm));
	opaque = FALSE;
    }

    ppci = ppciInit;
    while (nglyph--)
    {
	pci = *ppci++;
	pglyph = FONTGLYPHBITS(pglyphBase, pci);
	gWidth = GLYPHWIDTHPIXELS(pci);
	gHeight = GLYPHHEIGHTPIXELS(pci);
	if (gWidth && gHeight)
	{
	    gx = x + pci->metrics.leftSideBearing;
	    gy = y - pci->metrics.ascent; 
#ifndef FBNOPIXADDR
	    if (glyph && gWidth <= sizeof (FbStip) * 8 &&
		fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
	    {
		fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
		(*glyph) (dst + (gy + dstYoff) * dstStride,
			  dstStride,
			  dstBpp,
			  (FbStip *) pglyph,
			  pPriv->fg,
			  gx + dstXoff,
			  gHeight);
		fbFinishAccess (pDrawable);
	    }
	    else
#endif
	    {
		gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
		fbPutXYImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      pPriv->fg,
			      pPriv->bg,
			      pPriv->pm,
			      GXcopy,
			      opaque,
    
			      gx,
			      gy,
			      gWidth, gHeight,
    
			      (FbStip *) pglyph,
			      gStride,
			      0);
	    }
	}
	x += pci->metrics.characterWidth;
    }
}
예제 #4
0
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);
}
예제 #5
0
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbBits mask;

    /*
     * if the client clip is different or moved OR the subwindowMode has
     * changed OR the window's clip has changed since the last validation
     * we need to recompute the composite clip 
     */

    if ((changes &
         (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
        ) {
        miComputeCompositeClip(pGC, pDrawable);
    }

    if (pPriv->bpp != pDrawable->bitsPerPixel) {
        changes |= GCStipple | GCForeground | GCBackground | GCPlaneMask;
        pPriv->bpp = pDrawable->bitsPerPixel;
    }
    if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
        (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
        fbGetRotatedPixmap(pGC) = 0;
    }

    if (pGC->fillStyle == FillTiled) {
        PixmapPtr pOldTile, pNewTile;

        pOldTile = pGC->tile.pixmap;
        if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
            pNewTile = fbGetRotatedPixmap(pGC);
            if (!pNewTile ||
                pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
                if (pNewTile)
                    (*pGC->pScreen->DestroyPixmap) (pNewTile);
                pNewTile =
                    fb24_32ReformatTile(pOldTile, pDrawable->bitsPerPixel);
            }
            if (pNewTile) {
                fbGetRotatedPixmap(pGC) = pOldTile;
                pGC->tile.pixmap = pNewTile;
                changes |= GCTile;
            }
        }
    }
    if (changes & GCTile) {
        if (!pGC->tileIsPixel &&
            FbEvenTile(pGC->tile.pixmap->drawable.width *
                       pDrawable->bitsPerPixel))
            fbPadPixmap(pGC->tile.pixmap);
    }
    if (changes & GCStipple) {
        pPriv->evenStipple = FALSE;

        if (pGC->stipple) {

            /* can we do an even stipple ?? */
            if (FbEvenStip(pGC->stipple->drawable.width,
                           pDrawable->bitsPerPixel) &&
                (fbCanEvenStipple(pGC->stipple, pDrawable->bitsPerPixel)))
                pPriv->evenStipple = TRUE;

            if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
                FB_UNIT)
                fbPadPixmap(pGC->stipple);
        }
    }
    /*
     * Recompute reduced rop values
     */
    if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
        int s;
        FbBits depthMask;

        mask = FbFullMask(pDrawable->bitsPerPixel);
        depthMask = FbFullMask(pDrawable->depth);

        pPriv->fg = pGC->fgPixel & mask;
        pPriv->bg = pGC->bgPixel & mask;

        if ((pGC->planemask & depthMask) == depthMask)
            pPriv->pm = mask;
        else
            pPriv->pm = pGC->planemask & mask;

        s = pDrawable->bitsPerPixel;
        while (s < FB_UNIT) {
            pPriv->fg |= pPriv->fg << s;
            pPriv->bg |= pPriv->bg << s;
            pPriv->pm |= pPriv->pm << s;
            s <<= 1;
        }
        pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
        pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
    }
    if (changes & GCDashList) {
        unsigned short n = pGC->numInDashList;
        unsigned char *dash = pGC->dash;
        unsigned int dashLength = 0;

        while (n--)
            dashLength += (unsigned int) *dash++;
        pPriv->dashLength = dashLength;
    }
}
예제 #6
0
void
fbPolyGlyphBlt (DrawablePtr	pDrawable,
		GCPtr		pGC,
		int		x, 
		int		y,
		unsigned int	nglyph,
		CharInfoPtr	*ppci,
		pointer		pglyphBase)
{
    FbGCPrivPtr	    pPriv = fbGetGCPrivate (pGC);
    CharInfoPtr	    pci;
    unsigned char   *pglyph;		/* pointer bits in glyph */
    int		    gx, gy;
    int		    gWidth, gHeight;	/* width and height of glyph */
    FbStride	    gStride;		/* stride of glyph */
#ifndef FBNOPIXADDR
    void	    (*glyph) (FbBits *,
			      FbStride,
			      int,
			      FbStip *,
			      FbBits,
			      int,
			      int);
    FbBits	    *dst = 0;
    FbStride	    dstStride = 0;
    int		    dstBpp = 0;
    int		    dstXoff = 0, dstYoff = 0;
    
    glyph = 0;
    if (pGC->fillStyle == FillSolid && pPriv->and == 0)
    {
	dstBpp = pDrawable->bitsPerPixel;
	switch (dstBpp) {
	case 8:	    glyph = fbGlyph8; break;
	case 16:    glyph = fbGlyph16; break;
#ifdef FB_24BIT
	case 24:    glyph = fbGlyph24; break;
#endif
	case 32:    glyph = fbGlyph32; break;
	}
    }
#endif
    x += pDrawable->x;
    y += pDrawable->y;

    while (nglyph--)
    {
	pci = *ppci++;
	pglyph = FONTGLYPHBITS(pglyphBase, pci);
	gWidth = GLYPHWIDTHPIXELS(pci);
	gHeight = GLYPHHEIGHTPIXELS(pci);
	if (gWidth && gHeight)
	{
	    gx = x + pci->metrics.leftSideBearing;
	    gy = y - pci->metrics.ascent; 
#ifndef FBNOPIXADDR
	    if (glyph && gWidth <= sizeof (FbStip) * 8 &&
		fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
	    {
		fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
		(*glyph) (dst + (gy + dstYoff) * dstStride,
			  dstStride,
			  dstBpp,
			  (FbStip *) pglyph,
			  pPriv->xor,
			  gx + dstXoff,
			  gHeight);
		fbFinishAccess (pDrawable);
	    }
	    else
#endif
	    {
		gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
		fbPushImage (pDrawable,
			     pGC,
    
			     (FbStip *) pglyph,
			     gStride,
			     0,
    
			     gx,
			     gy,
			     gWidth, gHeight);
	    }
	}
	x += pci->metrics.characterWidth;
    }
}
예제 #7
0
파일: fbfill.c 프로젝트: dimkr/tinyxserver
void
fbFill (DrawablePtr pDrawable,
	GCPtr	    pGC,
	int	    x,
	int	    y,
	int	    width,
	int	    height)
{
    FbBits	    *dst;
    FbStride	    dstStride;
    int		    dstBpp;
    int		    dstXoff, dstYoff;
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    
    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);

    switch (pGC->fillStyle) {
    case FillSolid:
	fbSolid (dst + (y + dstYoff) * dstStride, 
		 dstStride, 
		 (x + dstXoff) * dstBpp,
		 dstBpp,
		 width * dstBpp, height,
		 pPriv->and, pPriv->xor);
	break;
    case FillStippled:
    case FillOpaqueStippled: {
	PixmapPtr   pStip = pGC->stipple;
	int	    stipWidth = pStip->drawable.width;
	int	    stipHeight = pStip->drawable.height;
	
	if (dstBpp == 1)
	{
	    int		alu;
	    FbBits	*stip;
	    FbStride    stipStride;
	    int		stipBpp;
	    int		stipXoff, stipYoff; /* XXX assumed to be zero */

	    if (pGC->fillStyle == FillStippled)
		alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
	    else
		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
	    fbTile (dst + (y + dstYoff) * dstStride,
		    dstStride,
		    x + dstXoff,
		    width, height,
		    stip,
		    stipStride,
		    stipWidth,
		    stipHeight,
		    alu,
		    pPriv->pm,
		    dstBpp,
		    
		    (pGC->patOrg.x + pDrawable->x),
		    pGC->patOrg.y + pDrawable->y - y);
	}
	else
	{
	    FbStip	*stip;
	    FbStride    stipStride;
	    int		stipBpp;
	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
	    FbBits	fgand, fgxor, bgand, bgxor;

	    fgand = pPriv->and;
	    fgxor = pPriv->xor;
	    if (pGC->fillStyle == FillStippled)
	    {
		bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
		bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
	    }
	    else
	    {
		bgand = pPriv->bgand;
		bgxor = pPriv->bgxor;
	    }

	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
	    fbStipple (dst + y * dstStride, 
		       dstStride, 
		       x * dstBpp,
		       dstBpp,
		       width * dstBpp, height,
		       stip,
		       stipStride,
		       stipWidth,
		       stipHeight,
		       pPriv->evenStipple,
		       fgand, fgxor,
		       bgand, bgxor,
		       pGC->patOrg.x + pDrawable->x,
		       pGC->patOrg.y + pDrawable->y - y);
	}
	break;
    }
    case FillTiled: {
	PixmapPtr   pTile = pGC->tile.pixmap;
	FbBits	    *tile;
	FbStride    tileStride;
	int	    tileBpp;
	int	    tileWidth;
	int	    tileHeight;
	int	    tileXoff, tileYoff; /* XXX assumed to be zero */
	
	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
	tileWidth = pTile->drawable.width;
	tileHeight = pTile->drawable.height;
	fbTile (dst + (y + dstYoff) * dstStride, 
		dstStride, 
		(x + dstXoff) * dstBpp, 
		width * dstBpp, height,
		tile,
		tileStride,
		tileWidth * tileBpp,
		tileHeight,
		pGC->alu,
		pPriv->pm,
		dstBpp,
		(pGC->patOrg.x + pDrawable->x) * dstBpp,
		pGC->patOrg.y + pDrawable->y - y);
	break;
    }
    }
    fbValidateDrawable (pDrawable);
}
예제 #8
0
파일: fbseg.c 프로젝트: mirror/xserver
static void
fbBresSolid(DrawablePtr pDrawable,
            GCPtr pGC,
            int dashOffset,
            int signdx,
            int signdy,
            int axis, int x1, int y1, int e, int e1, int e3, int len)
{
    FbStip *dst;
    FbStride dstStride;
    int dstBpp;
    int dstXoff, dstYoff;
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbStip and = (FbStip) pPriv->and;
    FbStip xor = (FbStip) pPriv->xor;
    FbStip mask, mask0;
    FbStip bits;

    fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    dst += ((y1 + dstYoff) * dstStride);
    x1 = (x1 + dstXoff) * dstBpp;
    dst += x1 >> FB_STIP_SHIFT;
    x1 &= FB_STIP_MASK;
    mask0 = FbStipMask(0, dstBpp);
    mask = FbStipRight(mask0, x1);
    if (signdx < 0)
        mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp);
    if (signdy < 0)
        dstStride = -dstStride;
    if (axis == X_AXIS) {
        bits = 0;
        while (len--) {
            bits |= mask;
            mask = fbBresShiftMask(mask, signdx, dstBpp);
            if (!mask) {
                WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits));
                bits = 0;
                dst += signdx;
                mask = mask0;
            }
            e += e1;
            if (e >= 0) {
                if (bits) {
                    WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits));
                    bits = 0;
                }
                dst += dstStride;
                e += e3;
            }
        }
        if (bits)
            WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits));
    }
    else {
        while (len--) {
            WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask));
            dst += dstStride;
            e += e1;
            if (e >= 0) {
                e += e3;
                mask = fbBresShiftMask(mask, signdx, dstBpp);
                if (!mask) {
                    dst += signdx;
                    mask = mask0;
                }
            }
        }
    }

    fbFinishAccess(pDrawable);
}
예제 #9
0
파일: fbseg.c 프로젝트: mirror/xserver
static void
fbBresDash(DrawablePtr pDrawable,
           GCPtr pGC,
           int dashOffset,
           int signdx,
           int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
{
    FbStip *dst;
    FbStride dstStride;
    int dstBpp;
    int dstXoff, dstYoff;
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbStip and = (FbStip) pPriv->and;
    FbStip xor = (FbStip) pPriv->xor;
    FbStip bgand = (FbStip) pPriv->bgand;
    FbStip bgxor = (FbStip) pPriv->bgxor;
    FbStip mask, mask0;

    FbDashDeclare;
    int dashlen;
    Bool even;
    Bool doOdd;

    fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    doOdd = pGC->lineStyle == LineDoubleDash;

    FbDashInit(pGC, pPriv, dashOffset, dashlen, even);

    dst += ((y1 + dstYoff) * dstStride);
    x1 = (x1 + dstXoff) * dstBpp;
    dst += x1 >> FB_STIP_SHIFT;
    x1 &= FB_STIP_MASK;
    mask0 = FbStipMask(0, dstBpp);
    mask = FbStipRight(mask0, x1);
    if (signdx < 0)
        mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp);
    if (signdy < 0)
        dstStride = -dstStride;
    while (len--) {
        if (even)
            WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask));
        else if (doOdd)
            WRITE(dst, FbDoMaskRRop(READ(dst), bgand, bgxor, mask));
        if (axis == X_AXIS) {
            mask = fbBresShiftMask(mask, signdx, dstBpp);
            if (!mask) {
                dst += signdx;
                mask = mask0;
            }
            e += e1;
            if (e >= 0) {
                dst += dstStride;
                e += e3;
            }
        }
        else {
            dst += dstStride;
            e += e1;
            if (e >= 0) {
                e += e3;
                mask = fbBresShiftMask(mask, signdx, dstBpp);
                if (!mask) {
                    dst += signdx;
                    mask = mask0;
                }
            }
        }
        FbDashStep(dashlen, even);
    }

    fbFinishAccess(pDrawable);
}
예제 #10
0
void
s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
{
    int		new_type;	/* drawable type has changed */
    int		new_origin;
    
    /* flags for changing the proc vector */
    FbGCPrivPtr fbPriv;
    s3PrivGCPtr	s3Priv;
    int		oneRect;
    GCOps	*newops;
    
    fbPriv = fbGetGCPrivate(pGC);
    s3Priv = s3GetGCPrivate(pGC);

    new_type = FALSE;
    new_origin = FALSE;

    /*
     * If the type of drawable has changed, fix up accelerated functions
     */
    if (s3Priv->type != pDrawable->type)
    {
	new_type = TRUE;
	s3Priv->type = pDrawable->type;
    }

    /*
     * Check tile/stipple origin
     */
    if (pGC->lastWinOrg.x != pDrawable->x || pGC->lastWinOrg.y != pDrawable->y)
	new_origin = TRUE;
    
    /*
     * Call down to FB to set clip list and rrop values
     */
    
    fbValidateGC (pGC, changes, pDrawable);
    
    /*
     * Check accelerated pattern if necessary
     */
    if (changes & (GCFillStyle|GCStipple|GCTile))
	s3CheckGCFill (pGC);
    else if (s3Priv->pPattern && 
	     (new_origin || changes & (GCTileStipXOrigin|GCTileStipYOrigin)))
	s3MoveGCFill (pGC);

    /*
     * Try to match common vector
     */
    
    if (newops = s3MatchCommon (pDrawable, pGC, fbPriv))
    {
	if (pGC->ops->devPrivate.val)
	    miDestroyGCOps (pGC->ops);
	pGC->ops = newops;
	return;
    }
    
    /*
     * No common vector matched, create private ops vector and
     * fill it in
     */
    if (!pGC->ops->devPrivate.val)
    {
	/*
	 * Switch from noop vector by first switching to fb
	 * vector and fixing it up
	 */
	if (pGC->ops == &kdNoopOps)
	{
	    pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
	    new_type = TRUE;
	}
        pGC->ops = miCreateGCOps (pGC->ops);
        pGC->ops->devPrivate.val = 1;
    }

    /*
     * Fills
     */
    if (new_type || (changes & (GCFillStyle|GCTile|GCStipple)))
    {
        pGC->ops->FillSpans = KdCheckFillSpans;
	pGC->ops->PolyFillRect = KdCheckPolyFillRect;
	if (s3Priv->type == DRAWABLE_WINDOW &&
	    (pGC->fillStyle != FillTiled || s3Priv->pPattern))
	{
	    pGC->ops->FillSpans = s3FillSpans;
	    pGC->ops->PolyFillRect = s3PolyFillRect;
	}
    }

    /*
     * Blt
     */
    if (new_type)
    {
	pGC->ops->CopyArea = s3CopyArea;
	pGC->ops->CopyPlane = s3CopyPlane;
	pGC->ops->PushPixels = s3PushPixels;
    }
    
    /*
     * Lines
     */
    if (new_type || (changes & (GCLineStyle|GCLineWidth|GCFillStyle)))
    {
	pGC->ops->Polylines = KdCheckPolylines;
	pGC->ops->PolySegment = KdCheckPolySegment;
	if (pGC->lineStyle == LineSolid &&
	    pGC->lineWidth == 0 &&
	    pGC->fillStyle == FillSolid &&
	    s3Priv->type == DRAWABLE_WINDOW)
	{
	    pGC->ops->Polylines = s3Polylines;
	    pGC->ops->PolySegment = s3PolySegment;
	}
    }

    /*
     * Polygons
     */
    if (new_type || (changes & (GCFillStyle)))
    {
	pGC->ops->FillPolygon = KdCheckFillPolygon;
	if (s3Priv->type == DRAWABLE_WINDOW &&
	    pGC->fillStyle == FillSolid)
	{
	    pGC->ops->FillPolygon = s3FillPoly;
	}
    }
	
    /*
     * Filled arcs
     */
    if (new_type || (changes & GCFillStyle))
    {
	pGC->ops->PolyFillArc = KdCheckPolyFillArc;
	if (s3Priv->type == DRAWABLE_WINDOW &&
	    pGC->fillStyle == FillSolid)
	{
	    pGC->ops->PolyFillArc = s3PolyFillArcSolid;
	}
    }
    
    /*
     * Text
     */
    if (new_type || (changes & (GCFont|GCFillStyle)))
    {
	pGC->ops->PolyGlyphBlt = KdCheckPolyGlyphBlt;
	pGC->ops->ImageGlyphBlt = KdCheckImageGlyphBlt;
	if (s3Priv->type == DRAWABLE_WINDOW && pGC->font)
	{
	    if (pGC->fillStyle == FillSolid)
	    {
		if (TERMINALFONT(pGC->font))
		    pGC->ops->PolyGlyphBlt = s3PolyTEGlyphBlt;
		else
		    pGC->ops->PolyGlyphBlt = s3PolyGlyphBlt;
	    }
	    if (TERMINALFONT(pGC->font))
		pGC->ops->ImageGlyphBlt = s3ImageTEGlyphBlt;
	    else
		pGC->ops->ImageGlyphBlt = s3ImageGlyphBlt;
        }
    }    
}
예제 #11
0
파일: fbgc.c 프로젝트: mirror/xserver
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbBits mask;

    /*
     * if the client clip is different or moved OR the subwindowMode has
     * changed OR the window's clip has changed since the last validation
     * we need to recompute the composite clip
     */

    if ((changes &
         (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
        ) {
        miComputeCompositeClip(pGC, pDrawable);
    }

    if (changes & GCTile) {
        if (!pGC->tileIsPixel &&
            FbEvenTile(pGC->tile.pixmap->drawable.width *
                       pDrawable->bitsPerPixel))
            fbPadPixmap(pGC->tile.pixmap);
    }
    if (changes & GCStipple) {
        if (pGC->stipple) {
            if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
                FB_UNIT)
                fbPadPixmap(pGC->stipple);
        }
    }
    /*
     * Recompute reduced rop values
     */
    if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
        int s;
        FbBits depthMask;

        mask = FbFullMask(pDrawable->bitsPerPixel);
        depthMask = FbFullMask(pDrawable->depth);

        pPriv->fg = pGC->fgPixel & mask;
        pPriv->bg = pGC->bgPixel & mask;

        if ((pGC->planemask & depthMask) == depthMask)
            pPriv->pm = mask;
        else
            pPriv->pm = pGC->planemask & mask;

        s = pDrawable->bitsPerPixel;
        while (s < FB_UNIT) {
            pPriv->fg |= pPriv->fg << s;
            pPriv->bg |= pPriv->bg << s;
            pPriv->pm |= pPriv->pm << s;
            s <<= 1;
        }
        pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
        pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
    }
    if (changes & GCDashList) {
        unsigned short n = pGC->numInDashList;
        unsigned char *dash = pGC->dash;
        unsigned int dashLength = 0;

        while (n--)
            dashLength += (unsigned int) *dash++;
        pPriv->dashLength = dashLength;
    }
}