123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /*
- *
- * 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.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdlib.h>
- #include "fb.h"
- 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
- };
- 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;
- int stride;
- int bpp;
- int xOff _X_UNUSED, yOff _X_UNUSED;
- fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
- width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
- 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;
- bits += stride;
- }
- }
- /*
- * 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 _X_UNUSED, stipYoff _X_UNUSED;
- 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;
- }
- 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;
- }
- }
|