home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xibm.zip
/
ibm8514
/
brcFillRct.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-04
|
27KB
|
1,124 lines
/*
* $Id: brcFillRct.c,v 1.5 1991/10/04 03:51:01 mtranle Exp $
*
* Copyright IBM Corporation 1987,1988,1989
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* 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 IBM not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* IBM 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.
*
*/
/***********************************************************
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
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 names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL 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.
******************************************************************/
#include "X.h"
#include "servermd.h"
#include "pixmapstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "miscstruct.h"
#include "regionstr.h"
#include "scrnintstr.h"
#include "OScompiler.h"
#include "x8514.h"
#include "ibmTrace.h"
#include "ppc.h"
extern int mfbGCPrivateIndex;
extern int mergexlate[] ;
extern int ibm8514cursorSemaphore ;
void ibm8514FillRectSolid();
void ibm8514FillRectStippled();
void ibm8514FillRectOpStippled();
void ibm8514FillRectTiled();
void ibm8514AreaFill();
#define NUM_STACK_RECTS 1024
/*
* filled rectangles.
* translate the rectangles, clip them, and call the
* helper function in the GC.
*/
void
ibm8514PolyFillRect( pDrawable, pGC, nrectFill, prectInit )
DrawablePtr pDrawable ;
GCPtr pGC ;
int nrectFill ; /* number of rectangles to fill */
xRectangle *prectInit ; /* Pointer to first rectangle to fill */
{
xRectangle *prect ; /* temporary */
RegionPtr prgnClip ;
register BoxPtr pbox ; /* used to clip with */
register BoxPtr pboxClipped ;
BoxPtr pboxClippedBase ;
BoxPtr pextent ;
BoxRec stackRects[NUM_STACK_RECTS];
ppcPrivGC *priv;
int numRects;
void (* BoxFill)() ;
int n ; /* spare counter */
int xorg, yorg;
TRACE(("ibm8514PolyFillRect(0x%x,0x%x,%d,0x%x)\n",pDrawable,pGC,
nrectFill,prectInit)) ;
if ( pDrawable->type != DRAWABLE_WINDOW )
{
ErrorF("ibm8514PolyFillRect: Not a window\n") ;
return ;
}
if ( ( pGC->alu == GXnoop ) || !pGC->planemask || !nrectFill )
return ;
priv = (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
prgnClip = priv->pCompositeClip ;
BoxFill = 0;
switch (pGC->fillStyle)
{
case FillSolid:
BoxFill = ibm8514FillRectSolid;
break;
case FillStippled:
BoxFill = ibm8514FillRectStippled;
break;
case FillOpaqueStippled:
BoxFill = ibm8514FillRectOpStippled;
break;
case FillTiled:
BoxFill = ibm8514FillRectTiled;
break;
}
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)ALLOCATE_LOCAL(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 = (*pGC->pScreen->RegionExtents)(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)
(*BoxFill) (pDrawable, pboxClipped-pboxClippedBase, pboxClippedBase,
pGC);
if (pboxClippedBase != stackRects)
DEALLOCATE_LOCAL(pboxClippedBase);
}
/*
* Same as ibm8514CheckCursor but does it on the bounding box of a list
* of boxes pBox.
*/
int
ibm8514CheckCursorInBoxes(nBox, pBox)
int nBox;
BoxPtr pBox;
{
if (nBox == 1)
return ibm8514CheckCursor(pBox->x1, pBox->y1,
pBox->x2 - pBox->x1 + 1,
pBox->y2 - pBox->y1 + 1);
else
{
int xmin, xmax, ymin, ymax;
xmin = pBox->x1;
xmax = pBox->x2;
ymin = pBox->y1;
ymax = pBox->y2;
pBox++; nBox--;
for ( ; nBox ; nBox--, pBox++)
{
if (pBox->x1 < xmin) xmin = pBox->x1;
if (pBox->x2 > xmax) xmax = pBox->x2;
if (pBox->y1 < ymin) ymin = pBox->y1;
if (pBox->y2 > ymax) ymax = pBox->y2;
}
return ibm8514CheckCursor(xmin, ymin, xmax-xmin+1, ymax-ymin+1);
}
}
/*
* Handle Solid Rectangle Fill
*/
void
ibm8514FillRectSolid(pWin, nBox, pBox, pGC)
WindowPtr pWin;
GCPtr pGC;
int nBox;
BoxPtr pBox;
{
int CursorIsSaved;
short x, y, w, h;
ppcPrivGC *priv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
if (priv->colorRrop.alu == GXnoop || !nBox)
return;
CursorIsSaved = (!ibm8514cursorSemaphore &&
ibm8514CheckCursorInBoxes(nBox, pBox));
ibm8514ATRNotBusy ;
ibm8514CheckQueue(3) ;
SETFN1(FNCOLOR1, mergexlate[priv->colorRrop.alu]);
SETCOL1(priv->colorRrop.fgPixel) ;
PLNWENBL(priv->colorRrop.planemask) ;
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
ibm8514CheckQueue(5) ;
SETY0(y) ;
SETX0(x) ;
SETLY(h-1) ;
SETLX(w-1) ;
COMMAND(0x80b3) ; /* Horizontal Rect operation,
DX = DY = 'increasing'*/
}
ibm8514ClearQueue(2) ;
PLNWENBL( ibm8514ALLPLANES ) ;
SETFN1(FNCOLOR1, FNREPLACE) ;
if (CursorIsSaved)
ibm8514ReplaceCursor() ;
}
/*
* Handle Stippled Rectangle Fill.
*/
void
ibm8514FillRectStippled(pWin, nBox, pBox, pGC)
WindowPtr pWin;
GCPtr pGC;
int nBox;
BoxPtr pBox;
{
int CursorIsSaved;
short x, y, w, h;
unsigned short tlx, tly ;
short xSrc, ySrc;
PixmapPtr pStipple;
ppcPrivGC *priv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
int hcount, vcount, vtarget, htarget, savehcount, savehtarget ;
int maxhite, maxwid ;
if (priv->colorRrop.alu == GXnoop || !nBox)
return;
pStipple = pGC->stipple;
tlx = pStipple->drawable.width ;
tly = pStipple->drawable.height ;
/* this replaces rotating the stipple. Instead we just adjust the offset
* at which we start grabbing bits from the stipple.
* Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
* so that iline and xrem always stay within the stipple bounds.
*/
xSrc = (pGC->patOrg.x % tlx) - tlx + pWin->drawable.x;
ySrc = (pGC->patOrg.y % tly) - tly + pWin->drawable.y;
CursorIsSaved = (!ibm8514cursorSemaphore &&
ibm8514CheckCursorInBoxes(nBox, pBox));
ibm8514cursorSemaphore++;
if ( ( tlx > MAXSTIPPLEWIDTH ) || ( tly > MAXSTIPPLEHEIGHT ) )
{
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
ibm8514UnnaturalStipple( pStipple,
priv->colorRrop.fgPixel,
priv->colorRrop.alu,
priv->colorRrop.planemask,
x, y, w, h, xSrc, ySrc) ;
}
}
else
{
int stageMonoDone = 0;
ibm8514ATRNotBusy ;
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
if ( x < 0 )
{
w += x ;
x = 0 ;
}
if ( y < 0 )
{
h += y ;
y = 0 ;
}
w = MIN(_8514_SCREENWIDTH-x, w) ;
h = MIN(_8514_SCREENHEIGHT-y, h) ;
if ( ( w <= 0) || (h <= 0) )
continue ;
if (!stageMonoDone)
{
ibm8514StageMono(tlx, tly, pStipple->devPrivate.ptr) ;
stageMonoDone++;
}
/*expand the tile to largest available size */
maxwid = MIN(MAXSTIPPLEWIDTH, w) ;
maxhite = MIN(MAXSTIPPLEHEIGHT, h) ;
if ( (tlx*2 <= maxwid) || ((tly*2) <= maxhite) )
{
ibm8514CheckQueue( 4 ) ;
PLNRENBL( MONO_STAGE_RPLANE ) ;
PLNWENBL( MONO_STAGE_WPLANE ) ;
SETFN1( FNCPYRCT, mergexlate[GXcopy] ) ;
SETLY( tly-1 ) ;
while ( tlx*2 <= maxwid )
{
/*
* ibm8514Bitblt( GXcopy, MONO_STAGE_RPLANE,
* MONO_STAGE_WPLANE,
* MONO_STAGE_X, MONO_STAGE_Y,
* MONO_STAGE_X, tly+MONO_STAGE_Y,
* tlx, tly)
*/
ibm8514CheckQueue( 6 ) ;
SETX0( MONO_STAGE_X ) ;
SETX1( tlx + MONO_STAGE_X ) ;
SETLX( tlx-1 ) ;
SETY0( MONO_STAGE_Y ) ;
SETY1( MONO_STAGE_Y ) ;
COMMAND( 0xC0F3 ) ;
tlx *= 2 ;
}
ibm8514CheckQueue( 1 ) ;
SETLX( tlx-1 ) ;
while ( tly*2 <= maxhite )
{
/*
* ibm8514Bitblt( GXcopy, MONO_STAGE_RPLANE,
* MONO_STAGE_WPLANE,
* MONO_STAGE_X, MONO_STAGE_Y,
* MONO_STAGE_X, tly+MONO_STAGE_Y,
* tlx, tly) ;
*/
ibm8514CheckQueue( 6 ) ;
SETY0( MONO_STAGE_Y ) ;
SETY1( tly + MONO_STAGE_Y ) ;
SETLY( tly-1 ) ;
SETX0( MONO_STAGE_X ) ;
SETX1( MONO_STAGE_X ) ;
COMMAND( 0xC0F3 ) ;
tly *= 2 ;
}
}
{
int tmp = ( x - xSrc ) % tlx ;
if ( tmp < 0 )
tmp += tlx ;
savehtarget = htarget = x - tmp ;
}
{
int tmp = ( y - ySrc ) % tly ;
if ( tmp < 0 )
tmp += tly ;
vtarget = y - tmp ;
}
savehcount = hcount = ((x+w-htarget)+tlx-1)/tlx ; /*tiles to fill horiz */
vcount = ((y+h-vtarget)+tly-1)/tly ; /*tiles it will take to fill vert */
ibm8514ClearQueue(4) ;
SETXMAX(x+w-1) ;
SETYMAX(y+h-1) ;
SETXMIN(x) ;
SETYMIN(y) ;
/* -- */
ibm8514CheckQueue( 6 ) ;
SETFN0( FNCOLOR0, FNNOP ) ;
SETFN1( FNCOLOR1, mergexlate[priv->colorRrop.alu] ) ;
PLNRENBL( MONO_STAGE_RPLANE ) ;
PLNWENBL( priv->colorRrop.planemask ) ;
SETMODE( M_CPYRCT ) ;
SETCOL1( priv->colorRrop.fgPixel ) ;
ibm8514CheckQueue( 2 ) ;
SETLX( tlx-1 ) ;
SETLY( tly-1 ) ;
while ( vcount-- )
{
while ( hcount-- )
{
/*
* ibm8514BlitFG( MONO_STAGE_RPLANE, pm, fg, alu,
* MONO_STAGE_X, MONO_STAGE_Y,
* htarget, vtarget, tlx, tly) ;
*/
ibm8514CheckQueue( 5 ) ;
SETX0( MONO_STAGE_X ) ;
SETY0( MONO_STAGE_Y ) ;
SETX1( htarget ) ;
SETY1( vtarget ) ;
COMMAND( 0xC0F3 ) ;
htarget += tlx ;
}
vtarget += tly ;
htarget = savehtarget ;
hcount = savehcount ;
}
ibm8514CheckQueue( 5 ) ;
PLNRENBL( RPLANES ) ;
PLNWENBL( WPLANES ) ;
SETFN0( FNCOLOR0, FNREPLACE ) ;
SETFN1( FNCOLOR1, FNREPLACE ) ;
SETMODE( M_ONES ) ;
/* -- */
ibm8514ClearQueue(4) ;
SETXMAX(_8514_SCREENWIDTH-1) ;
SETYMAX( 1023 ) ;
SETXMIN(0) ;
SETYMIN(0) ;
}
}
if ( !(--ibm8514cursorSemaphore) && CursorIsSaved )
ibm8514ReplaceCursor() ;
}
/*
* Handle Opaque Stippled Rectangle Fill.
*/
void
ibm8514FillRectOpStippled(pWin, nBox, pBox, pGC)
WindowPtr pWin;
GCPtr pGC;
int nBox;
BoxPtr pBox;
{
int CursorIsSaved;
short x, y, w, h ;
short xSrc, ySrc;
PixmapPtr pStipple;
ppcPrivGC *priv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
unsigned short tlx, tly ;
if (priv->colorRrop.alu == GXnoop || !nBox)
return;
pStipple = pGC->stipple;
tlx = pStipple->drawable.width ;
tly = pStipple->drawable.height ;
/* this replaces rotating the stipple. Instead we just adjust the offset
* at which we start grabbing bits from the stipple.
* Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
* so that iline and xrem always stay within the stipple bounds.
*/
xSrc = (pGC->patOrg.x % tlx) - tlx + pWin->drawable.x;
ySrc = (pGC->patOrg.y % tly) - tly + pWin->drawable.y;
CursorIsSaved = (!ibm8514cursorSemaphore &&
ibm8514CheckCursorInBoxes(nBox, pBox));
ibm8514cursorSemaphore++;
if ( ( tlx > MAXSTIPPLEWIDTH ) || ( tly > MAXSTIPPLEHEIGHT ) )
{
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
ibm8514UnnaturalOpStipple( pStipple,
priv->colorRrop.fgPixel,
priv->colorRrop.bgPixel,
priv->colorRrop.alu,
priv->colorRrop.planemask,
x, y, w, h, xSrc, ySrc) ;
}
}
else
{
int hcount, vcount, vtarget, htarget, savehcount, savehtarget ;
int maxhite, maxwid ;
int stageMonoDone = 0;
ibm8514ATRNotBusy ;
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
if ( x < 0 )
{
w += x ;
x = 0 ;
}
if ( y < 0 )
{
h += y ;
y = 0 ;
}
w = MIN(_8514_SCREENWIDTH-x, w) ;
h = MIN(_8514_SCREENHEIGHT-y, h) ;
if ( (w <= 0) || (h <= 0 ) )
continue ;
if (!stageMonoDone)
{
ibm8514StageMono(tlx, tly, pStipple->devPrivate.ptr) ;
stageMonoDone++;
}
/*expand the tile to largest available size */
maxwid = MIN(MAXSTIPPLEWIDTH, w) ;
maxhite = MIN(MAXSTIPPLEHEIGHT, h) ;
if ( (tlx*2 <= maxwid) || (tly*2 <= maxhite) )
{
ibm8514CheckQueue( 4 ) ;
PLNRENBL( MONO_STAGE_RPLANE ) ;
PLNWENBL( MONO_STAGE_WPLANE ) ;
SETFN1( FNCPYRCT, mergexlate[GXcopy] ) ;
SETLY( tly-1 ) ;
while ( tlx*2 <= maxwid )
{
/*
* ibm8514Bitblt( GXcopy, MONO_STAGE_RPLANE,
* MONO_STAGE_WPLANE,
* MONO_STAGE_X, MONO_STAGE_Y,
* MONO_STAGE_X, tly+MONO_STAGE_Y,
* tlx, tly)
*/
ibm8514CheckQueue( 6 ) ;
SETX0( MONO_STAGE_X ) ;
SETY0( MONO_STAGE_Y ) ;
SETX1( tlx + MONO_STAGE_X ) ;
SETY1( MONO_STAGE_Y ) ;
SETLX( tlx-1 ) ;
COMMAND( 0xC0F3 ) ;
tlx *= 2 ;
}
ibm8514CheckQueue( 1 ) ;
SETLX( tlx-1 ) ;
while ( tly*2 <= maxhite )
{
/*
* ibm8514Bitblt( GXcopy, MONO_STAGE_RPLANE,
* MONO_STAGE_WPLANE,
* MONO_STAGE_X, MONO_STAGE_Y,
* MONO_STAGE_X, tly+MONO_STAGE_Y,
* tlx, tly) ;
*/
ibm8514CheckQueue( 6 ) ;
SETX0( MONO_STAGE_X ) ;
SETY0( MONO_STAGE_Y ) ;
SETX1( MONO_STAGE_X ) ;
SETY1( tly + MONO_STAGE_Y ) ;
SETLY( tly-1 ) ;
COMMAND( 0xC0F3 ) ;
tly *= 2 ;
}
}
{
int tmp = ( x - xSrc ) % tlx ;
if ( tmp < 0 )
tmp += tlx ;
savehtarget = htarget = x - tmp ;
}
{
int tmp = ( y - ySrc ) % tly ;
if ( tmp < 0 )
tmp += tly ;
vtarget = y - tmp ;
}
savehcount = hcount = ((x+w-htarget)+tlx-1)/tlx ; /*tiles to fill horiz */
vcount = ((y+h-vtarget)+tly-1)/tly ; /*tiles it will take to fill vert */
ibm8514ClearQueue(4) ;
SETXMAX(x+w-1) ;
SETYMAX(y+h-1) ;
SETXMIN(x) ;
SETYMIN(y) ;
/* -- */
ibm8514CheckQueue( 7 ) ;
SETFN0( FNCOLOR0, mergexlate[priv->colorRrop.alu] ) ;
SETFN1( FNCOLOR1, mergexlate[priv->colorRrop.alu] ) ;
SETCOL0( priv->colorRrop.bgPixel ) ;
SETCOL1( priv->colorRrop.fgPixel ) ;
PLNRENBL( MONO_STAGE_RPLANE ) ;
PLNWENBL( priv->colorRrop.planemask ) ;
SETMODE( M_CPYRCT ) ;
ibm8514CheckQueue( 2 ) ;
SETLX( tlx-1 ) ;
SETLY( tly-1 ) ;
while ( vcount-- )
{
while ( hcount-- )
{
/*
* ibm8514BlitFGBG(MONO_STAGE_RPLANE, planes, fg, bg,merge,
* MONO_STAGE_X, MONO_STAGE_Y,
* htarget, vtarget, tlx, tly) ;
*/
ibm8514CheckQueue( 5 ) ;
SETX0( MONO_STAGE_X ) ;
SETY0( MONO_STAGE_Y ) ;
SETX1( htarget ) ;
SETY1( vtarget ) ;
COMMAND( 0xC0F3 ) ;
htarget += tlx ;
}
vtarget += tly ;
htarget = savehtarget ;
hcount = savehcount ;
}
ibm8514CheckQueue( 5 ) ;
PLNRENBL( RPLANES ) ;
PLNWENBL( WPLANES ) ;
SETFN0( FNCOLOR0, FNREPLACE ) ;
SETFN1( FNCOLOR1, FNREPLACE ) ;
SETMODE( M_ONES ) ;
/* -- */
ibm8514ClearQueue(4) ;
SETXMAX(_8514_SCREENWIDTH-1) ;
SETYMAX( 1023 ) ;
SETXMIN(0) ;
SETYMIN(0) ;
}
}
if ( !(--ibm8514cursorSemaphore) && CursorIsSaved )
ibm8514ReplaceCursor() ;
}
/*
* Handle Tile Rectangle Fill.
*/
void
ibm8514FillRectTiled(pWin, nBox, pBox, pGC)
WindowPtr pWin;
GCPtr pGC;
int nBox;
BoxPtr pBox;
{
int CursorIsSaved;
short x, y, w, h ;
short xSrc, ySrc;
unsigned short tlx, tly;
PixmapPtr pTile;
ppcPrivGC *priv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
if (priv->colorRrop.alu == GXnoop || !nBox)
return;
switch (priv->colorRrop.alu)
{
case GXset:
case GXclear:
case GXinvert:
ibm8514FillRectSolid (pWin, nBox, pBox, pGC);
return;
}
pTile = pGC->tile.pixmap;
tlx = pTile->drawable.width ;
tly = pTile->drawable.height ;
/* this replaces rotating the stipple. Instead we just adjust the offset
* at which we start grabbing bits from the stipple.
* Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
* so that iline and xrem always stay within the stipple bounds.
*/
xSrc = (pGC->patOrg.x % tlx) - tlx + pWin->drawable.x;
ySrc = (pGC->patOrg.y % tly) - tly + pWin->drawable.y;
CursorIsSaved = (!ibm8514cursorSemaphore &&
ibm8514CheckCursorInBoxes(nBox, pBox));
ibm8514cursorSemaphore++;
if ( ( tlx > MAXTILESIZE ) || ( tly > MAXTILESIZE ) )
{
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
ppcTileRect( pTile, priv->colorRrop.alu, priv->colorRrop.planemask,
x, y, w, h, xSrc, ySrc) ;
}
}
else
{
int htarget, tmp_w, tw, th, hoffset, voffset ;
int maxhite, maxwid ;
int drawColorImageDone = 0;
ibm8514ATRNotBusy ;
for ( ; nBox; nBox--, pBox++)
{
if (!(w = pBox->x2 - (x = pBox->x1)) ||
!(h = pBox->y2 - (y = pBox->y1)))
continue;
if ( x < 0 )
{
w += x ;
x = 0 ;
}
if ( y < 0 )
{
h += y ;
y = 0 ;
}
w = MIN(_8514_SCREENWIDTH-x, w) ;
h = MIN(_8514_SCREENHEIGHT-y, h) ;
if ( (w <= 0) || (h <= 0 ) )
continue ;
if ( !drawColorImageDone )
{
/* ALAS, ALACK, we are going to have to actually draw the silly
* thing N times. I won't bother rotating it, I'll just draw
* to the origin points clipped to the desired box. It's not
* clear when this is a win.
*/
ibm8514DrawColorImage( TILE_X, TILE_Y, tlx, tly,
pTile->devPrivate.ptr,
pTile->devKind,
GXcopy, ibm8514ALLPLANES ) ;
drawColorImageDone++;
}
ibm8514CheckQueue( 2 ) ;
PLNRENBL( ibm8514ALLPLANES ) ;
PLNWENBL( ibm8514ALLPLANES ) ;
/*expand the tile to largest available size */
maxwid = MIN(MAXTILESIZE, w) ;
maxhite = MIN(MAXTILESIZE, h) ;
if ( (tlx*2 <= maxwid) || (tly*2 <= maxhite) )
{
ibm8514CheckQueue( 2 ) ;
SETFN1( FNCPYRCT, mergexlate[GXcopy] ) ;
SETLY( tly-1 );
while ( tlx*2 <= maxwid )
{
/*
* ibm8514Bitblt(GXcopy,ibm8514ALLPLANES,ibm8514ALLPLANES,
* TILE_X,TILE_Y,tlx+TILE_X,TILE_Y, tlx, tly ) ;
*/
ibm8514CheckQueue( 6 ) ;
SETX0( TILE_X ) ;
SETX1( tlx + TILE_X ) ;
SETLX( tlx-1 ) ;
SETY0( TILE_Y ) ;
SETY1( TILE_Y ) ;
COMMAND( 0xC0F3 ) ;
tlx *= 2 ;
}
ibm8514CheckQueue( 1 ) ;
SETLX( tlx-1 ) ;
while ( tly*2 <= maxhite )
{
/*
* ibm8514Bitblt(GXcopy,ibm8514ALLPLANES,ibm8514ALLPLANES,
* TILE_X,TILE_Y,TILE_X,TILE_Y+tly,tlx,tly ) ;
*/
ibm8514CheckQueue( 6 ) ;
SETY0( TILE_Y ) ;
SETY1( tly + TILE_Y ) ;
SETLY( tly-1 ) ;
SETX0( TILE_X ) ;
SETX1( TILE_X ) ;
COMMAND( 0xC0F3 ) ;
tly *= 2 ;
}
}
if ( ( hoffset = ( x - xSrc ) % tlx ) < 0 )
hoffset += tlx ;
if ( ( voffset = ( y - ySrc ) % tly ) < 0 )
voffset += tly ;
/*
* -- ibm8514RotateTile( tlx, tly, hoffset, voffset ) --
*/
/* DO BOTTOM RIGHT */
/* You definitely want to do this, even if hoffset==voffset==0.
* This is to force *something* into the RotatedTile location
*/
/*
* ibm8514Bitblt( GXcopy, ibm8514ALLPLANES, ibm8514ALLPLANES,
* TILE_X + hoffset, TILE_Y + voffset,
* ROTTILE_X, ROTTILE_Y,
* tlx-hoffset, tly-voffset ) ;
*/
ibm8514CheckQueue( 8 ) ;
SETFN1( FNCPYRCT, mergexlate[GXcopy] ) ;
SETX0( TILE_X + hoffset ) ;
SETY0( TILE_Y + voffset ) ;
SETX1( ROTTILE_X ) ;
SETY1( ROTTILE_Y ) ;
SETLX( tlx-hoffset-1 ) ;
SETLY( tly-voffset-1 ) ;
COMMAND( 0xC0F3 ) ;
/* DO TOP RIGHT */
if (voffset)
{
/*
* ibm8514Bitblt(GXcopy,ibm8514ALLPLANES,ibm8514ALLPLANES,
* TILE_X + hoffset, TILE_Y,
* ROTTILE_X, ROTTILE_Y + tly-voffset,
* tlx-hoffset, voffset ) ;
*/
ibm8514CheckQueue( 6 ) ;
SETX0( TILE_X + hoffset ) ;
SETY0( TILE_Y ) ;
SETX1( ROTTILE_X ) ;
SETY1( ROTTILE_Y + tly-voffset ) ;
SETLY( voffset-1 ) ;
COMMAND( 0xC0F3 ) ;
}
/* DO BOTTOM LEFT */
if (hoffset)
{
/*
* ibm8514Bitblt(GXcopy,ibm8514ALLPLANES,ibm8514ALLPLANES,
* TILE_X , TILE_Y+voffset,
* ROTTILE_X+tlx-hoffset, ROTTILE_Y,
* hoffset, tly-voffset ) ;
*/
ibm8514CheckQueue( 7 ) ;
SETX0( TILE_X ) ;
SETY0( TILE_Y + voffset ) ;
SETX1( ROTTILE_X + tlx-hoffset ) ;
SETY1( ROTTILE_Y ) ;
SETLX( hoffset-1 ) ;
SETLY( tly-voffset-1 ) ;
COMMAND( 0xC0F3 ) ;
/* DO TOP LEFT */
if (voffset)
{
/*
* ibm8514Bitblt(GXcopy,ibm8514ALLPLANES,
* ibm8514ALLPLANES,
* TILE_X , TILE_Y,
* ROTTILE_X+tlx-hoffset,
* ROTTILE_Y+tly-voffset,
* hoffset, voffset ) ;
*/
ibm8514CheckQueue( 6 ) ;
SETX0( TILE_X ) ;
SETY0( TILE_Y ) ;
SETX1( ROTTILE_X + tlx-hoffset ) ;
SETY1( ROTTILE_Y + tly-voffset ) ;
SETLY( voffset-1 ) ;
COMMAND( 0xC0F3 ) ;
}
}
/* -- */
/*
* For GXcopy and GXcopyInverted we could use a smarter
* algorithm here like in ppcTile().
*/
ibm8514CheckQueue( 2 ) ;
PLNWENBL( priv->colorRrop.planemask ) ;
SETFN1( FNCPYRCT, mergexlate[priv->colorRrop.alu] ) ;
for ( ; h ; h -= th, y += th )
{
th = MIN( h, tly ) ;
ibm8514CheckQueue( 1 ) ;
SETLY( th - 1 ) ;
for ( htarget = x, tmp_w = w ; tmp_w ;
tmp_w -= tw, htarget += tlx )
{
/*
* ibm8514Bitblt( merge, ibm8514ALLPLANES, planes,
* ROTTILE_X, ROTTILE_Y,
* htarget, y,
* tw = MIN( tmp_w, tlx ), th ) ;
*/
ibm8514CheckQueue( 6 ) ;
SETX0( ROTTILE_X ) ;
SETY0( ROTTILE_Y ) ;
SETX1( htarget ) ;
SETY1( y ) ;
SETLX( (tw = MIN( tmp_w, tlx )) - 1 ) ;
COMMAND( 0xC0F3 ) ;
}
}
ibm8514CheckQueue( 2 ) ;
PLNWENBL( ibm8514ALLPLANES ) ;
SETFN1( FNCOLOR1, FNREPLACE ) ; /* as expected elsewhere */
}
}
if ( !(--ibm8514cursorSemaphore) && CursorIsSaved )
ibm8514ReplaceCursor() ;
}
/*
* Generic Area Fill.
* this is mainly a modified version of the function ppcFillArea().
* We mostly handle here FillTiled and FillOpaqueStippled.
*/
void
ibm8514AreaFill(pWin, nBox, pBox, pGC)
WindowPtr pWin;
GCPtr pGC;
int nBox;
BoxPtr pBox;
{
void (*FillFunc)();
ppcPrivGC *priv = (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
if (priv->colorRrop.alu == GXnoop || !nBox)
return;
switch (priv->colorRrop.fillStyle)
{
case FillOpaqueStippled:
FillFunc = ibm8514FillRectOpStippled;
break;
case FillStippled:
FillFunc = ibm8514FillRectStippled;
break;
case FillTiled:
switch (priv->colorRrop.alu)
{
case GXset:
case GXclear:
case GXinvert:
FillFunc = ibm8514FillRectSolid;
break;
default:
FillFunc = ibm8514FillRectTiled;
}
break;
case FillSolid:
FillFunc = ibm8514FillRectSolid;
break;
default:
FillFunc = NULL;
}
if (FillFunc)
(*FillFunc)(pWin, nBox, pBox, pGC);
}