1539 lines
35 KiB
C
1539 lines
35 KiB
C
/*
|
|
* $RCSId: xc/programs/Xserver/hw/kdrive/igs/igsdraw.c,v 1.1 2000/05/06 22:17:43 keithp Exp $
|
|
*
|
|
* Copyright © 2000 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_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include "igs.h"
|
|
#include "igsdraw.h"
|
|
|
|
#include "Xmd.h"
|
|
#include "gcstruct.h"
|
|
#include "scrnintstr.h"
|
|
#include "pixmapstr.h"
|
|
#include "regionstr.h"
|
|
#include "mistruct.h"
|
|
#include "fontstruct.h"
|
|
#include "dixfontstr.h"
|
|
#include "fb.h"
|
|
#include "migc.h"
|
|
#include "miline.h"
|
|
|
|
CARD8 igsPatRop[16] = {
|
|
/* GXclear */ 0x00, /* 0 */
|
|
/* GXand */ 0xa0, /* src AND dst */
|
|
/* GXandReverse */ 0x50, /* src AND NOT dst */
|
|
/* GXcopy */ 0xf0, /* src */
|
|
/* GXandInverted*/ 0x0a, /* NOT src AND dst */
|
|
/* GXnoop */ 0xaa, /* dst */
|
|
/* GXxor */ 0x5a, /* src XOR dst */
|
|
/* GXor */ 0xfa, /* src OR dst */
|
|
/* GXnor */ 0x05, /* NOT src AND NOT dst */
|
|
/* GXequiv */ 0xa5, /* NOT src XOR dst */
|
|
/* GXinvert */ 0x55, /* NOT dst */
|
|
/* GXorReverse */ 0xf5, /* src OR NOT dst */
|
|
/* GXcopyInverted*/ 0x0f, /* NOT src */
|
|
/* GXorInverted */ 0xaf, /* NOT src OR dst */
|
|
/* GXnand */ 0x5f, /* NOT src OR NOT dst */
|
|
/* GXset */ 0xff, /* 1 */
|
|
};
|
|
|
|
/*
|
|
* Handle pixel transfers
|
|
*/
|
|
|
|
#define BURST
|
|
#ifdef BURST
|
|
#define PixTransDeclare VOL32 *pix_trans_base = igsc->copData,\
|
|
*pix_trans = pix_trans_base
|
|
#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 16384) pix_trans = pix_trans_base
|
|
#define PixTransStore(t) *pix_trans++ = (t)
|
|
#else
|
|
#define PixTransDeclare VOL32 *pix_trans = igsc->copData
|
|
#define PixTransStart(n)
|
|
#define PixTransStore(t) *pix_trans = (t)
|
|
#endif
|
|
|
|
static IgsPattern *
|
|
igsSetPattern (ScreenPtr pScreen,
|
|
PixmapPtr pPixmap,
|
|
CARD8 fillStyle,
|
|
INT32 xrot,
|
|
INT32 yrot)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
igsCardInfo(pScreenPriv);
|
|
igsScreenInfo(pScreenPriv);
|
|
int i;
|
|
IgsPatternCache *c;
|
|
IgsPattern *p;
|
|
|
|
if (fillStyle == FillTiled)
|
|
c = &igss->tile;
|
|
else
|
|
c = &igss->stipple;
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
p = &c->pattern[i];
|
|
if (p->serial_number == pPixmap->drawable.serialNumber &&
|
|
p->xrot == xrot &&
|
|
p->yrot == yrot)
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
p = &c->pattern[c->next];
|
|
if (++c->next == IGS_NUM_PATTERN)
|
|
c->next = 0;
|
|
p->serial_number = pPixmap->drawable.serialNumber;
|
|
p->xrot = xrot;
|
|
p->yrot = yrot;
|
|
|
|
if (fillStyle != FillTiled)
|
|
{
|
|
FbStip *pix;
|
|
FbStride pixStride;
|
|
int pixBpp;
|
|
int pixXoff, pixYoff;
|
|
CARD8 tmp[8];
|
|
CARD32 *pat;
|
|
int stipX, stipY;
|
|
int y;
|
|
FbStip bits;
|
|
|
|
fbGetStipDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, pixXoff, pixYoff);
|
|
|
|
modulus (-yrot - pixYoff, pPixmap->drawable.height, stipY);
|
|
modulus (-xrot - pixXoff, FB_UNIT, stipX);
|
|
|
|
pat = (CARD32 *) p->base;
|
|
|
|
for (y = 0; y < 8; y++)
|
|
{
|
|
bits = pix[stipY * pixStride];
|
|
FbRotLeft (bits, stipX);
|
|
tmp[y] = (CARD8) bits;
|
|
stipY++;
|
|
if (stipY == pPixmap->drawable.height)
|
|
stipY = 0;
|
|
}
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
bits = (tmp[i*4+0] |
|
|
(tmp[i*4+1] << 8) |
|
|
(tmp[i*4+2] << 16) |
|
|
(tmp[i*4+3] << 24));
|
|
IgsAdjustBits32 (bits);
|
|
*pat++ = bits;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FbBits *pix;
|
|
FbStride pixStride;
|
|
int pixBpp;
|
|
FbBits *pat;
|
|
FbStride patStride;
|
|
int patBpp;
|
|
int patXoff, patYoff;
|
|
|
|
fbGetDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, patXoff, patYoff);
|
|
|
|
pat = (FbBits *) p->base;
|
|
patBpp = pixBpp;
|
|
patStride = (patBpp * IGS_PATTERN_WIDTH) / (8 * sizeof (FbBits));
|
|
|
|
fbTile (pat, patStride, 0,
|
|
patBpp * IGS_PATTERN_WIDTH, IGS_PATTERN_HEIGHT,
|
|
|
|
pix, pixStride,
|
|
pPixmap->drawable.width * pixBpp,
|
|
pPixmap->drawable.height,
|
|
GXcopy, FB_ALLONES, pixBpp,
|
|
(xrot - patXoff) * pixBpp, yrot - patYoff);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void
|
|
igsFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
|
|
unsigned long pixel, int alu, unsigned long planemask)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
|
|
_igsSetSolidRect(cop,alu,planemask,pixel,cmd);
|
|
while (nBox--)
|
|
{
|
|
_igsRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsFillBoxTiled (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
|
|
PixmapPtr pPixmap, int xrot, int yrot, int alu)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
IgsPattern *p = igsSetPattern (pDrawable->pScreen,
|
|
pPixmap,
|
|
FillTiled,
|
|
xrot, yrot);
|
|
|
|
_igsSetTiledRect(cop,alu,planemask,p->offset,cmd);
|
|
while (nBox--)
|
|
{
|
|
_igsPatRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsFillBoxStippled (DrawablePtr pDrawable, GCPtr pGC,
|
|
int nBox, BoxPtr pBox)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int xrot = pGC->patOrg.x + pDrawable->x;
|
|
int yrot = pGC->patOrg.y + pDrawable->y;
|
|
IgsPattern *p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->stipple,
|
|
pGC->fillStyle,
|
|
xrot, yrot);
|
|
if (pGC->fillStyle == FillStippled)
|
|
{
|
|
_igsSetStippledRect (cop,pGC->alu,planemask,pGC->fgPixel,p->offset,cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetOpaqueStippledRect (cop,pGC->alu,planemask,
|
|
pGC->fgPixel,pGC->bgPixel,p->offset,cmd);
|
|
}
|
|
while (nBox--)
|
|
{
|
|
_igsPatRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
|
|
void
|
|
igsStipple (ScreenPtr pScreen,
|
|
CARD32 cmd,
|
|
FbStip *psrcBase,
|
|
FbStride widthSrc,
|
|
int srcx,
|
|
int srcy,
|
|
int dstx,
|
|
int dsty,
|
|
int width,
|
|
int height)
|
|
{
|
|
SetupIgs(pScreen);
|
|
FbStip *psrcLine, *psrc;
|
|
FbStride widthRest;
|
|
FbStip bits, tmp, lastTmp;
|
|
int leftShift, rightShift;
|
|
int nl, nlMiddle;
|
|
int r;
|
|
PixTransDeclare;
|
|
|
|
/* Compute blt address and parameters */
|
|
psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
|
|
nlMiddle = (width + 31) >> 5;
|
|
leftShift = srcx & 0x1f;
|
|
rightShift = 32 - leftShift;
|
|
widthRest = widthSrc - nlMiddle;
|
|
|
|
_igsPlaneBlt(cop,dstx,dsty,width,height,cmd);
|
|
|
|
if (leftShift == 0)
|
|
{
|
|
while (height--)
|
|
{
|
|
nl = nlMiddle;
|
|
PixTransStart(nl);
|
|
while (nl--)
|
|
{
|
|
tmp = *psrc++;
|
|
IgsAdjustBits32 (tmp);
|
|
PixTransStore (tmp);
|
|
}
|
|
psrc += widthRest;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
widthRest--;
|
|
while (height--)
|
|
{
|
|
bits = *psrc++;
|
|
nl = nlMiddle;
|
|
PixTransStart(nl);
|
|
while (nl--)
|
|
{
|
|
tmp = FbStipLeft(bits, leftShift);
|
|
bits = *psrc++;
|
|
tmp |= FbStipRight(bits, rightShift);
|
|
IgsAdjustBits32(tmp);
|
|
PixTransStore (tmp);
|
|
}
|
|
psrc += widthRest;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
igsCopyNtoN (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy,
|
|
Bool reverse,
|
|
Bool upsidedown,
|
|
Pixel bitplane,
|
|
void *closure)
|
|
{
|
|
SetupIgs(pDstDrawable->pScreen);
|
|
int srcX, srcY, dstX, dstY;
|
|
int w, h;
|
|
CARD32 flags;
|
|
CARD32 cmd;
|
|
CARD8 alu;
|
|
|
|
if (pGC)
|
|
{
|
|
alu = pGC->alu;
|
|
if (sourceInvarient (pGC->alu))
|
|
{
|
|
igsFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
alu = GXcopy;
|
|
|
|
_igsSetBlt(cop,alu,pGC->planemask,reverse,upsidedown,cmd);
|
|
while (nbox--)
|
|
{
|
|
w = pbox->x2 - pbox->x1;
|
|
h = pbox->y2 - pbox->y1;
|
|
if (reverse)
|
|
dstX = pbox->x2 - 1;
|
|
else
|
|
dstX = pbox->x1;
|
|
srcX = dstX + dx;
|
|
|
|
if (upsidedown)
|
|
dstY = pbox->y2 - 1;
|
|
else
|
|
dstY = pbox->y1;
|
|
|
|
srcY = dstY + dy;
|
|
|
|
_igsBlt (cop, srcX, srcY, dstX, dstY, w, h, cmd);
|
|
pbox++;
|
|
}
|
|
KdMarkSync (pDstDrawable->pScreen);
|
|
}
|
|
|
|
RegionPtr
|
|
igsCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
|
|
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
|
{
|
|
KdScreenPriv(pDstDrawable->pScreen);
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pSrcDrawable->type == DRAWABLE_WINDOW &&
|
|
pDstDrawable->type == DRAWABLE_WINDOW)
|
|
{
|
|
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, igsCopyNtoN, 0, 0);
|
|
}
|
|
return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height, dstx, dsty);
|
|
}
|
|
|
|
typedef struct _igs1toNargs {
|
|
unsigned long copyPlaneFG, copyPlaneBG;
|
|
Bool opaque;
|
|
} igs1toNargs;
|
|
|
|
void
|
|
igsCopy1toN (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy,
|
|
Bool reverse,
|
|
Bool upsidedown,
|
|
Pixel bitplane,
|
|
void *closure)
|
|
{
|
|
SetupIgs(pDstDrawable->pScreen);
|
|
|
|
igs1toNargs *args = closure;
|
|
int dstx, dsty;
|
|
FbStip *psrcBase;
|
|
FbStride widthSrc;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
CARD32 cmd;
|
|
|
|
if (args->opaque && sourceInvarient (pGC->alu))
|
|
{
|
|
igsFillBoxSolid (pDstDrawable, nbox, pbox,
|
|
pGC->bgPixel, pGC->alu, pGC->planemask);
|
|
return;
|
|
}
|
|
|
|
fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff);
|
|
|
|
if (args->opaque)
|
|
{
|
|
_igsSetOpaquePlaneBlt (cop, pGC->alu, pGC->planemask, args->copyPlaneFG,
|
|
args->copyPlaneBG, cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, pGC->alu, pGC->planemask,
|
|
args->copyPlaneFG, cmd);
|
|
}
|
|
|
|
while (nbox--)
|
|
{
|
|
dstx = pbox->x1;
|
|
dsty = pbox->y1;
|
|
|
|
igsStipple (pDstDrawable->pScreen, cmd,
|
|
psrcBase, widthSrc,
|
|
dstx + dx - srcXoff, dsty + dy - srcYoff,
|
|
dstx, dsty,
|
|
pbox->x2 - dstx, pbox->y2 - dsty);
|
|
pbox++;
|
|
}
|
|
KdMarkSync (pDstDrawable->pScreen);
|
|
}
|
|
|
|
RegionPtr
|
|
igsCopyPlane (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
int srcx,
|
|
int srcy,
|
|
int width,
|
|
int height,
|
|
int dstx,
|
|
int dsty,
|
|
unsigned long bitPlane)
|
|
{
|
|
RegionPtr ret;
|
|
igs1toNargs args;
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pDstDrawable->type == DRAWABLE_WINDOW &&
|
|
pSrcDrawable->depth == 1)
|
|
{
|
|
args.copyPlaneFG = pGC->fgPixel;
|
|
args.copyPlaneBG = pGC->bgPixel;
|
|
args.opaque = TRUE;
|
|
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, igsCopy1toN, bitPlane, &args);
|
|
}
|
|
return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, bitPlane);
|
|
}
|
|
|
|
#if 0
|
|
/* would you believe this is slower than fb? */
|
|
void
|
|
igsPushPixels (GCPtr pGC,
|
|
PixmapPtr pBitmap,
|
|
DrawablePtr pDrawable,
|
|
int w,
|
|
int h,
|
|
int x,
|
|
int y)
|
|
{
|
|
igs1toNargs args;
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pDrawable->type == DRAWABLE_WINDOW &&
|
|
pGC->fillStyle == FillSolid)
|
|
{
|
|
args.opaque = FALSE;
|
|
args.copyPlaneFG = pGC->fgPixel;
|
|
(void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC,
|
|
0, 0, w, h, x, y, igsCopy1toN, 1, &args);
|
|
}
|
|
else
|
|
{
|
|
KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
|
}
|
|
}
|
|
#else
|
|
#define igsPushPixels KdCheckPushPixels
|
|
#endif
|
|
|
|
BOOL
|
|
igsFillOk (GCPtr pGC)
|
|
{
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask(pGC->depth);
|
|
if ((pGC->planemask & depthMask) != depthMask)
|
|
return FALSE;
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
return TRUE;
|
|
case FillTiled:
|
|
return (igsPatternDimOk (pGC->tile.pixmap->drawable.width) &&
|
|
igsPatternDimOk (pGC->tile.pixmap->drawable.height));
|
|
case FillStippled:
|
|
case FillOpaqueStippled:
|
|
return (igsPatternDimOk (pGC->stipple->drawable.width) &&
|
|
igsPatternDimOk (pGC->stipple->drawable.height));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
igsFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
|
|
DDXPointPtr ppt, int *pwidth, int fSorted)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
DDXPointPtr pptFree;
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
int *pwidthFree;/* copies of the pointers to free */
|
|
CARD32 cmd;
|
|
int nTmp;
|
|
INT16 x, y;
|
|
int width;
|
|
IgsPattern *p;
|
|
|
|
if (!igsFillOk (pGC))
|
|
{
|
|
KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
|
|
return;
|
|
}
|
|
nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC));
|
|
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(fbGetCompositeClip(pGC),
|
|
ppt, pwidth, n,
|
|
pptFree, pwidthFree, fSorted);
|
|
pwidth = pwidthFree;
|
|
ppt = pptFree;
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
_igsSetSolidRect(cop,pGC->alu,pGC->planemask,pGC->fgPixel,cmd);
|
|
break;
|
|
case FillTiled:
|
|
p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->tile.pixmap,
|
|
FillTiled,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y);
|
|
_igsSetTiledRect (cop,pGC->alu,pGC->planemask,p->offset,cmd);
|
|
break;
|
|
default:
|
|
p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->stipple,
|
|
pGC->fillStyle,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y);
|
|
if (pGC->fillStyle == FillStippled)
|
|
{
|
|
_igsSetStippledRect (cop,pGC->alu,pGC->planemask,
|
|
pGC->fgPixel,p->offset,cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetOpaqueStippledRect (cop,pGC->alu,pGC->planemask,
|
|
pGC->fgPixel,pGC->bgPixel,p->offset,cmd);
|
|
}
|
|
break;
|
|
}
|
|
while (n--)
|
|
{
|
|
x = ppt->x;
|
|
y = ppt->y;
|
|
ppt++;
|
|
width = *pwidth++;
|
|
if (width)
|
|
{
|
|
_igsPatRect(cop,x,y,width,1,cmd);
|
|
}
|
|
}
|
|
DEALLOCATE_LOCAL(pptFree);
|
|
DEALLOCATE_LOCAL(pwidthFree);
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
#define NUM_STACK_RECTS 1024
|
|
|
|
void
|
|
igsPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
|
int nrectFill, xRectangle *prectInit)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
xRectangle *prect;
|
|
RegionPtr prgnClip;
|
|
register BoxPtr pbox;
|
|
register BoxPtr pboxClipped;
|
|
BoxPtr pboxClippedBase;
|
|
BoxPtr pextent;
|
|
BoxRec stackRects[NUM_STACK_RECTS];
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC);
|
|
int numRects;
|
|
int n;
|
|
int xorg, yorg;
|
|
int x, y;
|
|
|
|
if (!igsFillOk (pGC))
|
|
{
|
|
KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
|
|
return;
|
|
}
|
|
prgnClip = fbGetCompositeClip (pGC);
|
|
xorg = pDrawable->x;
|
|
yorg = pDrawable->y;
|
|
|
|
if (xorg || yorg)
|
|
{
|
|
prect = prectInit;
|
|
n = nrectFill;
|
|
while(n--)
|
|
{
|
|
prect->x += xorg;
|
|
prect->y += yorg;
|
|
prect++;
|
|
}
|
|
}
|
|
|
|
prect = prectInit;
|
|
|
|
numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
|
|
if (numRects > NUM_STACK_RECTS)
|
|
{
|
|
pboxClippedBase = (BoxPtr)xalloc(numRects * sizeof(BoxRec));
|
|
if (!pboxClippedBase)
|
|
return;
|
|
}
|
|
else
|
|
pboxClippedBase = stackRects;
|
|
|
|
pboxClipped = pboxClippedBase;
|
|
|
|
if (REGION_NUM_RECTS(prgnClip) == 1)
|
|
{
|
|
int x1, y1, x2, y2, bx2, by2;
|
|
|
|
pextent = REGION_RECTS(prgnClip);
|
|
x1 = pextent->x1;
|
|
y1 = pextent->y1;
|
|
x2 = pextent->x2;
|
|
y2 = pextent->y2;
|
|
while (nrectFill--)
|
|
{
|
|
if ((pboxClipped->x1 = prect->x) < x1)
|
|
pboxClipped->x1 = x1;
|
|
|
|
if ((pboxClipped->y1 = prect->y) < y1)
|
|
pboxClipped->y1 = y1;
|
|
|
|
bx2 = (int) prect->x + (int) prect->width;
|
|
if (bx2 > x2)
|
|
bx2 = x2;
|
|
pboxClipped->x2 = bx2;
|
|
|
|
by2 = (int) prect->y + (int) prect->height;
|
|
if (by2 > y2)
|
|
by2 = y2;
|
|
pboxClipped->y2 = by2;
|
|
|
|
prect++;
|
|
if ((pboxClipped->x1 < pboxClipped->x2) &&
|
|
(pboxClipped->y1 < pboxClipped->y2))
|
|
{
|
|
pboxClipped++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int x1, y1, x2, y2, bx2, by2;
|
|
|
|
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
|
|
x1 = pextent->x1;
|
|
y1 = pextent->y1;
|
|
x2 = pextent->x2;
|
|
y2 = pextent->y2;
|
|
while (nrectFill--)
|
|
{
|
|
BoxRec box;
|
|
|
|
if ((box.x1 = prect->x) < x1)
|
|
box.x1 = x1;
|
|
|
|
if ((box.y1 = prect->y) < y1)
|
|
box.y1 = y1;
|
|
|
|
bx2 = (int) prect->x + (int) prect->width;
|
|
if (bx2 > x2)
|
|
bx2 = x2;
|
|
box.x2 = bx2;
|
|
|
|
by2 = (int) prect->y + (int) prect->height;
|
|
if (by2 > y2)
|
|
by2 = y2;
|
|
box.y2 = by2;
|
|
|
|
prect++;
|
|
|
|
if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
|
|
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--)
|
|
{
|
|
pboxClipped->x1 = max(box.x1, pbox->x1);
|
|
pboxClipped->y1 = max(box.y1, pbox->y1);
|
|
pboxClipped->x2 = min(box.x2, pbox->x2);
|
|
pboxClipped->y2 = min(box.y2, pbox->y2);
|
|
pbox++;
|
|
|
|
/* see if clipping left anything */
|
|
if(pboxClipped->x1 < pboxClipped->x2 &&
|
|
pboxClipped->y1 < pboxClipped->y2)
|
|
{
|
|
pboxClipped++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pboxClipped != pboxClippedBase)
|
|
{
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
igsFillBoxSolid(pDrawable,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase,
|
|
pGC->fgPixel, pGC->alu, pGC->planemask);
|
|
break;
|
|
case FillTiled:
|
|
igsFillBoxTiled(pDrawable,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase,
|
|
pGC->tile.pixmap,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y,
|
|
pGC->alu);
|
|
break;
|
|
case FillStippled:
|
|
case FillOpaqueStippled:
|
|
igsFillBoxStippled (pDrawable, pGC,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase);
|
|
break;
|
|
}
|
|
}
|
|
if (pboxClippedBase != stackRects)
|
|
xfree(pboxClippedBase);
|
|
}
|
|
|
|
int
|
|
igsTextInRegion (GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci)
|
|
{
|
|
int w;
|
|
FontPtr pfont = pGC->font;
|
|
BoxRec bbox;
|
|
|
|
if (FONTCONSTMETRICS(pfont))
|
|
w = FONTMAXBOUNDS(pfont,characterWidth) * nglyph;
|
|
else
|
|
{
|
|
w = 0;
|
|
while (nglyph--)
|
|
w += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (w < 0)
|
|
{
|
|
bbox.x1 = x + w;
|
|
bbox.x2 = x;
|
|
}
|
|
else
|
|
{
|
|
bbox.x1 = x;
|
|
bbox.x2 = x + w;
|
|
}
|
|
w = FONTMINBOUNDS(pfont,leftSideBearing);
|
|
if (w < 0)
|
|
bbox.x1 += w;
|
|
w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
|
|
if (w > 0)
|
|
bbox.x2 += w;
|
|
bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
|
|
bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
|
|
|
|
return RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox);
|
|
}
|
|
|
|
void
|
|
igsGlyphBltClipped (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppciInit,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int h;
|
|
int w;
|
|
int xBack, yBack;
|
|
int hBack, wBack;
|
|
int lw;
|
|
FontPtr pfont = pGC->font;
|
|
CharInfoPtr pci;
|
|
unsigned long *bits;
|
|
BoxPtr extents;
|
|
BoxRec bbox;
|
|
CARD32 b;
|
|
CharInfoPtr *ppci;
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
RegionPtr pClip = fbGetCompositeClip(pGC);
|
|
BoxPtr pBox;
|
|
int nbox;
|
|
int x1, y1, x2, y2;
|
|
unsigned char alu;
|
|
Bool set;
|
|
PixTransDeclare;
|
|
|
|
if (image)
|
|
{
|
|
xBack = x;
|
|
yBack = y - FONTASCENT(pGC->font);
|
|
wBack = 0;
|
|
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
|
if (hBack)
|
|
{
|
|
h = nglyph;
|
|
ppci = ppciInit;
|
|
while (h--)
|
|
wBack += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (wBack < 0)
|
|
{
|
|
xBack = xBack + wBack;
|
|
wBack = -wBack;
|
|
}
|
|
if (hBack < 0)
|
|
{
|
|
yBack = yBack + hBack;
|
|
hBack = -hBack;
|
|
}
|
|
alu = GXcopy;
|
|
if (wBack)
|
|
{
|
|
_igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
|
|
for (nbox = REGION_NUM_RECTS (pClip),
|
|
pBox = REGION_RECTS (pClip);
|
|
nbox--;
|
|
pBox++)
|
|
{
|
|
x1 = xBack;
|
|
x2 = xBack + wBack;
|
|
y1 = yBack;
|
|
y2 = yBack + hBack;
|
|
if (x1 < pBox->x1) x1 = pBox->x1;
|
|
if (x2 > pBox->x2) x2 = pBox->x2;
|
|
if (y1 < pBox->y1) y1 = pBox->y1;
|
|
if (y2 > pBox->y2) y2 = pBox->y2;
|
|
if (x1 < x2 && y1 < y2)
|
|
{
|
|
_igsRect (cop, x1, y1, x2 - x1, y2 - y1, cmd);
|
|
}
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wBack = 0;
|
|
alu = pGC->alu;
|
|
}
|
|
|
|
ppci = ppciInit;
|
|
set = FALSE;
|
|
while (nglyph--)
|
|
{
|
|
pci = *ppci++;
|
|
h = pci->metrics.ascent + pci->metrics.descent;
|
|
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
|
|
x1 = x + pci->metrics.leftSideBearing;
|
|
y1 = y - pci->metrics.ascent;
|
|
bbox.x1 = x1;
|
|
bbox.y1 = y1;
|
|
bbox.x2 = x1 + w;
|
|
bbox.y2 = y1 + h;
|
|
switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
|
|
{
|
|
case rgnIN:
|
|
lw = h * ((w + 31) >> 5);
|
|
if (lw)
|
|
{
|
|
if (!set)
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
set = TRUE;
|
|
}
|
|
_igsPlaneBlt(cop,
|
|
x + pci->metrics.leftSideBearing,
|
|
y - pci->metrics.ascent,
|
|
w, h, cmd);
|
|
bits = (unsigned long *) pci->bits;
|
|
PixTransStart (lw);
|
|
while (lw--)
|
|
{
|
|
b = *bits++;
|
|
IgsAdjustBits32 (b);
|
|
PixTransStore(b);
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
break;
|
|
case rgnPART:
|
|
set = FALSE;
|
|
KdCheckSync (pDrawable->pScreen);
|
|
fbPutXYImage (pDrawable,
|
|
pClip,
|
|
fbPriv->fg,
|
|
fbPriv->bg,
|
|
fbPriv->pm,
|
|
alu,
|
|
FALSE,
|
|
x1, y1,
|
|
w, h,
|
|
(FbStip *) pci->bits,
|
|
(w + 31) >> 5,
|
|
0);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
x += pci->metrics.characterWidth;
|
|
}
|
|
}
|
|
|
|
void
|
|
igsGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppciInit,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int h;
|
|
int w;
|
|
int xBack, yBack;
|
|
int hBack, wBack;
|
|
int lw;
|
|
FontPtr pfont = pGC->font;
|
|
CharInfoPtr pci;
|
|
unsigned long *bits;
|
|
BoxPtr extents;
|
|
BoxRec bbox;
|
|
CARD32 b;
|
|
CharInfoPtr *ppci;
|
|
unsigned char alu;
|
|
PixTransDeclare;
|
|
|
|
/*
|
|
* Paint background for image text
|
|
*/
|
|
if (image)
|
|
{
|
|
xBack = x;
|
|
yBack = y - FONTASCENT(pGC->font);
|
|
wBack = 0;
|
|
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
|
if (hBack)
|
|
{
|
|
h = nglyph;
|
|
ppci = ppciInit;
|
|
while (h--)
|
|
wBack += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (wBack < 0)
|
|
{
|
|
xBack = xBack + wBack;
|
|
wBack = -wBack;
|
|
}
|
|
if (hBack < 0)
|
|
{
|
|
yBack = yBack + hBack;
|
|
hBack = -hBack;
|
|
}
|
|
alu = GXcopy;
|
|
if (wBack)
|
|
{
|
|
_igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
|
|
_igsRect (cop, xBack, yBack, wBack, hBack, cmd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wBack = 0;
|
|
alu = pGC->alu;
|
|
}
|
|
|
|
_igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
ppci = ppciInit;
|
|
while (nglyph--)
|
|
{
|
|
pci = *ppci++;
|
|
h = pci->metrics.ascent + pci->metrics.descent;
|
|
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
|
|
lw = h * ((w + 31) >> 5);
|
|
if (lw)
|
|
{
|
|
_igsPlaneBlt(cop,
|
|
x + pci->metrics.leftSideBearing,
|
|
y - pci->metrics.ascent,
|
|
w, h, cmd);
|
|
bits = (unsigned long *) pci->bits;
|
|
PixTransStart(lw);
|
|
while (lw--)
|
|
{
|
|
b = *bits++;
|
|
IgsAdjustBits32 (b);
|
|
PixTransStore(b);
|
|
}
|
|
}
|
|
x += pci->metrics.characterWidth;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsTEGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int xInit,
|
|
int yInit,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int x, y;
|
|
int h, lw, lwTmp;
|
|
int w;
|
|
FontPtr pfont = pGC->font;
|
|
unsigned long *char1, *char2, *char3, *char4;
|
|
int widthGlyphs, widthGlyph;
|
|
BoxRec bbox;
|
|
CARD32 tmp;
|
|
PixTransDeclare;
|
|
|
|
widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
|
|
if (!widthGlyph)
|
|
return;
|
|
|
|
h = FONTASCENT(pfont) + FONTDESCENT(pfont);
|
|
if (!h)
|
|
return;
|
|
|
|
x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing);
|
|
y = yInit - FONTASCENT(pfont);
|
|
|
|
if (image)
|
|
{
|
|
_igsSetOpaquePlaneBlt (cop, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel, cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, pGC->alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
}
|
|
|
|
#if BITMAP_BIT_ORDER == LSBFirst
|
|
#define SHIFT <<
|
|
#else
|
|
#define SHIFT >>
|
|
#endif
|
|
|
|
#define LoopIt(count, w, loadup, fetch) \
|
|
while (nglyph >= count) \
|
|
{ \
|
|
nglyph -= count; \
|
|
_igsPlaneBlt (cop, x, y, w, h, cmd); \
|
|
x += w; \
|
|
loadup \
|
|
lwTmp = h; \
|
|
PixTransStart(h); \
|
|
while (lwTmp--) { \
|
|
tmp = fetch; \
|
|
IgsAdjustBits32(tmp); \
|
|
PixTransStore(tmp); \
|
|
} \
|
|
}
|
|
|
|
if (widthGlyph <= 8)
|
|
{
|
|
widthGlyphs = widthGlyph << 2;
|
|
LoopIt(4, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;
|
|
char3 = (unsigned long *) (*ppci++)->bits;
|
|
char4 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | ((*char2++ | ((*char3++ | (*char4++
|
|
SHIFT widthGlyph))
|
|
SHIFT widthGlyph))
|
|
SHIFT widthGlyph)))
|
|
}
|
|
else if (widthGlyph <= 10)
|
|
{
|
|
widthGlyphs = (widthGlyph << 1) + widthGlyph;
|
|
LoopIt(3, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;
|
|
char3 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
|
|
}
|
|
else if (widthGlyph <= 16)
|
|
{
|
|
widthGlyphs = widthGlyph << 1;
|
|
LoopIt(2, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | (*char2++ SHIFT widthGlyph)))
|
|
}
|
|
lw = h * ((widthGlyph + 31) >> 5);
|
|
while (nglyph--)
|
|
{
|
|
_igsPlaneBlt (cop, x, y, widthGlyph, h, cmd);
|
|
x += widthGlyph;
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
lwTmp = lw;
|
|
PixTransStart(lw);
|
|
while (lwTmp--)
|
|
{
|
|
tmp = *char1++;
|
|
IgsAdjustBits32(tmp);
|
|
PixTransStore(tmp);
|
|
}
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
/*
|
|
* Blt glyphs using image transfer window
|
|
*/
|
|
|
|
void
|
|
igsPolyGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
pointer pglyphBase)
|
|
{
|
|
if (pGC->fillStyle != FillSolid ||
|
|
fbGetGCPrivate(pGC)->pm != FB_ALLONES)
|
|
{
|
|
KdCheckPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
|
return;
|
|
}
|
|
x += pDrawable->x;
|
|
y += pDrawable->y;
|
|
|
|
switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
|
|
case rgnIN:
|
|
if (TERMINALFONT(pGC->font))
|
|
igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
else
|
|
igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
break;
|
|
case rgnPART:
|
|
igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
igsImageGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x, int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
pointer pglyphBase)
|
|
{
|
|
if (fbGetGCPrivate(pGC)->pm != FB_ALLONES)
|
|
{
|
|
KdCheckImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
|
return;
|
|
}
|
|
x += pDrawable->x;
|
|
y += pDrawable->y;
|
|
|
|
switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
|
|
case rgnIN:
|
|
if (TERMINALFONT(pGC->font))
|
|
igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
else
|
|
igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
break;
|
|
case rgnPART:
|
|
igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
igsInvalidatePattern (IgsPatternCache *c,
|
|
PixmapPtr pPixmap)
|
|
{
|
|
int i;
|
|
|
|
if (c->base)
|
|
{
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
if (c->pattern[i].serial_number == pPixmap->drawable.serialNumber)
|
|
c->pattern[i].serial_number = ~0;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
igsInitPattern (IgsPatternCache *c, int bsize, int psize)
|
|
{
|
|
int i;
|
|
int boffset;
|
|
int poffset;
|
|
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
boffset = i * bsize;
|
|
poffset = i * psize;
|
|
c->pattern[i].xrot = -1;
|
|
c->pattern[i].yrot = -1;
|
|
c->pattern[i].serial_number = ~0;
|
|
c->pattern[i].offset = c->offset + poffset;
|
|
c->pattern[i].base = c->base + boffset;
|
|
}
|
|
c->next = 0;
|
|
}
|
|
|
|
static const GCOps igsOps = {
|
|
igsFillSpans,
|
|
KdCheckSetSpans,
|
|
KdCheckPutImage,
|
|
igsCopyArea,
|
|
igsCopyPlane,
|
|
KdCheckPolyPoint,
|
|
KdCheckPolylines,
|
|
KdCheckPolySegment,
|
|
miPolyRectangle,
|
|
KdCheckPolyArc,
|
|
miFillPolygon,
|
|
igsPolyFillRect,
|
|
KdCheckPolyFillArc,
|
|
miPolyText8,
|
|
miPolyText16,
|
|
miImageText8,
|
|
miImageText16,
|
|
igsImageGlyphBlt,
|
|
igsPolyGlyphBlt,
|
|
igsPushPixels,
|
|
#ifdef NEED_LINEHELPER
|
|
,NULL
|
|
#endif
|
|
};
|
|
|
|
void
|
|
igsValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
|
|
{
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
|
|
fbValidateGC (pGC, changes, pDrawable);
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW)
|
|
pGC->ops = (GCOps *) &igsOps;
|
|
else
|
|
pGC->ops = (GCOps *) &fbGCOps;
|
|
}
|
|
|
|
GCFuncs igsGCFuncs = {
|
|
igsValidateGC,
|
|
miChangeGC,
|
|
miCopyGC,
|
|
miDestroyGC,
|
|
miChangeClip,
|
|
miDestroyClip,
|
|
miCopyClip
|
|
};
|
|
|
|
int
|
|
igsCreateGC (GCPtr pGC)
|
|
{
|
|
if (!fbCreateGC (pGC))
|
|
return FALSE;
|
|
|
|
if (pGC->depth != 1)
|
|
pGC->funcs = &igsGCFuncs;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
igsCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
|
{
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
KdScreenPriv(pScreen);
|
|
RegionRec rgnDst;
|
|
int dx, dy;
|
|
WindowPtr pwinRoot;
|
|
|
|
pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
|
|
|
|
dx = ptOldOrg.x - pWin->drawable.x;
|
|
dy = ptOldOrg.y - pWin->drawable.y;
|
|
REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
|
|
|
|
REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
|
|
|
|
REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
|
|
|
|
fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
|
|
0,
|
|
&rgnDst, dx, dy, igsCopyNtoN, 0, 0);
|
|
|
|
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
|
|
}
|
|
|
|
void
|
|
igsPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
|
{
|
|
KdScreenPriv(pWin->drawable.pScreen);
|
|
PixmapPtr pTile;
|
|
|
|
if (!REGION_NUM_RECTS(pRegion))
|
|
return;
|
|
switch (what) {
|
|
case PW_BACKGROUND:
|
|
switch (pWin->backgroundState) {
|
|
case None:
|
|
return;
|
|
case ParentRelative:
|
|
do {
|
|
pWin = pWin->parent;
|
|
} while (pWin->backgroundState == ParentRelative);
|
|
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
|
|
what);
|
|
return;
|
|
case BackgroundPixmap:
|
|
pTile = pWin->background.pixmap;
|
|
if (igsPatternDimOk (pTile->drawable.width) &&
|
|
igsPatternDimOk (pTile->drawable.height))
|
|
{
|
|
igsFillBoxTiled ((DrawablePtr)pWin,
|
|
(int)REGION_NUM_RECTS(pRegion),
|
|
REGION_RECTS(pRegion),
|
|
pTile,
|
|
pWin->drawable.x, pWin->drawable.y, GXcopy);
|
|
return;
|
|
}
|
|
break;
|
|
case BackgroundPixel:
|
|
igsFillBoxSolid((DrawablePtr)pWin,
|
|
(int)REGION_NUM_RECTS(pRegion),
|
|
REGION_RECTS(pRegion),
|
|
pWin->background.pixel, GXcopy, ~0);
|
|
return;
|
|
}
|
|
break;
|
|
case PW_BORDER:
|
|
if (pWin->borderIsPixel)
|
|
{
|
|
igsFillBoxSolid((DrawablePtr)pWin,
|
|
(int)REGION_NUM_RECTS(pRegion),
|
|
REGION_RECTS(pRegion),
|
|
pWin->border.pixel, GXcopy, ~0);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
pTile = pWin->border.pixmap;
|
|
if (igsPatternDimOk (pTile->drawable.width) &&
|
|
igsPatternDimOk (pTile->drawable.height))
|
|
{
|
|
igsFillBoxTiled ((DrawablePtr)pWin,
|
|
(int)REGION_NUM_RECTS(pRegion),
|
|
REGION_RECTS(pRegion),
|
|
pTile,
|
|
pWin->drawable.x, pWin->drawable.y, GXcopy);
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
KdCheckPaintWindow (pWin, pRegion, what);
|
|
}
|
|
|
|
Bool
|
|
igsDrawInit (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
igsCardInfo(pScreenPriv);
|
|
igsScreenInfo(pScreenPriv);
|
|
int i;
|
|
int pattern_size;
|
|
int boffset, poffset;
|
|
|
|
KdScreenInitAsync (pScreen);
|
|
|
|
/*
|
|
* Replace various fb screen functions
|
|
*/
|
|
pScreen->CreateGC = igsCreateGC;
|
|
pScreen->CopyWindow = igsCopyWindow;
|
|
pScreen->PaintWindowBackground = igsPaintWindow;
|
|
pScreen->PaintWindowBorder = igsPaintWindow;
|
|
|
|
/*
|
|
* Initialize patterns
|
|
*/
|
|
if (igss->tile.base)
|
|
{
|
|
pattern_size = IgsTileSize(pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
igsInitPattern (&igss->tile,
|
|
pattern_size,
|
|
pattern_size * 8 / pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
pattern_size = IgsStippleSize(pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
igsInitPattern (&igss->stipple,
|
|
pattern_size,
|
|
pattern_size * 8 / pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
igsDrawEnable (ScreenPtr pScreen)
|
|
{
|
|
SetupIgs(pScreen);
|
|
CARD32 cmd;
|
|
CARD32 base;
|
|
CARD16 stride;
|
|
CARD32 format;
|
|
|
|
stride = pScreenPriv->screen->fb[0].pixelStride;
|
|
_igsWaitIdleEmpty(cop);
|
|
_igsReset(cop);
|
|
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
|
|
case 8:
|
|
format = IGS_FORMAT_8BPP;
|
|
break;
|
|
case 16:
|
|
format = IGS_FORMAT_16BPP;
|
|
break;
|
|
case 24:
|
|
format = IGS_FORMAT_24BPP;
|
|
break;
|
|
case 32:
|
|
format = IGS_FORMAT_32BPP;
|
|
break;
|
|
}
|
|
cop->format = format;
|
|
cop->dst_stride = stride - 1;
|
|
cop->src1_stride = stride - 1;
|
|
cop->src2_stride = stride - 1;
|
|
cop->src1_start = 0;
|
|
cop->src2_start = 0;
|
|
cop->extension |= IGS_BLOCK_COP_REG | IGS_BURST_ENABLE;
|
|
|
|
_igsSetSolidRect(cop, GXcopy, ~0, pScreen->blackPixel, cmd);
|
|
_igsRect (cop, 0, 0,
|
|
pScreenPriv->screen->width, pScreenPriv->screen->height,
|
|
cmd);
|
|
_igsWaitIdleEmpty (cop);
|
|
}
|
|
|
|
void
|
|
igsDrawDisable (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|
|
void
|
|
igsDrawFini (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|
|
void
|
|
igsDrawSync (ScreenPtr pScreen)
|
|
{
|
|
SetupIgs(pScreen);
|
|
|
|
_igsWaitIdleEmpty(cop);
|
|
}
|