mirror of
https://github.com/X11Libre/xserver.git
synced 2026-09-22 20:35:43 +00:00
Initial revision
This commit is contained in:
parent
ded6147bfb
commit
9508a382f8
982 changed files with 479777 additions and 0 deletions
310
fb/fbgc.c
Normal file
310
fb/fbgc.c
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Id: fbgc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/fb/fbgc.c,v 1.12 2001/05/29 04:54:09 keithp Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#ifdef IN_MODULE
|
||||
#include "xf86_ansic.h"
|
||||
#endif
|
||||
|
||||
const GCFuncs fbGCFuncs = {
|
||||
fbValidateGC,
|
||||
miChangeGC,
|
||||
miCopyGC,
|
||||
miDestroyGC,
|
||||
miChangeClip,
|
||||
miDestroyClip,
|
||||
miCopyClip,
|
||||
};
|
||||
|
||||
const GCOps fbGCOps = {
|
||||
fbFillSpans,
|
||||
fbSetSpans,
|
||||
fbPutImage,
|
||||
fbCopyArea,
|
||||
fbCopyPlane,
|
||||
fbPolyPoint,
|
||||
fbPolyLine,
|
||||
fbPolySegment,
|
||||
fbPolyRectangle,
|
||||
fbPolyArc,
|
||||
miFillPolygon,
|
||||
fbPolyFillRect,
|
||||
fbPolyFillArc,
|
||||
miPolyText8,
|
||||
miPolyText16,
|
||||
miImageText8,
|
||||
miImageText16,
|
||||
fbImageGlyphBlt,
|
||||
fbPolyGlyphBlt,
|
||||
fbPushPixels
|
||||
#ifdef NEED_LINEHELPER
|
||||
,NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
Bool
|
||||
fbCreateGC(GCPtr pGC)
|
||||
{
|
||||
pGC->clientClip = NULL;
|
||||
pGC->clientClipType = CT_NONE;
|
||||
|
||||
pGC->ops = (GCOps *) &fbGCOps;
|
||||
pGC->funcs = (GCFuncs *) &fbGCFuncs;
|
||||
|
||||
/* fb wants to translate before scan conversion */
|
||||
pGC->miTranslate = 1;
|
||||
|
||||
fbGetRotatedPixmap(pGC) = 0;
|
||||
fbGetExpose(pGC) = 1;
|
||||
fbGetFreeCompClip(pGC) = 0;
|
||||
fbGetCompositeClip(pGC) = 0;
|
||||
fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad pixmap to FB_UNIT bits wide
|
||||
*/
|
||||
void
|
||||
fbPadPixmap (PixmapPtr pPixmap)
|
||||
{
|
||||
int width;
|
||||
FbBits *bits;
|
||||
FbBits b;
|
||||
FbBits mask;
|
||||
int height;
|
||||
int w;
|
||||
|
||||
width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
|
||||
bits = pPixmap->devPrivate.ptr;
|
||||
height = pPixmap->drawable.height;
|
||||
mask = FbBitsMask (0, width);
|
||||
while (height--)
|
||||
{
|
||||
b = *bits & mask;
|
||||
w = width;
|
||||
while (w < FB_UNIT)
|
||||
{
|
||||
b = b | FbScrRight(b, w);
|
||||
w <<= 1;
|
||||
}
|
||||
*bits++ = b;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that 'bits' repeats every 'len' bits
|
||||
*/
|
||||
static Bool
|
||||
fbBitsRepeat (FbBits bits, int len, int width)
|
||||
{
|
||||
FbBits mask = FbBitsMask(0, len);
|
||||
FbBits orig = bits & mask;
|
||||
int i;
|
||||
|
||||
if (width > FB_UNIT)
|
||||
width = FB_UNIT;
|
||||
for (i = 0; i < width / len; i++)
|
||||
{
|
||||
if ((bits & mask) != orig)
|
||||
return FALSE;
|
||||
bits = FbScrLeft(bits,len);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether an entire bitmap line is a repetition of
|
||||
* the first 'len' bits
|
||||
*/
|
||||
static Bool
|
||||
fbLineRepeat (FbBits *bits, int len, int width)
|
||||
{
|
||||
FbBits first = bits[0];
|
||||
|
||||
if (!fbBitsRepeat (first, len, width))
|
||||
return FALSE;
|
||||
width = (width + FB_UNIT-1) >> FB_SHIFT;
|
||||
bits++;
|
||||
while (--width)
|
||||
if (*bits != first)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The even stipple code wants the first FB_UNIT/bpp bits on
|
||||
* each scanline to represent the entire stipple
|
||||
*/
|
||||
static Bool
|
||||
fbCanEvenStipple (PixmapPtr pStipple, int bpp)
|
||||
{
|
||||
int len = FB_UNIT / bpp;
|
||||
FbBits *bits;
|
||||
int stride;
|
||||
int stip_bpp;
|
||||
int stipXoff, stipYoff;
|
||||
int h;
|
||||
|
||||
/* can't even stipple 24bpp drawables */
|
||||
if ((bpp & (bpp-1)) != 0)
|
||||
return FALSE;
|
||||
/* make sure the stipple width is a multiple of the even stipple width */
|
||||
if (pStipple->drawable.width % len != 0)
|
||||
return FALSE;
|
||||
fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff);
|
||||
h = pStipple->drawable.height;
|
||||
/* check to see that the stipple repeats horizontally */
|
||||
while (h--)
|
||||
{
|
||||
if (!fbLineRepeat (bits, len, pStipple->drawable.width))
|
||||
return FALSE;
|
||||
bits += stride;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
FbBits mask;
|
||||
|
||||
pGC->lastWinOrg.x = pDrawable->x;
|
||||
pGC->lastWinOrg.y = pDrawable->y;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
|
||||
}
|
||||
|
||||
#ifdef FB_24_32BIT
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (changes & GCTile)
|
||||
{
|
||||
if (!pGC->tileIsPixel &&
|
||||
FbEvenTile (pGC->tile.pixmap->drawable.width *
|
||||
pDrawable->bitsPerPixel))
|
||||
fbPadPixmap (pGC->tile.pixmap);
|
||||
}
|
||||
if (changes & GCStipple)
|
||||
{
|
||||
if (pGC->stipple &&
|
||||
(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);
|
||||
}
|
||||
else
|
||||
pPriv->evenStipple = FALSE;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue