home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xibm.zip
/
ppc
/
ppcPushPxl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-07
|
10KB
|
337 lines
/*
* 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.
*
*/
/* ppc PushPixels */
#include "X.h"
#include "misc.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "regionstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "miscstruct.h"
#include "ppc.h"
#include "ppcBitMacs.h"
#include "OScompiler.h"
#include "ibmTrace.h"
extern int mfbGCPrivateIndex;
static void
BitMapMerge( pDst, pSrc, pStp, xOffset, yOffset, srcInvert )
PixmapPtr pDst;
PixmapPtr pSrc ;
PixmapPtr pStp ;
int xOffset, yOffset ; /* Offset To Stipple Tmp bitmap */
int srcInvert ; /* used for opaqueness */
{
register unsigned long int bits ;
register unsigned long int *bitptr ;
register int wordOffset ;
register unsigned long int *pDstPriv =
(unsigned long int *) pDst->devPrivate.ptr ;
unsigned long int *pSrcPriv =
(unsigned long int *) pSrc->devPrivate.ptr ;
register int j ;
register int i ;
register unsigned long int *pStipSrc ;
unsigned long int *pStpPriv = (unsigned long int *) pStp->devPrivate.ptr ;
unsigned long int stipOffset ;
unsigned long int stpWidth = pStp->drawable.width ;
unsigned long int stpPaddedWidth = pStp->devKind >> 2 ;
unsigned long int stpHeight = pStp->drawable.height ;
unsigned long int dstHeight = pDst->drawable.height ;
unsigned long int dstWidth = pDst->devKind >> 2 ;
if ( ( xOffset %= stpWidth ) < 0 )
xOffset += stpWidth ;
if ( ( yOffset %= stpHeight ) < 0 )
yOffset += stpHeight ;
if ( stpWidth > 32 ) {
/* **************************** */
/* Only Works if stpWidth >= 32 */
/* **************************** */
if ( srcInvert )
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
pStipSrc = pStpPriv
+ ( ( ( yOffset + i ) % stpHeight ) * stpPaddedWidth ) ;
for ( j = dstWidth, stipOffset = xOffset ; j-- ; ) {
wordOffset = stipOffset & 0x1F ;
if ( stipOffset <= stpWidth - 32 ) {
bitptr = pStipSrc + ( stipOffset >> 5 ) ;
bits = SCRLEFT( bitptr[0], wordOffset )
| SCRRIGHT( bitptr[1],
( 32 - wordOffset )) ;
}
else { /* stipOffset > stpWidth - 32 */
bits = SCRLEFT(
pStipSrc[ stipOffset >> 5 ],
wordOffset )
| SCRRIGHT( pStipSrc[0],
( 32 - wordOffset )) ;
stipOffset -= stpWidth ;
}
*pDstPriv++ = *pSrcPriv++ & ~ bits ;
}
}
else
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
pStipSrc = pStpPriv
+ ( ( ( yOffset + i ) % stpHeight ) * stpPaddedWidth ) ;
for ( j = dstWidth, stipOffset = xOffset ; j-- ; ) {
wordOffset = stipOffset & 0x1F ;
if ( stipOffset <= stpWidth - 32 ) {
bitptr = pStipSrc + ( stipOffset >> 5 ) ;
bits = SCRLEFT( bitptr[0], wordOffset )
| SCRRIGHT( bitptr[1],
( 32 - wordOffset ) ) ;
}
else { /* stipOffset > stpWidth - 32 */
bits = SCRLEFT(
pStipSrc[ stipOffset >> 5 ],
wordOffset )
| SCRRIGHT( pStipSrc[0],
( 32 - wordOffset ) ) ;
stipOffset -= stpWidth ;
}
*pDstPriv++ = *pSrcPriv++ & bits ;
}
}
}
else { /* stpWidth <= 32 */
for ( i = stpWidth ; i < 32 ; i <<= 1 ) ; /* Test For A Power Of 2 */
if ( i == 32 ) { /* Best Case - Started w/ Power Of 2 */
if (srcInvert) {
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
/* Pad Out The Bit Mask To A Full Word */
for ( j = stpWidth ; j != 32 ; j <<= 1 )
bits |= SCRRIGHT( bits, j ) ;
/* If Needed Rotate The Mask */
if ( xOffset )
bits = SCRLEFT( bits, xOffset )
| SCRRIGHT( bits, 32 - xOffset ) ;
/* For Each Word In The Line */
for ( j = dstWidth ; j-- ; )
*pDstPriv++ = *pSrcPriv++ & ~bits ;
}
} else {
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
/* Pad Out The Bit Mask To A Full Word */
for ( j = stpWidth ; j != 32 ; j <<= 1 )
bits |= SCRRIGHT( bits, j ) ;
/* If Needed Rotate The Mask */
if ( xOffset )
bits = SCRLEFT( bits, xOffset )
| SCRRIGHT( bits, 32 - xOffset ) ;
/* For Each Word In The Line */
for ( j = dstWidth ; j-- ; )
*pDstPriv++ = *pSrcPriv++ & bits ;
}
}
} else { /* Case - Didn't Start w/ Power Of 2 */
int goalWidth = i >> 1 ;
if (srcInvert) {
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
/* Pad Out The Bit Mask To A Full Word */
for ( j = stpWidth ; j <= goalWidth ; j <<= 1 )
bits |= SCRRIGHT( bits, j ) ;
/* If Needed Rotate The Mask */
if ( xOffset )
bits = ~(SCRLEFT( bits, xOffset )
| SCRRIGHT( bits, goalWidth - xOffset)) ;
/* For Each Word In The Line */
for ( j = dstWidth ; j-- ; ) {
*pDstPriv++ = *pSrcPriv++ & bits ;
bits = ~(SCRLEFT( bits, 32 - goalWidth )
| SCRRIGHT( bits,
( goalWidth << 1 ) - 32 )) ;
}
}
} else {
for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
/* Pad Out The Bit Mask To A Full Word */
for ( j = stpWidth ; j <= goalWidth ; j <<= 1 )
bits |= SCRRIGHT( bits, j ) ;
/* If Needed Rotate The Mask */
if ( xOffset )
bits = SCRLEFT( bits, xOffset )
| SCRRIGHT( bits, goalWidth - xOffset ) ;
/* For Each Word In The Line */
for ( j = dstWidth ; j-- ; ) {
*pDstPriv++ = *pSrcPriv++ & bits ;
bits = SCRLEFT( bits, 32 - goalWidth )
| SCRRIGHT( bits,
( goalWidth << 1 ) - 32 ) ;
}
}
}
}
}
return ;
}
/* Note: pushPixels operates with the current Fill Style
thus the ppc's colorRrop is initially valid.
*/
void
ppcPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg )
GCPtr pGC ;
PixmapPtr pBitMap ;
DrawablePtr pDrawable ;
int dx, dy, xOrg, yOrg ;
{
ppcPrivGC *gcPriv = (ppcPrivGC *) ( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
ScreenPtr pScrn ;
ppcScrnPriv *scrPriv ;
RegionPtr prgnDst ;
int alu ;
int fillStyle ;
int xSrc, ySrc ;
BoxPtr pbox ;
unsigned int nbox ;
if ( ( pDrawable->type != DRAWABLE_WINDOW )
|| ( fillStyle = gcPriv->colorRrop.fillStyle ) == FillTiled ) {
miPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg ) ;
return ;
}
pScrn = (ScreenPtr) pDrawable->pScreen ;
scrPriv = (ppcScrnPriv *) ( pScrn->devPrivate ) ;
/* Note: pushPixels operates with the current Fill Style
thus the ppc's colorRrop is initially valid. */
if ( ( alu = gcPriv->colorRrop.alu ) == GXnoop )
return ;
/* Find The Actual Regions To Fill
* by intersecting the destination's clip-region with
* the box defined by our arguments.
*/
{
BoxRec dstBox ;
dstBox.x2 = ( dstBox.x1 = xOrg ) + dx ;
dstBox.y2 = ( dstBox.y1 = yOrg ) + dy ;
prgnDst = (* pScrn->RegionCreate )( &dstBox,
REGION_NUM_RECTS(gcPriv->pCompositeClip));
(* pScrn->Intersect)( prgnDst, prgnDst, gcPriv->pCompositeClip ) ;
if ( !( nbox = REGION_NUM_RECTS(prgnDst))) {
(* pScrn->RegionDestroy)( prgnDst ) ;
return;
}
pbox = REGION_RECTS(prgnDst);
}
/* ASSUME ( pDrawable->type == DRAWABLE_WINDOW ) */
xSrc = pGC->patOrg.x + pDrawable->x ;
ySrc = pGC->patOrg.y + pDrawable->y ;
{ /* Begin Sub-Block */
PixmapPtr ptmpBitmap = (PixmapPtr) 0 ;
/* Temp bitmap Make Sure It's Zero'ed Here */
int BitmapIsCopy = FALSE ;
void (*FillFunc)() = scrPriv->stipFill ;
unsigned long int fg = gcPriv->colorRrop.fgPixel ;
unsigned long int bg = gcPriv->colorRrop.bgPixel ;
unsigned long int pm = gcPriv->colorRrop.planemask ;
/* Now Do The Needed Fill */
switch ( fillStyle ) {
case FillOpaqueStippled : { /* Create two (2) Tmp stipples */
/* Create The Scratch Bitmap */
ptmpBitmap = (* pScrn->CreatePixmap)( pScrn,
pBitMap->drawable.width,
pBitMap->drawable.height, 1 ) ;
/* Now take the logical "AND-Not" of the pBitmap argument
* and the GC's stipple */
BitMapMerge( ptmpBitmap, pBitMap, pGC->stipple,
( xOrg - xSrc ), ( yOrg - ySrc ), TRUE ) ;
for ( nbox = REGION_NUM_RECTS(prgnDst), pbox = REGION_RECTS(prgnDst);
nbox-- ;
pbox++ ) {
(* FillFunc)( ptmpBitmap, bg, alu, pm,
pbox->x1,
pbox->y1,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1,
xOrg, yOrg ) ;
}
} /* Now Fall-Though To Do Foreground */
case FillStippled : /* Create Tmp stipple from pBitmap AND stipple */
if ( !ptmpBitmap ) {
ptmpBitmap = (* pScrn->CreatePixmap)( pScrn,
pBitMap->drawable.width,
pBitMap->drawable.height, 1 ) ;
}
/* Now take the logical "AND" of the GC's stipple
* and the pBitmap argument */
BitMapMerge( ptmpBitmap, pBitMap, pGC->stipple,
( xOrg - xSrc ), ( yOrg - ySrc ), FALSE ) ;
/* Now Fall-Though To REALLY Do Foreground */
case FillSolid : /* Easiest case -- Just Stipple it in ! */
if ( !ptmpBitmap ) {
ptmpBitmap = pBitMap ;
BitmapIsCopy = TRUE ;
}
for ( nbox = REGION_NUM_RECTS(prgnDst), pbox = REGION_RECTS(prgnDst);
nbox-- ;
pbox++ ) {
(* FillFunc)( ptmpBitmap, fg, alu, pm,
pbox->x1,
pbox->y1,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1,
xOrg, yOrg ) ;
}
if ( BitmapIsCopy == FALSE )
(* pScrn->DestroyPixmap)( ptmpBitmap ) ;
break ;
case FillTiled : /* Hardest case */
/* Not Yet Implimented Here -- Calls "mi" above */
break ;
default :
ErrorF( "ppcPushPixels: Unknown fill Style\n" ) ;
break ;
}
} /* End Sub-Block */
(* pScrn->RegionDestroy)( prgnDst ) ;
return ;
}