diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:54 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:54 +0000 |
commit | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (patch) | |
tree | 82355105e93cdac89ef7d987424351c77545faf0 /cfb | |
parent | cb6ef07bf01e72d1a6e6e83ceb7f76d6534da941 (diff) |
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'cfb')
45 files changed, 19827 insertions, 0 deletions
diff --git a/cfb/cfb.h b/cfb/cfb.h new file mode 100644 index 000000000..f8b48f66a --- /dev/null +++ b/cfb/cfb.h @@ -0,0 +1,1494 @@ +/* $Xorg: cfb.h,v 1.3 2000/08/17 19:48:12 cpqbld Exp $ */ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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 "pixmap.h" +#include "region.h" +#include "gc.h" +#include "colormap.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mfb.h" +#undef PixelType + +#include "cfbmap.h" + +/* + private filed of pixmap + pixmap.devPrivate = (unsigned int *)pointer_to_bits + pixmap.devKind = width_of_pixmap_in_bytes +*/ + +extern int cfbGCPrivateIndex; +extern int cfbWindowPrivateIndex; + +/* private field of GC */ +typedef struct { + unsigned char rop; /* special case rop values */ + /* next two values unused in cfb, included for compatibility with mfb */ + unsigned char ropOpStip; /* rop for opaque stipple */ + /* this value is ropFillArea in mfb, usurped for cfb */ + unsigned char oneRect; /* drawable has one clip rect */ + unsigned fExpose:1; /* callexposure handling ? */ + unsigned freeCompClip:1; + PixmapPtr pRotatedPixmap; + RegionPtr pCompositeClip; /* FREE_CC or REPLACE_CC */ + unsigned long xor, and; /* reduced rop values */ + } cfbPrivGC; + +typedef cfbPrivGC *cfbPrivGCPtr; + +#define cfbGetGCPrivate(pGC) ((cfbPrivGCPtr)\ + (pGC)->devPrivates[cfbGCPrivateIndex].ptr) + +#define cfbGetCompositeClip(pGC) (((cfbPrivGCPtr)\ + (pGC)->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip) + +/* way to carry RROP info around */ +typedef struct { + unsigned char rop; + unsigned long xor, and; +} cfbRRopRec, *cfbRRopPtr; + +/* private field of window */ +typedef struct { + unsigned char fastBorder; /* non-zero if border is 32 bits wide */ + unsigned char fastBackground; + unsigned short unused; /* pad for alignment with Sun compiler */ + DDXPointRec oldRotate; + PixmapPtr pRotatedBackground; + PixmapPtr pRotatedBorder; + } cfbPrivWin; + +#define cfbGetWindowPrivate(_pWin) ((cfbPrivWin *)\ + (_pWin)->devPrivates[cfbWindowPrivateIndex].ptr) + + +/* cfb8bit.c */ + +extern int cfbSetStipple( +#if NeedFunctionPrototypes + int /*alu*/, + unsigned long /*fg*/, + unsigned long /*planemask*/ +#endif +); + +extern int cfbSetOpaqueStipple( +#if NeedFunctionPrototypes + int /*alu*/, + unsigned long /*fg*/, + unsigned long /*bg*/, + unsigned long /*planemask*/ +#endif +); + +extern int cfbComputeClipMasks32( +#if NeedFunctionPrototypes + BoxPtr /*pBox*/, + int /*numRects*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + CARD32 * /*clips*/ +#endif +); +/* cfb8cppl.c */ + +extern void cfbCopyImagePlane( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + int /*rop*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbCopyPlane8to1( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + int /*rop*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/, + unsigned long /*bitPlane*/ +#endif +); +/* cfb8lineCO.c */ + +extern int cfb8LineSS1RectCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/, + DDXPointPtr /*pptInitOrig*/, + int * /*x1p*/, + int * /*y1p*/, + int * /*x2p*/, + int * /*y2p*/ +#endif +); + +extern void cfb8LineSS1Rect( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +#endif +); + +extern void cfb8ClippedLineCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x1*/, + int /*y1*/, + int /*x2*/, + int /*y2*/, + BoxPtr /*boxp*/, + Bool /*shorten*/ +#endif +); +/* cfb8lineCP.c */ + +extern int cfb8LineSS1RectPreviousCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/, + DDXPointPtr /*pptInitOrig*/, + int * /*x1p*/, + int * /*y1p*/, + int * /*x2p*/, + int * /*y2p*/ + +#endif +); +/* cfb8lineG.c */ + +extern int cfb8LineSS1RectGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/, + DDXPointPtr /*pptInitOrig*/, + int * /*x1p*/, + int * /*y1p*/, + int * /*x2p*/, + int * /*y2p*/ +#endif +); + +extern void cfb8ClippedLineGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x1*/, + int /*y1*/, + int /*x2*/, + int /*y2*/, + BoxPtr /*boxp*/, + Bool /*shorten*/ +#endif +); +/* cfb8lineX.c */ + +extern int cfb8LineSS1RectXor( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/, + DDXPointPtr /*pptInitOrig*/, + int * /*x1p*/, + int * /*y1p*/, + int * /*x2p*/, + int * /*y2p*/ +#endif +); + +extern void cfb8ClippedLineXor( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x1*/, + int /*y1*/, + int /*x2*/, + int /*y2*/, + BoxPtr /*boxp*/, + Bool /*shorten*/ +#endif +); +/* cfb8segC.c */ + +extern int cfb8SegmentSS1RectCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegInit*/ +#endif +); +/* cfb8segCS.c */ + +extern int cfb8SegmentSS1RectShiftCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegInit*/ +#endif +); + +extern void cfb8SegmentSS1Rect( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegInit*/ +#endif +); +/* cfb8segG.c */ + +extern int cfb8SegmentSS1RectGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegInit*/ +#endif +); +/* cfbsegX.c */ + +extern int cfb8SegmentSS1RectXor( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegInit*/ +#endif +); +/* cfballpriv.c */ + +extern Bool cfbAllocatePrivates( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int * /*window_index*/, + int * /*gc_index*/ +#endif +); +/* cfbbitblt.c */ + +extern RegionPtr cfbBitBlt( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr/*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + void (* /*doBitBlt*/)(), + unsigned long /*bitPlane*/ +#endif +); + +extern void cfbDoBitblt( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); + +extern RegionPtr cfbCopyArea( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr/*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/ +#endif +); + +extern void cfbCopyPlane1to8( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + int /*rop*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/, + unsigned long /*bitPlane*/ +#endif +); + +extern RegionPtr cfbCopyPlane( +#if NeedFunctionPrototypes + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*bitPlane*/ +#endif +); +/* cfbbltC.c */ + +extern void cfbDoBitbltCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* cfbbltG.c */ + +extern void cfbDoBitbltGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* cfbbltO.c */ + +extern void cfbDoBitbltOr( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* cfbbltX.c */ + +extern void cfbDoBitbltXor( +#if NeedFunctionPrototypes + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + int /*alu*/, + RegionPtr /*prgnDst*/, + DDXPointPtr /*pptSrc*/, + unsigned long /*planemask*/ +#endif +); +/* cfbbres.c */ + +extern void cfbBresS( +#if NeedFunctionPrototypes + int /*rop*/, + unsigned long /*and*/, + unsigned long /*xor*/, + unsigned long * /*addrl*/, + int /*nlwidth*/, + int /*signdx*/, + int /*signdy*/, + int /*axis*/, + int /*x1*/, + int /*y1*/, + int /*e*/, + int /*e1*/, + int /*e2*/, + int /*len*/ +#endif +); +/* cfbbresd.c */ + +extern void cfbBresD( +#if NeedFunctionPrototypes + cfbRRopPtr /*rrops*/, + int * /*pdashIndex*/, + unsigned char * /*pDash*/, + int /*numInDashList*/, + int * /*pdashOffset*/, + int /*isDoubleDash*/, + unsigned long * /*addrl*/, + int /*nlwidth*/, + int /*signdx*/, + int /*signdy*/, + int /*axis*/, + int /*x1*/, + int /*y1*/, + int /*e*/, + int /*e1*/, + int /*e2*/, + int /*len*/ +#endif +); +/* cfbbstore.c */ + +extern void cfbSaveAreas( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/, + RegionPtr /*prgnSave*/, + int /*xorg*/, + int /*yorg*/, + WindowPtr /*pWin*/ +#endif +); + +extern void cfbRestoreAreas( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/, + RegionPtr /*prgnRestore*/, + int /*xorg*/, + int /*yorg*/, + WindowPtr /*pWin*/ +#endif +); +/* cfbcmap.c */ + +extern int cfbListInstalledColormaps( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + Colormap * /*pmaps*/ +#endif +); + +extern void cfbInstallColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern void cfbUninstallColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern void cfbResolveColor( +#if NeedFunctionPrototypes + unsigned short * /*pred*/, + unsigned short * /*pgreen*/, + unsigned short * /*pblue*/, + VisualPtr /*pVisual*/ +#endif +); + +extern Bool cfbInitializeColormap( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/ +#endif +); + +extern int cfbExpandDirectColors( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + int /*ndef*/, + xColorItem * /*indefs*/, + xColorItem * /*outdefs*/ +#endif +); + +extern Bool cfbCreateDefColormap( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/ +#endif +); + +extern Bool cfbSetVisualTypes( +#if NeedFunctionPrototypes + int /*depth*/, + int /*visuals*/, + int /*bitsPerRGB*/ +#endif +); + +extern Bool cfbInitVisuals( +#if NeedFunctionPrototypes + VisualPtr * /*visualp*/, + DepthPtr * /*depthp*/, + int * /*nvisualp*/, + int * /*ndepthp*/, + int * /*rootDepthp*/, + VisualID * /*defaultVisp*/, + unsigned long /*sizes*/, + int /*bitsPerRGB*/ +#endif +); +/* cfbfillarcC.c */ + +extern void cfbPolyFillArcSolidCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); +/* cfbfillarcG.c */ + +extern void cfbPolyFillArcSolidGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); +/* cfbfillrct.c */ + +extern void cfbFillBoxTileOdd( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*n*/, + BoxPtr /*rects*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/ +#endif +); + +extern void cfbFillRectTileOdd( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbPolyFillRect( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nrectFill*/, + xRectangle * /*prectInit*/ +#endif +); +/* cfbfillsp.c */ + +extern void cfbUnnaturalTileFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void cfbUnnaturalStippleFS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void cfb8Stipple32FS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); + +extern void cfb8OpaqueStipple32FS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbgc.c */ + +extern GCOpsPtr cfbMatchCommon( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + cfbPrivGCPtr /*devPriv*/ +#endif +); + +extern Bool cfbCreateGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/ +#endif +); + +extern void cfbValidateGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + unsigned long /*changes*/, + DrawablePtr /*pDrawable*/ +#endif +); + +/* cfbgetsp.c */ + +extern void cfbGetSpans( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*wMax*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + int /*nspans*/, + char * /*pdstStart*/ +#endif +); +/* cfbglblt8.c */ + +extern void cfbPolyGlyphBlt8( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* cfbglrop8.c */ + +extern void cfbPolyGlyphRop8( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* cfbhrzvert.c */ + +extern int cfbHorzS( +#if NeedFunctionPrototypes + int /*rop*/, + unsigned long /*and*/, + unsigned long /*xor*/, + unsigned long * /*addrl*/, + int /*nlwidth*/, + int /*x1*/, + int /*y1*/, + int /*len*/ +#endif +); + +extern int cfbVertS( +#if NeedFunctionPrototypes + int /*rop*/, + unsigned long /*and*/, + unsigned long /*xor*/, + unsigned long * /*addrl*/, + int /*nlwidth*/, + int /*x1*/, + int /*y1*/, + int /*len*/ +#endif +); +/* cfbigblt8.c */ + +extern void cfbImageGlyphBlt8( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* cfbimage.c */ + +extern void cfbPutImage( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*depth*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*leftPad*/, + int /*format*/, + char * /*pImage*/ +#endif +); + +extern void cfbGetImage( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*sx*/, + int /*sy*/, + int /*w*/, + int /*h*/, + unsigned int /*format*/, + unsigned long /*planeMask*/, + char * /*pdstLine*/ +#endif +); +/* cfbline.c */ + +extern void cfbLineSS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +#endif +); + +extern void cfbLineSD( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +#endif +); +/* cfbmskbits.c */ +/* cfbpixmap.c */ + +extern PixmapPtr cfbCreatePixmap( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int /*width*/, + int /*height*/, + int /*depth*/ +#endif +); + +extern Bool cfbDestroyPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +extern PixmapPtr cfbCopyPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pSrc*/ +#endif +); + +extern void cfbPadPixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +extern void cfbXRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPix*/, + int /*rw*/ +#endif +); + +extern void cfbYRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*pPix*/, + int /*rh*/ +#endif +); + +extern void cfbCopyRotatePixmap( +#if NeedFunctionPrototypes + PixmapPtr /*psrcPix*/, + PixmapPtr * /*ppdstPix*/, + int /*xrot*/, + int /*yrot*/ +#endif +); +/* cfbply1rctC.c */ + +extern void cfbFillPoly1RectCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*shape*/, + int /*mode*/, + int /*count*/, + DDXPointPtr /*ptsIn*/ +#endif +); +/* cfbply1rctG.c */ + +extern void cfbFillPoly1RectGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*shape*/, + int /*mode*/, + int /*count*/, + DDXPointPtr /*ptsIn*/ +#endif +); +/* cfbpntwin.c */ + +extern void cfbPaintWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + RegionPtr /*pRegion*/, + int /*what*/ +#endif +); + +extern void cfbFillBoxSolid( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + unsigned long /*pixel*/ +#endif +); + +extern void cfbFillBoxTile32( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + PixmapPtr /*tile*/ +#endif +); +/* cfbpolypnt.c */ + +extern void cfbPolyPoint( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + xPoint * /*pptInit*/ +#endif +); +/* cfbpush8.c */ + +extern void cfbPushPixels8( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + PixmapPtr /*pBitmap*/, + DrawablePtr /*pDrawable*/, + int /*dx*/, + int /*dy*/, + int /*xOrg*/, + int /*yOrg*/ +#endif +); +/* cfbrctstp8.c */ + +extern void cfb8FillRectOpaqueStippled32( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfb8FillRectTransparentStippled32( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfb8FillRectStippledUnnatural( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); +/* cfbrrop.c */ + +extern int cfbReduceRasterOp( +#if NeedFunctionPrototypes + int /*rop*/, + unsigned long /*fg*/, + unsigned long /*pm*/, + unsigned long * /*andp*/, + unsigned long * /*xorp*/ +#endif +); +/* cfbscrinit.c */ + +extern Bool cfbCloseScreen( +#if NeedFunctionPrototypes + int /*index*/, + ScreenPtr /*pScreen*/ +#endif +); + +extern Bool cfbSetupScreen( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + pointer /*pbits*/, + int /*xsize*/, + int /*ysize*/, + int /*dpix*/, + int /*dpiy*/, + int /*width*/ +#endif +); + +extern int cfbFinishScreenInit( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + pointer /*pbits*/, + int /*xsize*/, + int /*ysize*/, + int /*dpix*/, + int /*dpiy*/, + int /*width*/ +#endif +); + +extern Bool cfbScreenInit( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + pointer /*pbits*/, + int /*xsize*/, + int /*ysize*/, + int /*dpix*/, + int /*dpiy*/, + int /*width*/ +#endif +); +/* cfbseg.c */ + +extern void cfbSegmentSS( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSeg*/ +#endif +); + +extern void cfbSegmentSD( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSeg*/ +#endif +); +/* cfbsetsp.c */ + +extern int cfbSetScanline( +#if NeedFunctionPrototypes + int /*y*/, + int /*xOrigin*/, + int /*xStart*/, + int /*xEnd*/, + unsigned int * /*psrc*/, + int /*alu*/, + int * /*pdstBase*/, + int /*widthDst*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbSetSpans( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + char * /*psrc*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + int /*nspans*/, + int /*fSorted*/ +#endif +); +/* cfbsolidC.c */ + +extern void cfbFillRectSolidCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbSolidSpansCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbsolidG.c */ + +extern void cfbFillRectSolidGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbSolidSpansGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbsolidX.c */ + +extern void cfbFillRectSolidXor( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbSolidSpansXor( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbteblt8.c */ + +extern void cfbTEGlyphBlt8( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*xInit*/, + int /*yInit*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* cfbtegblt.c */ + +extern void cfbTEGlyphBlt( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr/*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +#endif +); +/* cfbtile32C.c */ + +extern void cfbFillRectTile32Copy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbTile32FSCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbtile32G.c */ + +extern void cfbFillRectTile32General( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nBox*/, + BoxPtr /*pBox*/ +#endif +); + +extern void cfbTile32FSGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +#endif +); +/* cfbtileoddC.c */ + +extern void cfbFillBoxTileOddCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillSpanTileOddCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*n*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillBoxTile32sCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillSpanTile32sCopy( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*n*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); +/* cfbtileoddG.c */ + +extern void cfbFillBoxTileOddGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillSpanTileOddGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*n*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillBoxTile32sGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*nBox*/, + BoxPtr /*pBox*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); + +extern void cfbFillSpanTile32sGeneral( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + int /*n*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + PixmapPtr /*tile*/, + int /*xrot*/, + int /*yrot*/, + int /*alu*/, + unsigned long /*planemask*/ +#endif +); +/* cfbwindow.c */ + +extern Bool cfbCreateWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/ +#endif +); + +extern Bool cfbDestroyWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/ +#endif +); + +extern Bool cfbMapWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWindow*/ +#endif +); + +extern Bool cfbPositionWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/ +#endif +); + +extern Bool cfbUnmapWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWindow*/ +#endif +); + +extern void cfbCopyWindow( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + DDXPointRec /*ptOldOrg*/, + RegionPtr /*prgnSrc*/ +#endif +); + +extern Bool cfbChangeWindowAttributes( +#if NeedFunctionPrototypes + WindowPtr /*pWin*/, + unsigned long /*mask*/ +#endif +); +/* cfbzerarcC.c */ + +extern void cfbZeroPolyArcSS8Copy( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); +/* cfbzerarcG.c */ + +extern void cfbZeroPolyArcSS8General( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); +/* cfbzerarcX.c */ + +extern void cfbZeroPolyArcSS8Xor( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +#endif +); + +/* + * This is the only completely portable way to + * compute this info + */ + +#define BitsPerPixel(d) (\ + (1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ + (PixmapWidthPaddingInfo[d].padRoundUp+1)) + +/* Common macros for extracting drawing information */ + +#if !defined(SINGLEDEPTH) && PSZ != 8 || defined(FORCE_SEPARATE_PRIVATE) + +#define CFB_NEED_SCREEN_PRIVATE + +extern int cfbScreenPrivateIndex; +#define cfbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivates[cfbScreenPrivateIndex].ptr) +#else +#define cfbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate) +#endif + +#ifdef PIXMAP_PER_WINDOW +#define cfbGetWindowPixmap(d) ((PixmapPtr) ((WindowPtr) d)->devPrivates[frameWindowPrivateIndex].ptr) +#else +#define cfbGetWindowPixmap(d) cfbGetScreenPixmap((d)->pScreen) +#endif + +#define cfbGetTypedWidth(pDrawable,wtype) (\ + (((pDrawable)->type != DRAWABLE_PIXMAP) ? \ + (int) (cfbGetWindowPixmap(pDrawable)->devKind) : \ + (int)(((PixmapPtr)pDrawable)->devKind)) / sizeof (wtype)) + +#define cfbGetByteWidth(pDrawable) cfbGetTypedWidth(pDrawable, unsigned char) + +#define cfbGetPixelWidth(pDrawable) cfbGetTypedWidth(pDrawable, PixelType) + +#define cfbGetLongWidth(pDrawable) cfbGetTypedWidth(pDrawable, unsigned long) + +#define cfbGetTypedWidthAndPointer(pDrawable, width, pointer, wtype, ptype) {\ + PixmapPtr _pPix; \ + if ((pDrawable)->type != DRAWABLE_PIXMAP) \ + _pPix = cfbGetWindowPixmap(pDrawable); \ + else \ + _pPix = (PixmapPtr) (pDrawable); \ + (pointer) = (ptype *) _pPix->devPrivate.ptr; \ + (width) = ((int) _pPix->devKind) / sizeof (wtype); \ +} + +#define cfbGetByteWidthAndPointer(pDrawable, width, pointer) \ + cfbGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned char, unsigned char) + +#define cfbGetLongWidthAndPointer(pDrawable, width, pointer) \ + cfbGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned long, unsigned long) + +#define cfbGetPixelWidthAndPointer(pDrawable, width, pointer) \ + cfbGetTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType) + +#define cfbGetWindowTypedWidthAndPointer(pWin, width, pointer, wtype, ptype) {\ + PixmapPtr _pPix = cfbGetWindowPixmap((DrawablePtr) (pWin)); \ + (pointer) = (ptype *) _pPix->devPrivate.ptr; \ + (width) = ((int) _pPix->devKind) / sizeof (wtype); \ +} + +#define cfbGetWindowLongWidthAndPointer(pWin, width, pointer) \ + cfbGetWindowTypedWidthAndPointer(pWin, width, pointer, unsigned long, unsigned long) + +#define cfbGetWindowByteWidthAndPointer(pWin, width, pointer) \ + cfbGetWindowTypedWidthAndPointer(pWin, width, pointer, unsigned char, unsigned char) + +#define cfbGetWindowPixelWidthAndPointer(pDrawable, width, pointer) \ + cfbGetWindowTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType) + +/* Macros which handle a coordinate in a single register */ + +/* Most compilers will convert divide by 65536 into a shift, if signed + * shifts exist. If your machine does arithmetic shifts and your compiler + * can't get it right, add to this line. + */ + +/* mips compiler - what a joke - it CSEs the 65536 constant into a reg + * forcing as to use div instead of shift. Let's be explicit. + */ + +#if defined(mips) || defined(sparc) || defined(__alpha) +#define GetHighWord(x) (((int) (x)) >> 16) +#else +#define GetHighWord(x) (((int) (x)) / 65536) +#endif + +#if IMAGE_BYTE_ORDER == MSBFirst +#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i)))) +#define coordToInt(x,y) (((x) << 16) | (y)) +#define intToX(i) (GetHighWord(i)) +#define intToY(i) ((int) ((short) i)) +#else +#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i))) +#define coordToInt(x,y) (((y) << 16) | (x)) +#define intToX(i) ((int) ((short) (i))) +#define intToY(i) (GetHighWord(i)) +#endif diff --git a/cfb/cfb8bit.c b/cfb/cfb8bit.c new file mode 100644 index 000000000..080970e70 --- /dev/null +++ b/cfb/cfb8bit.c @@ -0,0 +1,466 @@ +/* $Xorg: cfb8bit.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ +/* + +Copyright 1989, 1994, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* + * cfb8bit.c + * + * 8 bit color frame buffer utility routines + */ + + +#if PSZ == 8 + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +PixelGroup cfb8StippleMasks[NUM_MASKS] = { +#if NUM_MASKS == 16 + 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, + 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, + 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, + 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff +#else /* NUM_MASKS == 256 */ + 0x0000000000000000, 0x00000000000000ff, + 0x000000000000ff00, 0x000000000000ffff, + 0x0000000000ff0000, 0x0000000000ff00ff, + 0x0000000000ffff00, 0x0000000000ffffff, + 0x00000000ff000000, 0x00000000ff0000ff, + 0x00000000ff00ff00, 0x00000000ff00ffff, + 0x00000000ffff0000, 0x00000000ffff00ff, + 0x00000000ffffff00, 0x00000000ffffffff, + 0x000000ff00000000, 0x000000ff000000ff, + 0x000000ff0000ff00, 0x000000ff0000ffff, + 0x000000ff00ff0000, 0x000000ff00ff00ff, + 0x000000ff00ffff00, 0x000000ff00ffffff, + 0x000000ffff000000, 0x000000ffff0000ff, + 0x000000ffff00ff00, 0x000000ffff00ffff, + 0x000000ffffff0000, 0x000000ffffff00ff, + 0x000000ffffffff00, 0x000000ffffffffff, + 0x0000ff0000000000, 0x0000ff00000000ff, + 0x0000ff000000ff00, 0x0000ff000000ffff, + 0x0000ff0000ff0000, 0x0000ff0000ff00ff, + 0x0000ff0000ffff00, 0x0000ff0000ffffff, + 0x0000ff00ff000000, 0x0000ff00ff0000ff, + 0x0000ff00ff00ff00, 0x0000ff00ff00ffff, + 0x0000ff00ffff0000, 0x0000ff00ffff00ff, + 0x0000ff00ffffff00, 0x0000ff00ffffffff, + 0x0000ffff00000000, 0x0000ffff000000ff, + 0x0000ffff0000ff00, 0x0000ffff0000ffff, + 0x0000ffff00ff0000, 0x0000ffff00ff00ff, + 0x0000ffff00ffff00, 0x0000ffff00ffffff, + 0x0000ffffff000000, 0x0000ffffff0000ff, + 0x0000ffffff00ff00, 0x0000ffffff00ffff, + 0x0000ffffffff0000, 0x0000ffffffff00ff, + 0x0000ffffffffff00, 0x0000ffffffffffff, + 0x00ff000000000000, 0x00ff0000000000ff, + 0x00ff00000000ff00, 0x00ff00000000ffff, + 0x00ff000000ff0000, 0x00ff000000ff00ff, + 0x00ff000000ffff00, 0x00ff000000ffffff, + 0x00ff0000ff000000, 0x00ff0000ff0000ff, + 0x00ff0000ff00ff00, 0x00ff0000ff00ffff, + 0x00ff0000ffff0000, 0x00ff0000ffff00ff, + 0x00ff0000ffffff00, 0x00ff0000ffffffff, + 0x00ff00ff00000000, 0x00ff00ff000000ff, + 0x00ff00ff0000ff00, 0x00ff00ff0000ffff, + 0x00ff00ff00ff0000, 0x00ff00ff00ff00ff, + 0x00ff00ff00ffff00, 0x00ff00ff00ffffff, + 0x00ff00ffff000000, 0x00ff00ffff0000ff, + 0x00ff00ffff00ff00, 0x00ff00ffff00ffff, + 0x00ff00ffffff0000, 0x00ff00ffffff00ff, + 0x00ff00ffffffff00, 0x00ff00ffffffffff, + 0x00ffff0000000000, 0x00ffff00000000ff, + 0x00ffff000000ff00, 0x00ffff000000ffff, + 0x00ffff0000ff0000, 0x00ffff0000ff00ff, + 0x00ffff0000ffff00, 0x00ffff0000ffffff, + 0x00ffff00ff000000, 0x00ffff00ff0000ff, + 0x00ffff00ff00ff00, 0x00ffff00ff00ffff, + 0x00ffff00ffff0000, 0x00ffff00ffff00ff, + 0x00ffff00ffffff00, 0x00ffff00ffffffff, + 0x00ffffff00000000, 0x00ffffff000000ff, + 0x00ffffff0000ff00, 0x00ffffff0000ffff, + 0x00ffffff00ff0000, 0x00ffffff00ff00ff, + 0x00ffffff00ffff00, 0x00ffffff00ffffff, + 0x00ffffffff000000, 0x00ffffffff0000ff, + 0x00ffffffff00ff00, 0x00ffffffff00ffff, + 0x00ffffffffff0000, 0x00ffffffffff00ff, + 0x00ffffffffffff00, 0x00ffffffffffffff, + 0xff00000000000000, 0xff000000000000ff, + 0xff0000000000ff00, 0xff0000000000ffff, + 0xff00000000ff0000, 0xff00000000ff00ff, + 0xff00000000ffff00, 0xff00000000ffffff, + 0xff000000ff000000, 0xff000000ff0000ff, + 0xff000000ff00ff00, 0xff000000ff00ffff, + 0xff000000ffff0000, 0xff000000ffff00ff, + 0xff000000ffffff00, 0xff000000ffffffff, + 0xff0000ff00000000, 0xff0000ff000000ff, + 0xff0000ff0000ff00, 0xff0000ff0000ffff, + 0xff0000ff00ff0000, 0xff0000ff00ff00ff, + 0xff0000ff00ffff00, 0xff0000ff00ffffff, + 0xff0000ffff000000, 0xff0000ffff0000ff, + 0xff0000ffff00ff00, 0xff0000ffff00ffff, + 0xff0000ffffff0000, 0xff0000ffffff00ff, + 0xff0000ffffffff00, 0xff0000ffffffffff, + 0xff00ff0000000000, 0xff00ff00000000ff, + 0xff00ff000000ff00, 0xff00ff000000ffff, + 0xff00ff0000ff0000, 0xff00ff0000ff00ff, + 0xff00ff0000ffff00, 0xff00ff0000ffffff, + 0xff00ff00ff000000, 0xff00ff00ff0000ff, + 0xff00ff00ff00ff00, 0xff00ff00ff00ffff, + 0xff00ff00ffff0000, 0xff00ff00ffff00ff, + 0xff00ff00ffffff00, 0xff00ff00ffffffff, + 0xff00ffff00000000, 0xff00ffff000000ff, + 0xff00ffff0000ff00, 0xff00ffff0000ffff, + 0xff00ffff00ff0000, 0xff00ffff00ff00ff, + 0xff00ffff00ffff00, 0xff00ffff00ffffff, + 0xff00ffffff000000, 0xff00ffffff0000ff, + 0xff00ffffff00ff00, 0xff00ffffff00ffff, + 0xff00ffffffff0000, 0xff00ffffffff00ff, + 0xff00ffffffffff00, 0xff00ffffffffffff, + 0xffff000000000000, 0xffff0000000000ff, + 0xffff00000000ff00, 0xffff00000000ffff, + 0xffff000000ff0000, 0xffff000000ff00ff, + 0xffff000000ffff00, 0xffff000000ffffff, + 0xffff0000ff000000, 0xffff0000ff0000ff, + 0xffff0000ff00ff00, 0xffff0000ff00ffff, + 0xffff0000ffff0000, 0xffff0000ffff00ff, + 0xffff0000ffffff00, 0xffff0000ffffffff, + 0xffff00ff00000000, 0xffff00ff000000ff, + 0xffff00ff0000ff00, 0xffff00ff0000ffff, + 0xffff00ff00ff0000, 0xffff00ff00ff00ff, + 0xffff00ff00ffff00, 0xffff00ff00ffffff, + 0xffff00ffff000000, 0xffff00ffff0000ff, + 0xffff00ffff00ff00, 0xffff00ffff00ffff, + 0xffff00ffffff0000, 0xffff00ffffff00ff, + 0xffff00ffffffff00, 0xffff00ffffffffff, + 0xffffff0000000000, 0xffffff00000000ff, + 0xffffff000000ff00, 0xffffff000000ffff, + 0xffffff0000ff0000, 0xffffff0000ff00ff, + 0xffffff0000ffff00, 0xffffff0000ffffff, + 0xffffff00ff000000, 0xffffff00ff0000ff, + 0xffffff00ff00ff00, 0xffffff00ff00ffff, + 0xffffff00ffff0000, 0xffffff00ffff00ff, + 0xffffff00ffffff00, 0xffffff00ffffffff, + 0xffffffff00000000, 0xffffffff000000ff, + 0xffffffff0000ff00, 0xffffffff0000ffff, + 0xffffffff00ff0000, 0xffffffff00ff00ff, + 0xffffffff00ffff00, 0xffffffff00ffffff, + 0xffffffffff000000, 0xffffffffff0000ff, + 0xffffffffff00ff00, 0xffffffffff00ffff, + 0xffffffffffff0000, 0xffffffffffff00ff, + 0xffffffffffffff00, 0xffffffffffffffff +#endif +}; + +int cfb8StippleMode, cfb8StippleAlu, cfb8StippleRRop; +PixelGroup cfb8StippleFg, cfb8StippleBg, cfb8StipplePm; +PixelGroup cfb8StippleAnd[NUM_MASKS], cfb8StippleXor[NUM_MASKS]; + +int +cfb8SetStipple (alu, fg, planemask) +int alu; +unsigned long fg, planemask; +{ + unsigned long and, xor, rrop; + int s; + unsigned long c; + + cfb8StippleMode = FillStippled; + cfb8StippleAlu = alu; + cfb8StippleFg = fg & PMSK; + cfb8StipplePm = planemask & PMSK; + rrop = cfbReduceRasterOp (alu, fg, planemask, &and, &xor); + cfb8StippleRRop = rrop; + /* + * create the appropriate pixel-fill bits for current + * foreground + */ + for (s = 0; s < NUM_MASKS; s++) + { + c = cfb8StippleMasks[s]; + cfb8StippleAnd[s] = and | ~c; + cfb8StippleXor[s] = xor & c; + } + return TRUE; +} + + +int +cfb8SetOpaqueStipple (alu, fg, bg, planemask) +int alu; +unsigned long fg, bg, planemask; +{ + unsigned long andfg, xorfg, andbg, xorbg, rropfg, rropbg; + int s; + unsigned long c; + + cfb8StippleMode = FillOpaqueStippled; + cfb8StippleAlu = alu; + cfb8StippleFg = fg & PMSK; + cfb8StippleBg = bg & PMSK; + cfb8StipplePm = planemask & PMSK; + rropfg = cfbReduceRasterOp (alu, cfb8StippleFg, cfb8StipplePm, &andfg, &xorfg); + rropbg = cfbReduceRasterOp (alu, cfb8StippleBg, cfb8StipplePm, &andbg, &xorbg); + if (rropfg == rropbg) + cfb8StippleRRop = rropfg; + else + cfb8StippleRRop = GXset; + /* + * create the appropriate pixel-fill bits for current + * foreground + */ + for (s = 0; s < NUM_MASKS; s++) + { + c = cfb8StippleMasks[s]; + cfb8StippleAnd[s] = (andfg | ~c) & (andbg | c); + cfb8StippleXor[s] = (xorfg & c) | (xorbg & ~c); + } + return TRUE; +} + +/* + * a grungy little routine. This computes clip masks + * for partial character blts. Returns rgnOUT if the + * entire character is clipped; returns rgnIN if the entire + * character is unclipped; returns rgnPART if a portion of + * the character is visible. Computes clip masks for each + * longword of the character -- and those with the + * contents of the glyph to compute the visible bits. + */ + +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) +PixelGroup cfb8BitLenMasks[PGSZ] = { + 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, + 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff, + 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff, + 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, + 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff, + 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff, + 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f, + 0x0000000f, 0x00000007, 0x00000003, 0x00000001, +}; +#else +PixelGroup cfb8BitLenMasks[PGSZ] = { + 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, + 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, + 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, + 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, + 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, + 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, + 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, + 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, +}; +#endif /* BITMAP_BIT_ORDER */ +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) +PixelGroup cfb8BitLenMasks[PGSZ] = { + 0xffffffffffffffff, 0x7fffffffffffffff, + 0x3fffffffffffffff, 0x1fffffffffffffff, + 0x0fffffffffffffff, 0x07ffffffffffffff, + 0x03ffffffffffffff, 0x01ffffffffffffff, + 0x00ffffffffffffff, 0x007fffffffffffff, + 0x003fffffffffffff, 0x001fffffffffffff, + 0x000fffffffffffff, 0x0007ffffffffffff, + 0x0003ffffffffffff, 0x0001ffffffffffff, + 0x0000ffffffffffff, 0x00007fffffffffff, + 0x00003fffffffffff, 0x00001fffffffffff, + 0x00000fffffffffff, 0x000007ffffffffff, + 0x000003ffffffffff, 0x000001ffffffffff, + 0x000000ffffffffff, 0x0000007fffffffff, + 0x0000003fffffffff, 0x0000001fffffffff, + 0x0000000fffffffff, 0x00000007ffffffff, + 0x00000003ffffffff, 0x00000001ffffffff, + 0x00000000ffffffff, 0x000000007fffffff, + 0x000000003fffffff, 0x000000001fffffff, + 0x000000000fffffff, 0x0000000007ffffff, + 0x0000000003ffffff, 0x0000000001ffffff, + 0x0000000000ffffff, 0x00000000007fffff, + 0x00000000003fffff, 0x00000000001fffff, + 0x00000000000fffff, 0x000000000007ffff, + 0x000000000003ffff, 0x000000000001ffff, + 0x000000000000ffff, 0x0000000000007fff, + 0x0000000000003fff, 0x0000000000001fff, + 0x0000000000000fff, 0x00000000000007ff, + 0x00000000000003ff, 0x00000000000001ff, + 0x00000000000000ff, 0x000000000000007f, + 0x000000000000003f, 0x000000000000001f, + 0x000000000000000f, 0x0000000000000007, + 0x0000000000000003, 0x0000000000000001 +}; +#else +PixelGroup cfb8BitLenMasks[PGSZ] = { + 0xffffffffffffffff, 0xfffffffffffffffe, + 0xfffffffffffffffc, 0xfffffffffffffff8, + 0xfffffffffffffff0, 0xffffffffffffffe0, + 0xffffffffffffffc0, 0xffffffffffffff80, + 0xffffffffffffff00, 0xfffffffffffffe00, + 0xfffffffffffffc00, 0xfffffffffffff800, + 0xfffffffffffff000, 0xffffffffffffe000, + 0xffffffffffffc000, 0xffffffffffff8000, + 0xffffffffffff0000, 0xfffffffffffe0000, + 0xfffffffffffc0000, 0xfffffffffff80000, + 0xfffffffffff00000, 0xffffffffffe00000, + 0xffffffffffc00000, 0xffffffffff800000, + 0xffffffffff000000, 0xfffffffffe000000, + 0xfffffffffc000000, 0xfffffffff8000000, + 0xfffffffff0000000, 0xffffffffe0000000, + 0xffffffffc0000000, 0xffffffff80000000, + 0xffffffff00000000, 0xfffffffe00000000, + 0xfffffffc00000000, 0xfffffff800000000, + 0xfffffff000000000, 0xffffffe000000000, + 0xffffffc000000000, 0xffffff8000000000, + 0xffffff0000000000, 0xfffffe0000000000, + 0xfffffc0000000000, 0xfffff80000000000, + 0xfffff00000000000, 0xffffe00000000000, + 0xffffc00000000000, 0xffff800000000000, + 0xffff000000000000, 0xfffe000000000000, + 0xfffc000000000000, 0xfff8000000000000, + 0xfff0000000000000, 0xffe0000000000000, + 0xffc0000000000000, 0xff80000000000000, + 0xff00000000000000, 0xfe00000000000000, + 0xfc00000000000000, 0xf800000000000000, + 0xf000000000000000, 0xe000000000000000, + 0xc000000000000000, 0x8000000000000000 +}; +#endif /* BITMAP_BIT_ORDER */ +#endif /* PGSZ */ + + + +int +cfb8ComputeClipMasks32 (pBox, numRects, x, y, w, h, clips) + BoxPtr pBox; + int numRects; + int x, y, w, h; + CARD32 *clips; +{ + int yBand, yBandBot; + int ch; + unsigned long clip; + int partIN = FALSE, partOUT = FALSE; + int result; + + if (numRects == 0) + return rgnOUT; + while (numRects && pBox->y2 <= y) + { + --numRects; + ++pBox; + } + if (!numRects || pBox->y1 >= y + h) + return rgnOUT; + yBand = pBox->y1; + while (numRects && pBox->y1 == yBand && pBox->x2 <= x) + { + --numRects; + ++pBox; + } + if (!numRects || pBox->y1 >= y + h) + return rgnOUT; + if (numRects && + x >= pBox->x1 && + x + w <= pBox->x2 && + y >= pBox->y1 && + y + h <= pBox->y2) + { + return rgnIN; + } + ch = 0; + while (numRects && pBox->y1 < y + h) + { + yBand = pBox->y1; + yBandBot = pBox->y2; + while (ch < h && y + ch < yBand) + { + partOUT = TRUE; + clips[ch++] = 0; + } + if (ch >= h) + break; + while (numRects && pBox->y1 == yBand && pBox->x2 <= x) + { + --numRects; + ++pBox; + } + if (!numRects) + break; + clip = 0; + while (numRects && pBox->y1 == yBand && pBox->x1 < x + w) + { + if (x < pBox->x1) + if (pBox->x2 < x + w) + clip |= cfb8BitLenMasks[pBox->x1 - x] & ~cfb8BitLenMasks[pBox->x2 - x]; + else + clip |= cfb8BitLenMasks[pBox->x1 - x]; + else + if (pBox->x2 < x + w) + clip |= ~cfb8BitLenMasks[pBox->x2 - x]; + else + clip = ~0; + --numRects; + ++pBox; + } + if (clip != 0) + partIN = TRUE; + if (clip != ~0) + partOUT = TRUE; + while (ch < h && y + ch < yBandBot) + clips[ch++] = clip; + while (numRects && pBox->y1 == yBand) + { + --numRects; + ++pBox; + } + } + while (ch < h) + { + partOUT = TRUE; + clips[ch++] = 0; + } + result = rgnOUT; + if (partIN) + { + if (partOUT) + result = rgnPART; + else + result = rgnIN; + } + return result; +} + +#endif /* PSZ == 8 */ diff --git a/cfb/cfb8bit.h b/cfb/cfb8bit.h new file mode 100644 index 000000000..23853bf2d --- /dev/null +++ b/cfb/cfb8bit.h @@ -0,0 +1,1196 @@ +/* + * cfb8bit.h + * + * Defines which are only useful to 8 bit color frame buffers + * + * That doesn't seem to be true any more. Some of the macros in here + * are used for depths other than 8. Perhaps the file should be + * renamed. dpw + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* $Xorg: cfb8bit.h,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "servermd.h" + +#if (BITMAP_BIT_ORDER == MSBFirst) +#define GetBitGroup(x) (((PixelGroup) (x)) >> (PGSZ - PGSZB)) +#define NextBitGroup(x) ((x) <<= PGSZB) +#define NextSomeBits(x,n) ((x) <<= (n)) +#else +#define GetBitGroup(x) ((x) & PGSZBMSK) +#define NextBitGroup(x) ((x) >>= PGSZB) +#define NextSomeBits(x,n) ((x) >>= (n)) +#endif + +#define RotBitsLeft(x,k) ((x) = BitLeft (x,k) | \ + BitRight (x, PGSZ-(k))) + +#if defined(__GNUC__) && defined(mc68020) +#undef RotBitsLeft +#define RotBitsLeft(x,k) asm("rol%.l %2,%0" \ + : "=d" (x) \ + : "0" (x), "dI" (k)) +#endif + +#if PSZ == 8 + +#define GetPixelGroup(x) (cfb8StippleXor[GetBitGroup(x)]) +#define RRopPixels(dst,x) (DoRRop(dst,cfb8StippleAnd[x], cfb8StippleXor[x])) +#define RRopPixelGroup(dst,x) (RRopPixels(dst,GetBitGroup(x))) +#define MaskRRopPixels(dst,x,mask) (DoMaskRRop(dst,cfb8StippleAnd[x], cfb8StippleXor[x], mask)) + +#define NUM_MASKS (1<<PPW) /* XXX goes in cfbmskbits.h? */ +extern int cfb8StippleMode, cfb8StippleAlu; +extern PixelGroup cfb8StippleFg, cfb8StippleBg, cfb8StipplePm; +extern PixelGroup cfb8StippleMasks[NUM_MASKS]; +extern PixelGroup cfb8StippleAnd[NUM_MASKS], cfb8StippleXor[NUM_MASKS]; +extern int cfb8StippleRRop; + +#define cfb8PixelMasks cfb8StippleMasks +#define cfb8Pixels cfb8StippleXor + +#define cfb8CheckPixels(fg, bg) \ + (FillOpaqueStippled == cfb8StippleMode && \ + GXcopy == cfb8StippleAlu && \ + ((fg) & PMSK) == cfb8StippleFg && \ + ((bg) & PMSK) == cfb8StippleBg && \ + PMSK == cfb8StipplePm) + +#define cfb8CheckOpaqueStipple(alu,fg,bg,pm) \ + ((FillOpaqueStippled == cfb8StippleMode && \ + (alu) == cfb8StippleAlu && \ + ((fg) & PMSK) == cfb8StippleFg && \ + ((bg) & PMSK) == cfb8StippleBg && \ + ((pm) & PMSK) == cfb8StipplePm) ? 0 : cfb8SetOpaqueStipple(alu,fg,bg,pm)) + +#define cfb8CheckStipple(alu,fg,pm) \ + ((FillStippled == cfb8StippleMode && \ + (alu) == cfb8StippleAlu && \ + ((fg) & PMSK) == cfb8StippleFg && \ + ((pm) & PMSK) == cfb8StipplePm) ? 0 : cfb8SetStipple(alu,fg,pm)) + +#define cfb8SetPixels(fg,bg) cfb8SetOpaqueStipple(GXcopy,fg,bg,PMSK) + +/* + * These macros are shared between the unnatural spans code + * and the unnatural rectangle code. No reasonable person + * would attempt to use them anyplace else. + */ + +#define NextUnnaturalStippleWord \ + if (bitsLeft >= MFB_PPW) \ + { \ + inputBits = *srcTemp++; \ + bitsLeft -= MFB_PPW; \ + partBitsLeft = MFB_PPW; \ + } \ + else \ + { \ + inputBits = 0; \ + if (bitsLeft) \ + inputBits = *srcTemp & ~cfb8BitLenMasks[bitsLeft]; \ + srcTemp = srcStart; \ + partBitsLeft = bitsLeft; \ + bitsLeft = bitsWhole; \ + } + +#define NextUnnaturalStippleBits \ + if (partBitsLeft >= PPW) { \ + bits = GetBitGroup (inputBits); \ + NextBitGroup (inputBits); \ + partBitsLeft -= PPW; \ + } else { \ + bits = GetBitGroup (inputBits); \ + nextPartBits = PPW - partBitsLeft; \ + NextUnnaturalStippleWord \ + if (partBitsLeft < nextPartBits) { \ + if (partBitsLeft) {\ + bits |= BitRight (GetBitGroup (inputBits), \ + PPW - nextPartBits) & PPWMSK;\ + nextPartBits -= partBitsLeft; \ + } \ + NextUnnaturalStippleWord \ + } \ + bits |= BitRight (GetBitGroup (inputBits), \ + PPW - nextPartBits) & PPWMSK; \ + NextSomeBits (inputBits, nextPartBits); \ + partBitsLeft -= nextPartBits; \ + } + +#define NextUnnaturalStippleBitsFast \ + if (partBitsLeft >= PPW) { \ + bits = GetBitGroup(inputBits); \ + NextBitGroup(inputBits); \ + partBitsLeft -= PPW; \ + } else { \ + bits = GetBitGroup (inputBits); \ + nextPartBits = PPW - partBitsLeft; \ + inputBits = *srcTemp++; \ + bits |= BitRight (GetBitGroup (inputBits), \ + partBitsLeft) & PPWMSK; \ + NextSomeBits (inputBits, nextPartBits); \ + partBitsLeft = MFB_PPW - nextPartBits; \ + } + +/* + * WriteBitGroup takes the destination address, a pixel + * value (which must be 8 bits duplicated 4 time with PFILL) + * and the PPW bits to write, which must be in the low order + * bits of the register (probably from GetBitGroup) and writes + * the appropriate locations in memory with the pixel value. This + * is a copy-mode only operation. + */ + +#define RRopBitGroup(dst,bits) \ + { \ + register PixelGroup _bitsTmp = (bits); \ + *(dst) = RRopPixels(*(dst),bits); \ + } + +#define MaskRRopBitGroup(dst,bits,mask) \ + { \ + register PixelGroup _bitsTmp = (bits); \ + *(dst) = MaskRRopPixels(*(dst),bits,mask); \ + } +#endif /* PSZ == 8 */ + +#if !defined(AVOID_MEMORY_READ) && PSZ == 8 + +#define WriteBitGroup(dst,pixel,bits) \ + { \ + register PixelGroup _maskTmp = cfb8PixelMasks[(bits)]; \ + *(dst) = (*(dst) & ~_maskTmp) | ((pixel) & _maskTmp); \ + } + +#define SwitchBitGroup(dst,pixel,bits) \ + { \ + register PixelGroup _maskTmp = cfb8PixelMasks[(bits)]; \ + register PixelGroup _pixTmp = ((pixel) & _maskTmp); \ + _maskTmp = ~_maskTmp; \ + SwitchBitsLoop (*(dst) = (*(dst) & _maskTmp) | _pixTmp;) \ + } + +#else /* AVOID_MEMORY_READ */ + +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) +#define SinglePixel0 3 +#define SinglePixel1 2 +#define SinglePixel2 1 +#define SinglePixel3 0 +#define DoublePixel0 1 +#define DoublePixel1 0 +#else +#define SinglePixel0 0 +#define SinglePixel1 1 +#define SinglePixel2 2 +#define SinglePixel3 3 +#define DoublePixel0 0 +#define DoublePixel1 1 +#endif +#define QuadPixel0 0 +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) +#define SinglePixel0 7 +#define SinglePixel1 6 +#define SinglePixel2 5 +#define SinglePixel3 4 +#define SinglePixel4 3 +#define SinglePixel5 2 +#define SinglePixel6 1 +#define SinglePixel7 0 +#define DoublePixel0 3 +#define DoublePixel1 2 +#define DoublePixel2 1 +#define DoublePixel3 0 +#define QuadPixel0 1 +#define QuadPixel1 0 +#else +#define SinglePixel0 0 +#define SinglePixel1 1 +#define SinglePixel2 2 +#define SinglePixel3 3 +#define SinglePixel4 4 +#define SinglePixel5 5 +#define SinglePixel6 6 +#define SinglePixel7 7 +#define DoublePixel0 0 +#define DoublePixel1 1 +#define DoublePixel2 2 +#define DoublePixel3 3 +#define QuadPixel0 0 +#define QuadPixel1 1 +#endif +#define OctaPixel0 0 +#endif /* PGSZ == 64 */ + +#if PSZ == 8 + +#if PGSZ == 32 +#define WriteBitGroup(dst,pixel,bits) \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + break; \ + case 4: \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 13: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 14: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[0] = (pixel); \ + break; \ + } +#else /* PGSZ == 64 */ +#define WriteBitGroup(dst,pixel,bits) \ + if ( bits == 0xff ) \ + ((PixelGroup *) (dst))[OctaPixel0] = (pixel); \ + else { \ + switch (bits & 0x0f) { \ + case 0: \ + break; \ + case 1: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + break; \ + case 4: \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 13: \ + ((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 14: \ + ((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[QuadPixel0] = (pixel); \ + break; \ + } \ + switch ((bits & 0xf0) >> 4) { \ + case 0: \ + break; \ + case 1: \ + ((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + break; \ + case 2: \ + ((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + break; \ + case 3: \ + ((CARD16 *) (dst))[DoublePixel2] = (pixel); \ + break; \ + case 4: \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 5: \ + ((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 6: \ + ((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 7: \ + ((CARD16 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 8: \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 9: \ + ((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 10: \ + ((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 11: \ + ((CARD16 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 12: \ + ((CARD16 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 13: \ + ((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 14: \ + ((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[QuadPixel1] = (pixel); \ + break; \ + } \ + } +#endif /* PGSZ == 64 */ + +#if PGSZ == 32 +#define SwitchBitGroup(dst,pixel,bits) { \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel);) \ + break; \ + case 2: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel);) \ + break; \ + case 3: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel);) \ + break; \ + case 4: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 5: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 6: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 7: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 8: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 9: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 10: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 11: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 12: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 13: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 14: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 15: \ + SwitchBitsLoop (((CARD32 *) (dst))[0] = (pixel);) \ + break; \ + } \ +} +#else /* PGSZ == 64 */ +#define SwitchBitGroup(dst,pixel,bits) { \ + if ( bits == 0xff ) \ + SwitchBitsLoop (((PixelGroup *) (dst))[OctaPixel0] = (pixel);) \ + else { \ + switch (bits & 0x0f) { \ + case 0: \ + break; \ + case 1: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel);) \ + break; \ + case 2: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel);) \ + break; \ + case 3: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel);)\ + break; \ + case 4: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 5: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 6: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 7: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 8: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 9: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 10: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 11: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 12: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel1] = (pixel);)\ + break; \ + case 13: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel);)\ + break; \ + case 14: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel1] = (pixel);)\ + break; \ + case 15: \ + SwitchBitsLoop (((CARD32 *) (dst))[QuadPixel0] = (pixel);) \ + break; \ + } \ + switch ((bits & 0xf0) >> 4) { \ + case 0: \ + break; \ + case 1: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel4] = (pixel);) \ + break; \ + case 2: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel5] = (pixel);) \ + break; \ + case 3: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel2] = (pixel);)\ + break; \ + case 4: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel6] = (pixel);) \ + break; \ + case 5: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel);) \ + break; \ + case 6: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel);) \ + break; \ + case 7: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel6] = (pixel);) \ + break; \ + case 8: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel7] = (pixel);) \ + break; \ + case 9: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel);) \ + break; \ + case 10: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel);) \ + break; \ + case 11: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD8 *) (dst))[SinglePixel7] = (pixel);) \ + break; \ + case 12: \ + SwitchBitsLoop (((CARD16 *) (dst))[DoublePixel3] = (pixel);)\ + break; \ + case 13: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel3] = (pixel);)\ + break; \ + case 14: \ + SwitchBitsLoop (((CARD8 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD16 *) (dst))[DoublePixel3] = (pixel);)\ + break; \ + case 15: \ + SwitchBitsLoop (((CARD32 *) (dst))[QuadPixel1] = (pixel);) \ + break; \ + } \ + } \ +} +#endif /* PGSZ == 64 */ +#endif /* PSZ == 8 */ + +#if PSZ == 16 + +#if PGSZ == 32 +#define WriteBitGroup(dst,pixel,bits) \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + break; \ + case 4: \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 13: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 14: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + } +#else /* PGSZ == 64 */ +#define WriteBitGroup(dst,pixel,bits) \ + if ( bits == 0xff ) { \ + ((PixelGroup *) (dst))[QuadPixel0] = (pixel); \ + ((PixelGroup *) (dst))[QuadPixel1] = (pixel); \ + } \ + else { \ + switch (bits & 0x0f) { \ + case 0: \ + break; \ + case 1: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + break; \ + case 4: \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 13: \ + ((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 14: \ + ((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel); \ + break; \ + } \ + switch ((bits & 0xf0) >> 4) { \ + case 0: \ + break; \ + case 1: \ + ((CARD16 *) (dst))[SinglePixel4] = (pixel); \ + break; \ + case 2: \ + ((CARD16 *) (dst))[SinglePixel5] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[DoublePixel2] = (pixel); \ + break; \ + case 4: \ + ((CARD16 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 5: \ + ((CARD16 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 6: \ + ((CARD16 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 8: \ + ((CARD16 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 9: \ + ((CARD16 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 10: \ + ((CARD16 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 13: \ + ((CARD16 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 14: \ + ((CARD16 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[DoublePixel2] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel3] = (pixel); \ + break; \ + } \ + } +#endif /* PGSZ */ + +#if PGSZ == 32 +#define SwitchBitGroup(dst,pixel,bits) { \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel0] = (pixel);) \ + break; \ + case 2: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel1] = (pixel);) \ + break; \ + case 3: \ + SwitchBitsLoop (((CARD32 *) (dst))[DoublePixel0] = (pixel);) \ + break; \ + case 4: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 5: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 6: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 7: \ + SwitchBitsLoop (((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 8: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 9: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 10: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 11: \ + SwitchBitsLoop (((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD16 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 12: \ + SwitchBitsLoop (((CARD32 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 13: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 14: \ + SwitchBitsLoop (((CARD16 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + case 15: \ + SwitchBitsLoop (((CARD32 *) (dst))[DoublePixel0] = (pixel); \ + ((CARD32 *) (dst))[DoublePixel1] = (pixel);) \ + break; \ + } \ +} +#else /* PGSZ == 64 */ +#define SwitchBitGroup(dst,pixel,bits) { \ + cfb cannot hack 64-bit SwitchBitGroup psz=PSZ +#endif /* PGSZ */ + +#endif /* PSZ == 16 */ + + +#if PSZ == 32 + +#if PGSZ == 32 +#define WriteBitGroup(dst,pixel,bits) \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 4: \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 13: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 14: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + } +#else /* PGSZ == 64 */ +#define WriteBitGroup(dst,pixel,bits) \ + if ( bits == 0xff ) { \ + ((PixelGroup *) (dst))[DoublePixel0] = (pixel); \ + ((PixelGroup *) (dst))[DoublePixel1] = (pixel); \ + ((PixelGroup *) (dst))[DoublePixel2] = (pixel); \ + ((PixelGroup *) (dst))[DoublePixel3] = (pixel); \ + } \ + else { \ + switch (bits & 0x0f) { \ + case 0: \ + break; \ + case 1: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + break; \ + case 2: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + break; \ + case 4: \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 5: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 6: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + break; \ + case 8: \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 9: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 10: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 13: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 14: \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel); \ + break; \ + } \ + switch ((bits & 0xf0) >> 4) { \ + case 0: \ + break; \ + case 1: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + break; \ + case 2: \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + break; \ + case 3: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + break; \ + case 4: \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 5: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 6: \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 7: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + break; \ + case 8: \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 9: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 10: \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 11: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 12: \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 13: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 14: \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + case 15: \ + ((CARD32 *) (dst))[SinglePixel4] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel5] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel6] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel7] = (pixel); \ + break; \ + } \ + } +#endif /* PGSZ */ + +#if PGSZ == 32 +#define SwitchBitGroup(dst,pixel,bits) { \ + switch (bits) { \ + case 0: \ + break; \ + case 1: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel);) \ + break; \ + case 2: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel1] = (pixel);) \ + break; \ + case 3: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel);) \ + break; \ + case 4: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 5: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 6: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 7: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel);) \ + break; \ + case 8: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 9: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 10: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 11: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 12: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 13: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 14: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + case 15: \ + SwitchBitsLoop (((CARD32 *) (dst))[SinglePixel0] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel1] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel2] = (pixel); \ + ((CARD32 *) (dst))[SinglePixel3] = (pixel);) \ + break; \ + } \ +} +#else /* PGSZ == 64 */ +#define SwitchBitGroup(dst,pixel,bits) { \ + cfb cannot hack 64-bit SwitchBitGroup psz=PSZ +#endif /* PGSZ */ + +#endif /* PSZ == 32 */ +#endif /* AVOID_MEMORY_READ */ + +extern PixelGroup cfb8BitLenMasks[PGSZ]; + +extern int cfb8SetStipple ( +#if NeedFunctionPrototypes + int /*alu*/, + unsigned long /*fg*/, + unsigned long /*planemask*/ +#endif +); + +extern int cfb8SetOpaqueStipple ( +#if NeedFunctionPrototypes + int /*alu*/, + unsigned long /*fg*/, + unsigned long /*bg*/, + unsigned long /*planemask*/ +#endif +); + +extern int cfb8ComputeClipMasks32 ( +#if NeedFunctionPrototypes + BoxPtr /*pBox*/, + int /*numRects*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + CARD32 * /*clips*/ +#endif +); diff --git a/cfb/cfb8line.c b/cfb/cfb8line.c new file mode 100644 index 000000000..7a5f1ac5d --- /dev/null +++ b/cfb/cfb8line.c @@ -0,0 +1,915 @@ +/* + * $Xorg: cfb8line.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +#include "X.h" + +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "mistruct.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfbrrop.h" +#include "miline.h" + +#ifdef PIXEL_ADDR + +#if defined(__GNUC__) && defined(mc68020) +#define STUPID volatile +#define REARRANGE +#else +#define STUPID +#endif + +#ifdef __GNUC__ +/* lame compiler doesn't even look at 'register' attributes */ +#define I_H do{ +#define I_T }while(0); +#define IMPORTANT_START I_H I_H I_H I_H I_H I_H I_H I_H I_H I_H +#define IMPORTANT_END I_T I_T I_T I_T I_T I_T I_T I_T I_T I_T +#else +#define IMPORTANT_START +#define IMPORTANT_END +#endif + +#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask) + +#ifdef POLYSEGMENT + +# ifdef sun +# define WIDTH_FAST 1152 +# endif + +# ifdef ultrix +# define WIDTH_FAST 1024 +# endif + +# ifdef Mips +# define WIDTH_FAST 4096 +# endif +# ifdef WIDTH_FAST +# if WIDTH_FAST == 1024 +# define FAST_MUL(y) ((y) << 10) +# endif + +# if WIDTH_FAST == 1152 +# define FAST_MUL(y) (((y) << 10) + ((y) << 7)) +# endif + +# if WIDTH_FAST == 1280 +# define FAST_MUL(y) (((y) << 10) + ((y) << 8)) +# endif + +# if WIDTH_FAST == 2048 +# define FAST_MUL(y) ((y) << 11) +# endif + +# if WIDTH_FAST == 4096 +# define FAST_MUL(y) ((y) << 12) +# endif +# endif + +# if defined(WIDTH_SHIFT) +# ifdef FAST_MUL +# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Shift)) +# if RROP == GXcopy +# define INCLUDE_OTHERS +# define SERIOUS_UNROLLING +# endif +# define INCLUDE_DRAW +# define NWIDTH(nwidth) WIDTH_FAST +# define WIDTH_MUL(y,w) FAST_MUL(y) +# endif +# else +# define FUNC_NAME(e) RROP_NAME(e) +# define WIDTH_MUL(y,w) ((y) * (w)) +# define NWIDTH(nwidth) (nwidth) +# define INCLUDE_DRAW +# if !defined (FAST_MUL) && RROP == GXcopy +# define INCLUDE_OTHERS +# define SERIOUS_UNROLLING +# endif +# endif +#else + +# define INCLUDE_DRAW +# define WIDTH_MUL(y,w) ((y) * (w)) +# define NWIDTH(nwidth) nwidth +# ifdef PREVIOUS +# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Previous)) +# else +# define FUNC_NAME(e) RROP_NAME(e) +# if RROP == GXcopy +# define INCLUDE_OTHERS +# ifdef PLENTIFUL_REGISTERS +# define SAVE_X2Y2 +# endif +# define ORIGIN +# define SERIOUS_UNROLLING +# else +# define EITHER_MODE +# endif +# endif +#endif + +#ifdef INCLUDE_DRAW + +int +#ifdef POLYSEGMENT +FUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit) + DrawablePtr pDrawable; + GCPtr pGC; + int nseg; + xSegment *pSegInit; +#else +FUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig, + x1p,y1p,x2p,y2p) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; /* number of points */ + DDXPointPtr pptInit, pptInitOrig; + int *x1p, *y1p, *x2p, *y2p; +#endif /* POLYSEGEMENT */ +{ + register long e; + register int y1_or_e1; + register PixelType *addrp; + register int stepmajor; + register int stepminor; +#ifndef REARRANGE + register long e3; +#endif +#ifdef mc68000 + register short x1_or_len; +#else + register int x1_or_len; +#endif + RROP_DECLARE + +#ifdef SAVE_X2Y2 +# define c2 y2 +#else + register int c2; +#endif +#ifndef ORIGIN + register int _x1, _y1, _x2, _y2; /* only used for CoordModePrevious */ + int extents_x1, extents_y1, extents_x2, extents_y2; +#endif /* !ORIGIN */ +#ifndef PREVIOUS + register int upperleft, lowerright; + CARD32 ClipMask = 0x80008000; +#endif /* !PREVIOUS */ +#ifdef POLYSEGMENT + register int capStyle; +#endif /* POLYSEGMENT */ +#ifdef SAVE_X2Y2 + register int x2, y2; +# define X1 x1_or_len +# define Y1 y1_or_e1 +# define X2 x2 +# define Y2 y2 +#else +# ifdef POLYSEGMENT +# define X1 x1_or_len +# define Y1 y1_or_e1 +# else +# define X1 intToX(y1_or_e1) +# define Y1 intToY(y1_or_e1) +# endif /* POLYSEGMENT */ +# define X2 intToX(c2) +# define Y2 intToY(c2) +#endif /* SAVE_X2Y2 */ + PixelType *addr; + int nwidth; + cfbPrivGCPtr devPriv; + BoxPtr extents; + int *ppt; + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + + devPriv = cfbGetGCPrivate(pGC); + cfbGetPixelWidthAndPointer (pDrawable, nwidth, addr); +#ifndef REARRANGE + RROP_FETCH_GCPRIV(devPriv); +#endif + extents = &devPriv->pCompositeClip->extents; +#ifndef PREVIOUS + c2 = *((int *) &pDrawable->x); + c2 -= (c2 & 0x8000) << 1; + upperleft = *((int *) &extents->x1) - c2; + lowerright = *((int *) &extents->x2) - c2 - 0x00010001; +#endif /* !PREVIOUS */ + addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x; +#ifdef POLYSEGMENT + capStyle = pGC->capStyle - CapNotLast; + ppt = (int *) pSegInit; + while (nseg--) +#else /* POLYSEGMENT */ +#ifdef EITHER_MODE + mode -= CoordModePrevious; + if (!mode) +#endif /* EITHER_MODE */ +#ifndef ORIGIN + { /* CoordModePrevious */ + ppt = (int *)pptInit + 1; + _x1 = *x1p; + _y1 = *y1p; + extents_x1 = extents->x1 - pDrawable->x; + extents_x2 = extents->x2 - pDrawable->x; + extents_y1 = extents->y1 - pDrawable->y; + extents_y2 = extents->y2 - pDrawable->y; + if (_x1 < extents_x1 || _x1 >= extents_x2 || + _y1 < extents_y1 || _y1 >= extents_y2) + { + c2 = *ppt++; + intToCoord(c2, _x2, _y2); + *x2p = _x1 + _x2; + *y2p = _y1 + _y2; + return 1; + } + addrp = addr + WIDTH_MUL(_y1, nwidth) + _x1; + _x2 = _x1; + _y2 = _y1; + } +#endif /* !ORIGIN */ +#ifdef EITHER_MODE + else +#endif /* EITHER_MODE */ +#ifndef PREVIOUS + { + ppt = (int *) pptInit; + c2 = *ppt++; + if (isClipped (c2, upperleft, lowerright)) + { + return 1; + } +#ifdef SAVE_X2Y2 + intToCoord(c2,x2,y2); +#endif + addrp = addr + WIDTH_MUL(Y2, nwidth) + X2; + } +#endif /* !PREVIOUS */ + while (--npt) +#endif /* POLYSEGMENT */ + { +#ifdef POLYSEGMENT + y1_or_e1 = ppt[0]; + c2 = ppt[1]; + ppt += 2; + if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright)) + break; + intToCoord(y1_or_e1,x1_or_len,y1_or_e1); + /* compute now to avoid needing x1, y1 later */ + addrp = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len; +#else /* !POLYSEGMENT */ +#ifdef EITHER_MODE + if (!mode) +#endif /* EITHER_MODE */ +#ifndef ORIGIN + { + /* CoordModePrevious */ + _x1 = _x2; + _y1 = _y2; + c2 = *ppt++; + intToCoord(c2, _x2, _y2); + _x2 = _x1 + _x2; + _y2 = _y1 + _y2; + + if (_x2 < extents_x1 || _x2 >= extents_x2 || + _y2 < extents_y1 || _y2 >= extents_y2) + { + break; + } + CalcLineDeltas(_x1, _y1, _x2, _y2, x1_or_len, y1_or_e1, + stepmajor, stepminor, 1, NWIDTH(nwidth), octant); + } +#endif /* !ORIGIN */ +#ifdef EITHER_MODE + else +#endif /* EITHER_MODE */ +#ifndef PREVIOUS + { +#ifndef SAVE_X2Y2 + y1_or_e1 = c2; +#else + y1_or_e1 = y2; + x1_or_len = x2; +#endif /* SAVE_X2Y2 */ + c2 = *ppt++; + + if (isClipped (c2, upperleft, lowerright)) + break; +#ifdef SAVE_X2Y2 + intToCoord(c2,x2,y2); +#endif + CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1, + stepmajor, stepminor, 1, NWIDTH(nwidth), octant); + } +#endif /* !PREVIOUS */ +#endif /* POLYSEGMENT */ + +#ifdef POLYSEGMENT + CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1, + stepmajor, stepminor, 1, NWIDTH(nwidth), octant); + /* + * although the horizontal code works for polyline, it + * slows down 10 pixel lines by 15%. Thus, this + * code is optimized for horizontal segments and + * random orientation lines, which seems like a reasonable + * assumption + */ + if (y1_or_e1 != 0) + { +#endif /* POLYSEGMENT */ + if (x1_or_len < y1_or_e1) + { +#ifdef REARRANGE + register int e3; +#endif + + e3 = x1_or_len; + x1_or_len = y1_or_e1; + y1_or_e1 = e3; + + e3 = stepminor; + stepminor = stepmajor; + stepmajor = e3; + SetYMajorOctant(octant); + } + + e = -x1_or_len; +#ifdef POLYSEGMENT + if (!capStyle) + x1_or_len--; +#endif + + { +#ifdef REARRANGE + register int e3; + RROP_DECLARE + RROP_FETCH_GCPRIV(devPriv); +#endif + + y1_or_e1 = y1_or_e1 << 1; + e3 = e << 1; + + FIXUP_ERROR(e, octant, bias); + +#define body {\ + RROP_SOLID(addrp); \ + addrp += stepmajor; \ + e += y1_or_e1; \ + if (e >= 0) \ + { \ + addrp += stepminor; \ + e += e3; \ + } \ + } + +#ifdef LARGE_INSTRUCTION_CACHE + +# ifdef SERIOUS_UNROLLING +# define UNROLL 16 +# else +# define UNROLL 4 +# endif +#define CASE(n) case -n: body + + while ((x1_or_len -= UNROLL) >= 0) + { + body body body body +# if UNROLL >= 8 + body body body body +# endif +# if UNROLL >= 12 + body body body body +# endif +# if UNROLL >= 16 + body body body body +# endif + } + switch (x1_or_len) + { + CASE(1) CASE(2) CASE(3) +# if UNROLL >= 8 + CASE(4) CASE(5) CASE(6) CASE(7) +# endif +# if UNROLL >= 12 + CASE(8) CASE(9) CASE(10) CASE(11) +# endif +# if UNROLL >= 16 + CASE(12) CASE(13) CASE(14) CASE(15) +# endif + } +#else /* !LARGE_INSTRUCTION_CACHE */ + + IMPORTANT_START + IMPORTANT_START + + if (x1_or_len & 1) + body + x1_or_len >>= 1; + while (x1_or_len--) { + body body + } + + IMPORTANT_END + IMPORTANT_END +#endif /* LARGE_INSTRUCTION_CACHE */ + +#ifdef POLYSEGMENT + RROP_SOLID(addrp); +#endif + } +#undef body +#ifdef POLYSEGMENT + } + else + { +# ifdef REARRANGE + register int e3; + RROP_DECLARE + RROP_FETCH_GCPRIV(devPriv); +# endif /* REARRANGE */ + if (stepmajor < 0) + { + addrp -= x1_or_len; + if (capStyle) + x1_or_len++; + else + addrp++; + } + else + { + if (capStyle) + x1_or_len++; + } + y1_or_e1 = ((int) addrp) & PIM; + addrp = (PixelType *) (((unsigned char *) addrp) - y1_or_e1); +#if PGSZ == 32 +# if PWSH != 2 + y1_or_e1 >>= (2 - PWSH); +# endif +#else /* PGSZ == 64 */ +# if PWSH != 3 + y1_or_e1 >>= (3 - PWSH); +# endif +#endif /* PGSZ */ + if (y1_or_e1 + x1_or_len <= PPW) + { + if (x1_or_len) + { + maskpartialbits(y1_or_e1, x1_or_len, e) + RROP_SOLID_MASK((unsigned long *) addrp, e); + } + } + else + { + maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len) + if (e) + { + RROP_SOLID_MASK((unsigned long *) addrp, e); + addrp += PPW; + } + RROP_SPAN(addrp, x1_or_len) + if (e3) + RROP_SOLID_MASK((unsigned long *) addrp, e3); + } + } +#endif /* POLYSEGMENT */ + } +#ifdef POLYSEGMENT + if (nseg >= 0) + return (xSegment *) ppt - pSegInit; +#else + if (npt) + { +#ifdef EITHER_MODE + if (!mode) +#endif /* EITHER_MODE */ +#ifndef ORIGIN + { + *x1p = _x1; + *y1p = _y1; + *x2p = _x2; + *y2p = _y2; + } +#endif /* !ORIGIN */ + return ((DDXPointPtr) ppt - pptInit) - 1; + } +#endif /* POLYSEGMENT */ + +#ifndef POLYSEGMENT +# ifndef ORIGIN +# define C2 c2 +# else +# define C2 ppt[-1] +# endif +#ifdef EITHER_MODE + if (pGC->capStyle != CapNotLast && + ((mode ? (C2 != *((int *) pptInitOrig)) + : ((_x2 != pptInitOrig->x) || + (_y2 != pptInitOrig->y))) + || (ppt == ((int *)pptInitOrig) + 2))) +#endif /* EITHER_MODE */ +#ifdef PREVIOUS + if (pGC->capStyle != CapNotLast && + ((_x2 != pptInitOrig->x) || + (_y2 != pptInitOrig->y) || + (ppt == ((int *)pptInitOrig) + 2))) +#endif /* PREVIOUS */ +#ifdef ORIGIN + if (pGC->capStyle != CapNotLast && + ((C2 != *((int *) pptInitOrig)) || + (ppt == ((int *)pptInitOrig) + 2))) +#endif /* !PREVIOUS */ + { +# ifdef REARRANGE + RROP_DECLARE + + RROP_FETCH_GCPRIV(devPriv); +# endif + RROP_SOLID (addrp); + } +#endif /* !POLYSEGMENT */ + return -1; +} + +#endif /* INCLUDE_DRAW */ + + +#ifdef INCLUDE_OTHERS + +#ifdef POLYSEGMENT + +void +cfb8SegmentSS1Rect (pDrawable, pGC, nseg, pSegInit) + DrawablePtr pDrawable; + GCPtr pGC; + int nseg; + xSegment *pSegInit; +{ + int (*func)(); + void (*clip)(); + int drawn; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); +#ifdef NO_ONE_RECT + if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1) + { + cfbSegmentSS(pDrawable, pGC, nseg, pSegInit); + return; + } +#endif + switch (devPriv->rop) + { + case GXcopy: + func = cfb8SegmentSS1RectCopy; + clip = cfb8ClippedLineCopy; +#ifdef FAST_MUL + if (cfbGetPixelWidth (pDrawable) == WIDTH_FAST) + func = cfb8SegmentSS1RectShiftCopy; +#endif + break; + case GXxor: + func = cfb8SegmentSS1RectXor; + clip = cfb8ClippedLineXor; + break; + default: + func = cfb8SegmentSS1RectGeneral; + clip = cfb8ClippedLineGeneral; + break; + } + while (nseg) + { + drawn = (*func) (pDrawable, pGC, nseg, pSegInit); + if (drawn == -1) + break; + (*clip) (pDrawable, pGC, + pSegInit[drawn-1].x1, pSegInit[drawn-1].y1, + pSegInit[drawn-1].x2, pSegInit[drawn-1].y2, + &devPriv->pCompositeClip->extents, + pGC->capStyle == CapNotLast); + pSegInit += drawn; + nseg -= drawn; + } +} + +#else /* POLYSEGMENT */ + +void +cfb8LineSS1Rect (pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; + int npt; + DDXPointPtr pptInit; +{ + int (*func)(); + void (*clip)(); + int drawn; + cfbPrivGCPtr devPriv; + int x1, y1, x2, y2; + DDXPointPtr pptInitOrig = pptInit; + + devPriv = cfbGetGCPrivate(pGC); +#ifdef NO_ONE_RECT + if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1) + { + cfbLineSS(pDrawable, pGC, mode, npt, pptInit); + return; + } +#endif + switch (devPriv->rop) + { + case GXcopy: + func = cfb8LineSS1RectCopy; + clip = cfb8ClippedLineCopy; + if (mode == CoordModePrevious) + func = cfb8LineSS1RectPreviousCopy; + break; + case GXxor: + func = cfb8LineSS1RectXor; + clip = cfb8ClippedLineXor; + break; + default: + func = cfb8LineSS1RectGeneral; + clip = cfb8ClippedLineGeneral; + break; + } + if (mode == CoordModePrevious) + { + x1 = pptInit->x; + y1 = pptInit->y; + while (npt > 1) + { + drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig, + &x1, &y1, &x2, &y2); + if (drawn == -1) + break; + (*clip) (pDrawable, pGC, x1, y1, x2, y2, + &devPriv->pCompositeClip->extents, + drawn != npt - 1 || pGC->capStyle == CapNotLast); + pptInit += drawn; + npt -= drawn; + x1 = x2; + y1 = y2; + } + } + else + { + while (npt > 1) + { + drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig, + &x1, &y1, &x2, &y2); + if (drawn == -1) + break; + (*clip) (pDrawable, pGC, + pptInit[drawn-1].x, pptInit[drawn-1].y, + pptInit[drawn].x, pptInit[drawn].y, + &devPriv->pCompositeClip->extents, + drawn != npt - 1 || pGC->capStyle == CapNotLast); + pptInit += drawn; + npt -= drawn; + } + } +} + +#endif /* else POLYSEGMENT */ +#endif /* INCLUDE_OTHERS */ + +#if !defined(POLYSEGMENT) && !defined (PREVIOUS) + +void +RROP_NAME (cfb8ClippedLine) (pDrawable, pGC, x1, y1, x2, y2, boxp, shorten) + DrawablePtr pDrawable; + GCPtr pGC; + int x1, y1, x2, y2; + BoxPtr boxp; + Bool shorten; +{ + int oc1, oc2; + int e, e1, e3, len; + int adx, ady; + + PixelType *addr; + int nwidth; + int stepx, stepy; + int xorg, yorg; + int new_x1, new_y1, new_x2, new_y2; + Bool pt1_clipped, pt2_clipped; + int changex, changey, result; + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + + cfbGetPixelWidthAndPointer(pDrawable, nwidth, addr); + + xorg = pDrawable->x; + yorg = pDrawable->y; + x1 += xorg; + y1 += yorg; + x2 += xorg; + y2 += yorg; + oc1 = 0; + oc2 = 0; + OUTCODES (oc1, x1, y1, boxp); + OUTCODES (oc2, x2, y2, boxp); + + if (oc1 & oc2) + return; + + CalcLineDeltas(x1, y1, x2, y2, adx, ady, stepx, stepy, 1, nwidth, octant); + + if (adx <= ady) + { + int t; + + t = adx; + adx = ady; + ady = t; + + t = stepx; + stepx = stepy; + stepy = t; + + SetYMajorOctant(octant); + } + e = - adx; + e1 = ady << 1; + e3 = - (adx << 1); + + FIXUP_ERROR(e, octant, bias); + + new_x1 = x1; + new_y1 = y1; + new_x2 = x2; + new_y2 = y2; + pt1_clipped = 0; + pt2_clipped = 0; + + if (IsXMajorOctant(octant)) + { + result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, + &pt1_clipped, &pt2_clipped, + octant, bias, oc1, oc2); + if (result == -1) + return; + + len = abs(new_x2 - new_x1) - 1; /* this routine needs the "-1" */ + + /* if we've clipped the endpoint, always draw the full length + * of the segment, because then the capstyle doesn't matter + * if x2,y2 isn't clipped, use the capstyle + * (shorten == TRUE <--> CapNotLast) + */ + if (pt2_clipped || !shorten) + len++; + + if (pt1_clipped) + { + /* must calculate new error terms */ + changex = abs(new_x1 - x1); + changey = abs(new_y1 - y1); + e = e + changey * e3 + changex * e1; + } + } + else /* Y_AXIS */ + { + result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1, + &new_x1, &new_y1, &new_x2, &new_y2, + ady, adx, + &pt1_clipped, &pt2_clipped, + octant, bias, oc1, oc2); + if (result == -1) + return; + + len = abs(new_y2 - new_y1) - 1; /* this routine needs the "-1" */ + + /* if we've clipped the endpoint, always draw the full length + * of the segment, because then the capstyle doesn't matter + * if x2,y2 isn't clipped, use the capstyle + * (shorten == TRUE <--> CapNotLast) + */ + if (pt2_clipped || !shorten) + len++; + + if (pt1_clipped) + { + /* must calculate new error terms */ + changex = abs(new_x1 - x1); + changey = abs(new_y1 - y1); + e = e + changex * e3 + changey * e1; + } + } + x1 = new_x1; + y1 = new_y1; + { + register PixelType *addrp; + RROP_DECLARE + + RROP_FETCH_GC(pGC); + + addrp = addr + (y1 * nwidth) + x1; + +#ifndef REARRANGE + if (!ady) + { +#define body { RROP_SOLID(addrp); addrp += stepx; } + while (len >= PGSZB) + { + body body body body +#if PGSZ == 64 + body body body body +#endif + len -= PGSZB; + } + switch (len) + { +#if PGSZ == 64 + case 7: body case 6: body case 5: body case 4: body +#endif + case 3: body case 2: body case 1: body + } +#undef body + } + else +#endif /* !REARRANGE */ + { +#define body {\ + RROP_SOLID(addrp); \ + addrp += stepx; \ + e += e1; \ + if (e >= 0) \ + { \ + addrp += stepy; \ + e += e3; \ + } \ + } + +#ifdef LARGE_INSTRUCTION_CACHE + while ((len -= PGSZB) >= 0) + { + body body body body +#if PGSZ == 64 + body body body body +#endif + } + switch (len) + { + case -1: body case -2: body case -3: body +#if PGSZ == 64 + case -4: body case -5: body case -6: body case -7: body +#endif + } +#else /* !LARGE_INSTRUCTION_CACHE */ + IMPORTANT_START; + + while ((len -= 2) >= 0) + { + body body; + } + if (len & 1) + body; + + IMPORTANT_END; +#endif /* LARGE_INSTRUCTION_CACHE */ + } + RROP_SOLID(addrp); +#undef body + } +} + +#endif /* !POLYSEGMENT && !PREVIOUS */ +#endif /* PIXEL_ADDR */ diff --git a/cfb/cfballpriv.c b/cfb/cfballpriv.c new file mode 100644 index 000000000..abd634e2c --- /dev/null +++ b/cfb/cfballpriv.c @@ -0,0 +1,84 @@ +/* + * $Xorg: cfballpriv.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ + * +Copyright 1991, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "resource.h" +#include "colormap.h" +#include "colormapst.h" +#include "cfb.h" +#include "mi.h" +#include "mistruct.h" +#include "dix.h" +#include "cfbmskbits.h" +#include "mibstore.h" + +int cfbWindowPrivateIndex; +int cfbGCPrivateIndex; +#ifdef CFB_NEED_SCREEN_PRIVATE +int cfbScreenPrivateIndex; +#endif + +extern RegionPtr (*cfbPuntCopyPlane)(); + +Bool +cfbAllocatePrivates(pScreen, window_index, gc_index) + ScreenPtr pScreen; + int *window_index, *gc_index; +{ + if (!window_index || !gc_index || + *window_index == -1 && *gc_index == -1) + { + if (!mfbAllocatePrivates(pScreen, + &cfbWindowPrivateIndex, &cfbGCPrivateIndex)) + return FALSE; + if (window_index) + *window_index = cfbWindowPrivateIndex; + if (gc_index) + *gc_index = cfbGCPrivateIndex; + } + else + { + cfbWindowPrivateIndex = *window_index; + cfbGCPrivateIndex = *gc_index; + } + if (!AllocateWindowPrivate(pScreen, cfbWindowPrivateIndex, + sizeof(cfbPrivWin)) || + !AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC))) + return FALSE; + cfbPuntCopyPlane = miCopyPlane; +#ifdef CFB_NEED_SCREEN_PRIVATE + cfbScreenPrivateIndex = AllocateScreenPrivateIndex (); + if (cfbScreenPrivateIndex == -1) + return FALSE; +#endif + return TRUE; +} diff --git a/cfb/cfbbitblt.c b/cfb/cfbbitblt.c new file mode 100644 index 000000000..3afe4eb81 --- /dev/null +++ b/cfb/cfbbitblt.c @@ -0,0 +1,759 @@ +/* + * cfb copy area + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Keith Packard + +*/ +/* $Xorg: cfbbitblt.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" +#include "fastblt.h" +#define MFB_CONSTS_ONLY +#include "maskbits.h" + +RegionPtr +cfbBitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane) + register DrawablePtr pSrcDrawable; + register DrawablePtr pDstDrawable; + GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; + void (*doBitBlt)(); + unsigned long bitPlane; +{ + RegionPtr prgnSrcClip; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + + RegionPtr prgnExposed; + RegionRec rgnDst; + DDXPointPtr pptSrc; + register DDXPointPtr ppt; + register BoxPtr pbox; + int i; + register int dx; + register int dy; + xRectangle origSource; + DDXPointRec origDest; + int numRects; + BoxRec fastBox; + int fastClip = 0; /* for fast clipping with pixmap source */ + int fastExpose = 0; /* for fast exposures with pixmap source */ + + origSource.x = srcx; + origSource.y = srcy; + origSource.width = width; + origSource.height = height; + origDest.x = dstx; + origDest.y = dsty; + + if ((pSrcDrawable != pDstDrawable) && + pSrcDrawable->pScreen->SourceValidate) + { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height); + } + + srcx += pSrcDrawable->x; + srcy += pSrcDrawable->y; + + /* clip the source */ + + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) + { + prgnSrcClip = cfbGetCompositeClip(pGC); + } + else + { + fastClip = 1; + } + } + else + { + if (pGC->subWindowMode == IncludeInferiors) + { + if (!((WindowPtr) pSrcDrawable)->parent) + { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastClip = 1; + } + else if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) + { + prgnSrcClip = cfbGetCompositeClip(pGC); + } + else + { + prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); + freeSrcClip = TRUE; + } + } + else + { + prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + } + } + + fastBox.x1 = srcx; + fastBox.y1 = srcy; + fastBox.x2 = srcx + width; + fastBox.y2 = srcy + height; + + /* Don't create a source region if we are doing a fast clip */ + if (fastClip) + { + fastExpose = 1; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (fastBox.x1 < pSrcDrawable->x) + { + fastBox.x1 = pSrcDrawable->x; + fastExpose = 0; + } + if (fastBox.y1 < pSrcDrawable->y) + { + fastBox.y1 = pSrcDrawable->y; + fastExpose = 0; + } + if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) + { + fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + fastExpose = 0; + } + if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) + { + fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + fastExpose = 0; + } + } + else + { + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); + } + + dstx += pDstDrawable->x; + dsty += pDstDrawable->y; + + if (pDstDrawable->type == DRAWABLE_WINDOW) + { + if (!((WindowPtr)pDstDrawable)->realized) + { + if (!fastClip) + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return NULL; + } + } + + dx = srcx - dstx; + dy = srcy - dsty; + + /* Translate and clip the dst to the destination composite clip */ + if (fastClip) + { + RegionPtr cclip; + + /* Translate the region directly */ + fastBox.x1 -= dx; + fastBox.x2 -= dx; + fastBox.y1 -= dy; + fastBox.y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + + /* XXX because CopyPlane uses this routine for 8-to-1 bit + * copies, this next line *must* also correctly fetch the + * composite clip from an mfb gc + */ + + cclip = cfbGetCompositeClip(pGC); + if (REGION_NUM_RECTS(cclip) == 1) + { + BoxPtr pBox = REGION_RECTS(cclip); + + if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1; + if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2; + if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1; + if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2; + + /* Check to see if the region is empty */ + if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) + { + REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0); + } + else + { + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); + } + } + else + { + /* We must turn off fastClip now, since we must create + a full blown region. It is intersected with the + composite clip below. */ + fastClip = 0; + REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1); + } + } + else + { + REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); + } + + if (!fastClip) + { + REGION_INTERSECT(pGC->pScreen, &rgnDst, + &rgnDst, + cfbGetCompositeClip(pGC)); + } + + /* Do bit blitting */ + numRects = REGION_NUM_RECTS(&rgnDst); + if (numRects && width && height) + { + if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects * + sizeof(DDXPointRec)))) + { + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return NULL; + } + pbox = REGION_RECTS(&rgnDst); + ppt = pptSrc; + for (i = numRects; --i >= 0; pbox++, ppt++) + { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane); + DEALLOCATE_LOCAL(pptSrc); + } + + prgnExposed = NULL; + if ( cfbGetGCPrivate(pGC)->fExpose) + { + extern RegionPtr miHandleExposures(); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose) + prgnExposed = + miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + origSource.x, origSource.y, + (int)origSource.width, + (int)origSource.height, + origDest.x, origDest.y, bitPlane); + } + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return prgnExposed; +} + + +void +cfbDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask) + DrawablePtr pSrc, pDst; + int alu; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ + void (*blt)() = cfbDoBitbltGeneral; + if ((planemask & PMSK) == PMSK) { + switch (alu) { + case GXcopy: + blt = cfbDoBitbltCopy; + break; + case GXxor: + blt = cfbDoBitbltXor; + break; + case GXor: + blt = cfbDoBitbltOr; + break; + } + } + (*blt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask); +} + +RegionPtr +cfbCopyArea(pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty) + register DrawablePtr pSrcDrawable; + register DrawablePtr pDstDrawable; + GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; +{ + void (*doBitBlt) (); + + doBitBlt = cfbDoBitbltCopy; + if (pGC->alu != GXcopy || (pGC->planemask & PMSK) != PMSK) + { + doBitBlt = cfbDoBitbltGeneral; + if ((pGC->planemask & PMSK) == PMSK) + { + switch (pGC->alu) { + case GXxor: + doBitBlt = cfbDoBitbltXor; + break; + case GXor: + doBitBlt = cfbDoBitbltOr; + break; + } + } + } + return cfbBitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0L); +} + +#if PSZ == 8 +void +cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, bitPlane) + DrawablePtr pSrcDrawable; /* must be a bitmap */ + DrawablePtr pDstDrawable; /* must be depth 8 drawable */ + int rop; /* not used; caller must call cfb8CheckOpaqueStipple + * beforehand to get cfb8StippleRRop set correctly */ + unsigned long planemask; /* to apply to destination writes */ + RegionPtr prgnDst; /* region in destination to draw to; + * screen relative coords. if dest is a window; + * drawable relative if dest is a pixmap */ + DDXPointPtr pptSrc; /* drawable relative src coords to copy from; + * must be one point for each box in prgnDst */ + unsigned long bitPlane; /* not used; assumed always to be 1 */ +{ + int srcx, srcy; /* upper left corner of box being copied in source */ + int dstx, dsty; /* upper left corner of box being copied in dest */ + int width, height; /* in pixels, unpadded, of box being copied */ + int xoffSrc; /* bit # in leftmost word of row from which copying starts */ + int xoffDst; /* byte # in leftmost word of row from which copying starts */ + unsigned long *psrcBase, *pdstBase; /* start of drawable's pixel data */ + int widthSrc; /* # of groups of 32 pixels (1 bit/pixel) in src bitmap*/ + int widthDst; /* # of groups of 4 pixels (8 bits/pixel) in dst */ + unsigned long *psrcLine, *pdstLine; /* steps a row at a time thru src/dst; + * may point into middle of row */ + register unsigned long *psrc, *pdst; /* steps within the row */ + register unsigned long bits, tmp; /* bits from source */ + register int leftShift; + register int rightShift; + unsigned long startmask; /* left edge pixel mask */ + unsigned long endmask; /* right edge pixel mask */ + register int nlMiddle; /* number of words in middle of the row to draw */ + register int nl; + int firstoff; + int secondoff; + unsigned long src; + int nbox; /* number of boxes in region to copy */ + BoxPtr pbox; /* steps thru boxes in region */ + int pixelsRemainingOnRightEdge; /* # pixels to be drawn on a row after + * the main "middle" loop */ + + cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase) + cfbGetLongWidthAndPointer (pDstDrawable, widthDst, pdstBase) + + nbox = REGION_NUM_RECTS(prgnDst); + pbox = REGION_RECTS(prgnDst); + while (nbox--) + { + dstx = pbox->x1; + dsty = pbox->y1; + srcx = pptSrc->x; + srcy = pptSrc->y; + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + pbox++; + pptSrc++; + + psrcLine = psrcBase + srcy * widthSrc + (srcx >> MFB_PWSH); + pdstLine = pdstBase + dsty * widthDst + (dstx >> PWSH); + xoffSrc = srcx & MFB_PIM; /* finds starting bit in src */ + xoffDst = dstx & PIM; /* finds starting byte in dst */ + + /* compute startmask, endmask, nlMiddle */ + + if (xoffDst + width < PPW) /* XXX should this be '<= PPW' ? */ + { /* the copy only affects one word per row in destination */ + maskpartialbits(dstx, width, startmask); + endmask = 0; /* nothing on right edge */ + nlMiddle = 0; /* nothing in middle */ + } + else + { /* the copy will affect multiple words per row in destination */ + maskbits(dstx, width, startmask, endmask, nlMiddle); + } + + /* + * compute constants for the first four bits to be + * copied. This avoids troubles with partial first + * writes, and difficult shift computation + */ + if (startmask) + { + firstoff = xoffSrc - xoffDst; + if (firstoff > (MFB_PPW-PPW)) + secondoff = MFB_PPW - firstoff; + if (xoffDst) + { + srcx += (PPW-xoffDst); + xoffSrc = srcx & MFB_PIM; + } + } + leftShift = xoffSrc; + rightShift = MFB_PPW - leftShift; + + pixelsRemainingOnRightEdge = (nlMiddle & 7) * PPW + + ((dstx + width) & PIM); + + /* setup is done; now let's move some bits */ + + /* caller must call cfb8CheckOpaqueStipple before this function + * to set cfb8StippleRRop! + */ + + if (cfb8StippleRRop == GXcopy) + { + while (height--) + { /* one iteration of this loop copies one row */ + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + bits = *psrc++; + if (startmask) + { + if (firstoff < 0) + tmp = BitRight (bits, -firstoff); + else + { + tmp = BitLeft (bits, firstoff); + /* + * need a more cautious test for partialmask + * case... + */ + if (firstoff >= (MFB_PPW-PPW)) + { + bits = *psrc++; + if (firstoff != (MFB_PPW-PPW)) + tmp |= BitRight (bits, secondoff); + } + } + *pdst = (*pdst & ~startmask) | (GetPixelGroup(tmp) & startmask); + pdst++; + } + nl = nlMiddle; + while (nl >= 8) + { + nl -= 8; + tmp = BitLeft(bits, leftShift); + bits = *psrc++; + if (rightShift != MFB_PPW) + tmp |= BitRight(bits, rightShift); + +#ifdef FAST_CONSTANT_OFFSET_MODE +# define StorePixels(pdst,o,pixels) (pdst)[o] = (pixels) +# define EndStep(pdst,o) (pdst) += (o) +# define StoreRopPixels(pdst,o,and,xor) (pdst)[o] = DoRRop((pdst)[o],and,xor); +#else +# define StorePixels(pdst,o,pixels) *(pdst)++ = (pixels) +# define EndStep(pdst,o) +# define StoreRopPixels(pdst,o,and,xor) *(pdst) = DoRRop(*(pdst),and,xor); (pdst)++; +#endif + +#define Step(c) NextBitGroup(c); +#define StoreBitsPlain(o,c) StorePixels(pdst,o,GetPixelGroup(c)) +#define StoreRopBitsPlain(o,c) StoreRopPixels(pdst,o,\ + cfb8StippleAnd[GetBitGroup(c)], \ + cfb8StippleXor[GetBitGroup(c)]) +#define StoreBits0(c) StoreBitsPlain(0,c) +#define StoreRopBits0(c) StoreRopBitsPlain(0,c) + +#if (BITMAP_BIT_ORDER == MSBFirst) +# define StoreBits(o,c) StoreBitsPlain(o,c) +# define StoreRopBits(o,c) StoreRopBitsPlain(o,c) +# define FirstStep(c) Step(c) +#else /* BITMAP_BIT_ORDER == LSBFirst */ +#if PGSZ == 64 +# define StoreBits(o,c) StorePixels(pdst,o, (cfb8Pixels[c & 0xff])) +# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \ + (cfb8StippleAnd[c & 0xff]), \ + (cfb8StippleXor[c & 0xff])) +# define FirstStep(c) c = BitLeft (c, 8); +#else +/* 0x3c is 0xf << 2 (4 bits, long word) */ +# define StoreBits(o,c) StorePixels(pdst,o,*((unsigned long *)\ + (((char *) cfb8Pixels) + (c & 0x3c)))) +# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \ + *((unsigned long *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \ + *((unsigned long *) (((char *) cfb8StippleXor) + (c & 0x3c)))) +# define FirstStep(c) c = BitLeft (c, 2); +#endif /* PGSZ */ +#endif /* BITMAP_BIT_ORDER */ + + StoreBits0(tmp); FirstStep(tmp); + StoreBits(1,tmp); Step(tmp); + StoreBits(2,tmp); Step(tmp); + StoreBits(3,tmp); Step(tmp); + StoreBits(4,tmp); Step(tmp); + StoreBits(5,tmp); Step(tmp); + StoreBits(6,tmp); Step(tmp); + StoreBits(7,tmp); EndStep (pdst,8); + } + + /* do rest of middle and partial word on right edge */ + + if (pixelsRemainingOnRightEdge) + { + tmp = BitLeft(bits, leftShift); + + if (pixelsRemainingOnRightEdge > rightShift) + { + bits = *psrc++; + tmp |= BitRight (bits, rightShift); + } + EndStep (pdst, nl); + switch (nl) + { + case 7: + StoreBitsPlain(-7,tmp); Step(tmp); + case 6: + StoreBitsPlain(-6,tmp); Step(tmp); + case 5: + StoreBitsPlain(-5,tmp); Step(tmp); + case 4: + StoreBitsPlain(-4,tmp); Step(tmp); + case 3: + StoreBitsPlain(-3,tmp); Step(tmp); + case 2: + StoreBitsPlain(-2,tmp); Step(tmp); + case 1: + StoreBitsPlain(-1,tmp); Step(tmp); + } + if (endmask) + *pdst = (*pdst & ~endmask) | (GetPixelGroup(tmp) & endmask); + } + } + } + else /* cfb8StippleRRop != GXcopy */ + { + while (height--) + { /* one iteration of this loop copies one row */ + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + bits = *psrc++; + + /* do partial word on left edge */ + + if (startmask) + { + if (firstoff < 0) + tmp = BitRight (bits, -firstoff); + else + { + tmp = BitLeft (bits, firstoff); + if (firstoff >= (MFB_PPW-PPW)) + { + bits = *psrc++; + if (firstoff != (MFB_PPW-PPW)) + tmp |= BitRight (bits, secondoff); + } + } + src = GetBitGroup(tmp); + *pdst = MaskRRopPixels (*pdst, src, startmask); + pdst++; + } + + /* do middle of row */ + + nl = nlMiddle; + while (nl >= 8) + { + nl -= 8; + tmp = BitLeft(bits, leftShift); + bits = *psrc++; + if (rightShift != MFB_PPW) + tmp |= BitRight(bits, rightShift); + StoreRopBits0(tmp); FirstStep(tmp); + StoreRopBits(1,tmp); Step(tmp); + StoreRopBits(2,tmp); Step(tmp); + StoreRopBits(3,tmp); Step(tmp); + StoreRopBits(4,tmp); Step(tmp); + StoreRopBits(5,tmp); Step(tmp); + StoreRopBits(6,tmp); Step(tmp); + StoreRopBits(7,tmp); EndStep(pdst,8); + } + + /* do rest of middle and partial word on right edge */ + + if (pixelsRemainingOnRightEdge) + { + tmp = BitLeft(bits, leftShift); + + if (pixelsRemainingOnRightEdge > rightShift) + { + bits = *psrc++; /* XXX purify abr here */ + tmp |= BitRight (bits, rightShift); + } + while (nl--) + { + src = GetBitGroup (tmp); + *pdst = RRopPixels (*pdst, src); + pdst++; + NextBitGroup(tmp); + } + if (endmask) + { + src = GetBitGroup (tmp); + *pdst = MaskRRopPixels (*pdst, src, endmask); + } + } + } /* end copy one row */ + } /* end alu is non-copy-mode case */ + } /* end iteration over region boxes */ +} + +#endif + +/* shared among all different cfb depths through linker magic */ +RegionPtr (*cfbPuntCopyPlane)(); + +RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, bitPlane) + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + GCPtr pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; + unsigned long bitPlane; +{ + RegionPtr ret; + extern RegionPtr miHandleExposures(); + void (*doBitBlt)(); + +#if PSZ == 8 + + if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == 8) + { + if (bitPlane == 1) + { + doBitBlt = cfbCopyPlane1to8; + cfb8CheckOpaqueStipple (pGC->alu, + pGC->fgPixel, pGC->bgPixel, + pGC->planemask); + ret = cfbBitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane); + } + else + ret = miHandleExposures (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); + } + else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 1) + { + extern int InverseAlu[16]; + int oldalu; + + oldalu = pGC->alu; + if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1) + pGC->alu = InverseAlu[pGC->alu]; + else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) + pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); + ret = cfbBitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, + cfbCopyPlane8to1, bitPlane); + pGC->alu = oldalu; + } + else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 8) + { + PixmapPtr pBitmap; + ScreenPtr pScreen = pSrcDrawable->pScreen; + GCPtr pGC1; + + pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1); + if (!pBitmap) + return NULL; + pGC1 = GetScratchGC (1, pScreen); + if (!pGC1) + { + (*pScreen->DestroyPixmap) (pBitmap); + return NULL; + } + /* + * don't need to set pGC->fgPixel,bgPixel as copyPlane8to1 + * ignores pixel values, expecting the rop to "do the + * right thing", which GXcopy will. + */ + ValidateGC ((DrawablePtr) pBitmap, pGC1); + /* no exposures here, scratch GC's don't get graphics expose */ + (void) cfbBitBlt (pSrcDrawable, (DrawablePtr) pBitmap, + pGC1, srcx, srcy, width, height, 0, 0, + cfbCopyPlane8to1, bitPlane); + cfb8CheckOpaqueStipple (pGC->alu, + pGC->fgPixel, pGC->bgPixel, + pGC->planemask); + /* no exposures here, copy bits from inside a pixmap */ + (void) cfbBitBlt ((DrawablePtr) pBitmap, pDstDrawable, pGC, + 0, 0, width, height, dstx, dsty, cfbCopyPlane1to8, 1); + FreeScratchGC (pGC1); + (*pScreen->DestroyPixmap) (pBitmap); + /* compute resultant exposures */ + ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, + dstx, dsty, bitPlane); + } + else +#endif + ret = (*cfbPuntCopyPlane) (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); + return ret; +} diff --git a/cfb/cfbblt.c b/cfb/cfbblt.c new file mode 100644 index 000000000..f87acc03d --- /dev/null +++ b/cfb/cfbblt.c @@ -0,0 +1,633 @@ +/* + * cfb copy area + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Keith Packard + +*/ +/* $Xorg: cfbblt.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" +#include "fastblt.h" +#include "mergerop.h" + +#ifdef notdef /* XXX fails right now, walks off end of pixmaps */ +#if defined (FAST_UNALIGNED_READS) && PSZ == 8 +#define DO_UNALIGNED_BITBLT +#endif +#endif + +#if defined(FAST_MEMCPY) && (MROP == Mcopy) && PSZ == 8 +#define DO_MEMCPY +#endif + +void +MROP_NAME(cfbDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask) + DrawablePtr pSrc, pDst; + int alu; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ + unsigned long *psrcBase, *pdstBase; + /* start of src and dst bitmaps */ + int widthSrc, widthDst; /* add to get to same position in next line */ + + BoxPtr pbox; + int nbox; + + BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; + /* temporaries for shuffling rectangles */ + DDXPointPtr pptTmp, pptNew1, pptNew2; + /* shuffling boxes entails shuffling the + source points too */ + int w, h; + int xdir; /* 1 = left right, -1 = right left/ */ + int ydir; /* 1 = top down, -1 = bottom up */ + + unsigned long *psrcLine, *pdstLine; + /* pointers to line with current src and dst */ + register unsigned long *psrc;/* pointer to current src longword */ + register unsigned long *pdst;/* pointer to current dst longword */ + + MROP_DECLARE_REG() + + /* following used for looping through a line */ + unsigned long startmask, endmask; /* masks for writing ends of dst */ + int nlMiddle; /* whole longwords in dst */ + int xoffSrc, xoffDst; + register int leftShift, rightShift; + register unsigned long bits; + register unsigned long bits1; + register int nl; /* temp copy of nlMiddle */ + + /* place to store full source word */ + int nstart; /* number of ragged bits at start of dst */ + int nend; /* number of ragged bits at end of dst */ + int srcStartOver; /* pulling nstart bits from src + overflows into the next word? */ + int careful; + int tmpSrc; + + MROP_INITIALIZE(alu,planemask); + + cfbGetLongWidthAndPointer (pSrc, widthSrc, psrcBase) + + cfbGetLongWidthAndPointer (pDst, widthDst, pdstBase) + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrc == pDst) || + ((pSrc->type == DRAWABLE_WINDOW) && + (pDst->type == DRAWABLE_WINDOW))); + + pbox = REGION_RECTS(prgnDst); + nbox = REGION_NUM_RECTS(prgnDst); + + pboxNew1 = NULL; + pptNew1 = NULL; + pboxNew2 = NULL; + pptNew2 = NULL; + if (careful && (pptSrc->y < pbox->y1)) + { + /* walk source botttom to top */ + ydir = -1; + widthSrc = -widthSrc; + widthDst = -widthDst; + + if (nbox > 1) + { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); + if(!pboxNew1) + return; + pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); + if(!pptNew1) + { + DEALLOCATE_LOCAL(pboxNew1); + return; + } + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) + { + while ((pboxNext >= pbox) && + (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp <= pboxBase) + { + *pboxNew1++ = *pboxTmp++; + *pptNew1++ = *pptTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + pptNew1 -= nbox; + pptSrc = pptNew1; + } + } + else + { + /* walk source top to bottom */ + ydir = 1; + } + + if (careful && (pptSrc->x < pbox->x1)) + { + /* walk source right to left */ + xdir = -1; + + if (nbox > 1) + { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); + pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); + if(!pboxNew2 || !pptNew2) + { + if (pptNew2) DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) + { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) + { + while ((pboxNext < pbox+nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp != pboxBase) + { + *pboxNew2++ = *--pboxTmp; + *pptNew2++ = *--pptTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + pptNew2 -= nbox; + pptSrc = pptNew2; + } + } + else + { + /* walk source left to right */ + xdir = 1; + } + + while(nbox--) + { + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + if (ydir == -1) /* start at last scanline of rectangle */ + { + psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc); + pdstLine = pdstBase + ((pbox->y2-1) * -widthDst); + } + else /* start at first scanline */ + { + psrcLine = psrcBase + (pptSrc->y * widthSrc); + pdstLine = pdstBase + (pbox->y1 * widthDst); + } + if ((pbox->x1 & PIM) + w <= PPW) + { + maskpartialbits (pbox->x1, w, endmask); + startmask = 0; + nlMiddle = 0; + } + else + { + maskbits(pbox->x1, w, startmask, endmask, nlMiddle); + } + +#ifdef DO_MEMCPY + /* If the src and dst scanline don't overlap, do forward case. */ + + if ((xdir == 1) || (pptSrc->y != pbox->y1) + || (pptSrc->x + w <= pbox->x1)) + { + char *psrc = (char *) psrcLine + pptSrc->x; + char *pdst = (char *) pdstLine + pbox->x1; + while (h--) + { + memcpy(pdst, psrc, w); + pdst += widthDst << 2; + psrc += widthSrc << 2; + } + } +#else /* ! DO_MEMCPY */ + if (xdir == 1) + { + xoffSrc = pptSrc->x & PIM; + xoffDst = pbox->x1 & PIM; + pdstLine += (pbox->x1 >> PWSH); + psrcLine += (pptSrc->x >> PWSH); +#ifdef DO_UNALIGNED_BITBLT + nl = xoffSrc - xoffDst; + psrcLine = (unsigned long *) + (((unsigned char *) psrcLine) + nl); +#else + if (xoffSrc == xoffDst) +#endif + { + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + pdstLine += widthDst; + psrcLine += widthSrc; + if (startmask) + { + *pdst = MROP_MASK(*psrc, *pdst, startmask); + psrc++; + pdst++; + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); +#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++; +#define BodyEven(n) BodyOdd(n) + +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else +#ifdef NOTDEF + /* you'd think this would be faster -- + * a single instruction instead of 6 + * but measurements show it to be ~15% slower + */ + while ((nl -= 6) >= 0) + { + asm ("moveml %1+,#0x0c0f;moveml#0x0c0f,%0" + : "=m" (*(char *)pdst) + : "m" (*(char *)psrc) + : "d0", "d1", "d2", "d3", + "a2", "a3"); + pdst += 6; + } + nl += 6; + while (nl--) + *pdst++ = *psrc++; +#endif + DuffL(nl, label1, + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++;) +#endif + + if (endmask) + *pdst = MROP_MASK(*psrc, *pdst, endmask); + } + } +#ifndef DO_UNALIGNED_BITBLT + else + { + if (xoffSrc > xoffDst) + { +#if PGSZ == 32 + leftShift = (xoffSrc - xoffDst) << (5 - PWSH); +#else /* PGSZ == 64 */ + leftShift = (xoffSrc - xoffDst) << (6 - PWSH); +#endif /* PGSZ */ + rightShift = PGSZ - leftShift; + } + else + { +#if PGSZ == 32 + rightShift = (xoffDst - xoffSrc) << (5 - PWSH); +#else /* PGSZ == 64 */ + rightShift = (xoffDst - xoffSrc) << (6 - PWSH); +#endif /* PGSZ */ + leftShift = PGSZ - rightShift; + } + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + pdstLine += widthDst; + psrcLine += widthSrc; + bits = 0; + if (xoffSrc > xoffDst) + bits = *psrc++; + if (startmask) + { + bits1 = BitLeft(bits,leftShift); + bits = *psrc++; + bits1 |= BitRight(bits,rightShift); + *pdst = MROP_MASK(bits1, *pdst, startmask); + pdst++; + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; + +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) \ +bits = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]); + +#define BodyEven(n) \ +bits1 = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) \ +bits = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \ +pdst++; + +#define BodyEven(n) \ +bits1 = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \ +pdst++; + +#define LoopReset ; + +#endif /* !FAST_CONSTANT_OFFSET_MODE */ + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL (nl,label2, + bits1 = BitLeft(bits, leftShift); + bits = *psrc++; + *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst); + pdst++; + ) +#endif + + if (endmask) + { + bits1 = BitLeft(bits, leftShift); + if (BitLeft(endmask, rightShift)) + { + bits = *psrc; + bits1 |= BitRight(bits, rightShift); + } + *pdst = MROP_MASK (bits1, *pdst, endmask); + } + } + } +#endif /* DO_UNALIGNED_BITBLT */ + } +#endif /* ! DO_MEMCPY */ + else /* xdir == -1 */ + { + xoffSrc = (pptSrc->x + w - 1) & PIM; + xoffDst = (pbox->x2 - 1) & PIM; + pdstLine += ((pbox->x2-1) >> PWSH) + 1; + psrcLine += ((pptSrc->x+w - 1) >> PWSH) + 1; +#ifdef DO_UNALIGNED_BITBLT + nl = xoffSrc - xoffDst; + psrcLine = (unsigned long *) + (((unsigned char *) psrcLine) + nl); +#else + if (xoffSrc == xoffDst) +#endif + { + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + pdstLine += widthDst; + psrcLine += widthSrc; + if (endmask) + { + pdst--; + psrc--; + *pdst = MROP_MASK (*psrc, *pdst, endmask); + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + psrc -= nl & (UNROLL - 1); + pdst -= nl & (UNROLL - 1); + +#define BodyOdd(n) pdst[n-1] = MROP_SOLID (psrc[n-1], pdst[n-1]); + +#define BodyEven(n) BodyOdd(n) + +#define LoopReset \ +pdst -= UNROLL;\ +psrc -= UNROLL; + +#else + +#define BodyOdd(n) --pdst; --psrc; *pdst = MROP_SOLID(*psrc, *pdst); +#define BodyEven(n) BodyOdd(n) +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl,label3, + --pdst; --psrc; *pdst = MROP_SOLID (*psrc, *pdst);) +#endif + + if (startmask) + { + --pdst; + --psrc; + *pdst = MROP_MASK(*psrc, *pdst, startmask); + } + } + } +#ifndef DO_UNALIGNED_BITBLT + else + { + if (xoffDst > xoffSrc) + { +#if PGSZ == 32 + rightShift = (xoffDst - xoffSrc) << (5 - PWSH); +#else /* PGSZ == 64 */ + rightShift = (xoffDst - xoffSrc) << (6 - PWSH); +#endif /* PGSZ */ + leftShift = PGSZ - rightShift; + } + else + { +#if PGSZ == 32 + leftShift = (xoffSrc - xoffDst) << (5 - PWSH); +#else /* PGSZ == 64 */ + leftShift = (xoffSrc - xoffDst) << (6 - PWSH); +#endif /* PGSZ */ + rightShift = PGSZ - leftShift; + } + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + pdstLine += widthDst; + psrcLine += widthSrc; + bits = 0; + if (xoffDst > xoffSrc) + bits = *--psrc; + if (endmask) + { + bits1 = BitRight(bits, rightShift); + bits = *--psrc; + bits1 |= BitLeft(bits, leftShift); + pdst--; + *pdst = MROP_MASK(bits1, *pdst, endmask); + } + nl = nlMiddle; + +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; +#ifdef FAST_CONSTANT_OFFSET_MODE + psrc -= nl & (UNROLL - 1); + pdst -= nl & (UNROLL - 1); + +#define BodyOdd(n) \ +bits = psrc[n-1]; \ +pdst[n-1] = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),pdst[n-1]); + +#define BodyEven(n) \ +bits1 = psrc[n-1]; \ +pdst[n-1] = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),pdst[n-1]); + +#define LoopReset \ +pdst -= UNROLL; \ +psrc -= UNROLL; + +#else + +#define BodyOdd(n) \ +bits = *--psrc; --pdst; \ +*pdst = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),*pdst); + +#define BodyEven(n) \ +bits1 = *--psrc; --pdst; \ +*pdst = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),*pdst); + +#define LoopReset ; + +#endif + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL (nl, label4, + bits1 = BitRight(bits, rightShift); + bits = *--psrc; + --pdst; + *pdst = MROP_SOLID(bits1 | BitLeft(bits, leftShift),*pdst); + ) +#endif + + if (startmask) + { + bits1 = BitRight(bits, rightShift); + if (BitRight (startmask, leftShift)) + { + bits = *--psrc; + bits1 |= BitLeft(bits, leftShift); + } + --pdst; + *pdst = MROP_MASK(bits1, *pdst, startmask); + } + } + } +#endif + } + pbox++; + pptSrc++; + } + if (pboxNew2) + { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) + { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } +} diff --git a/cfb/cfbbres.c b/cfb/cfbbres.c new file mode 100644 index 000000000..139a868b7 --- /dev/null +++ b/cfb/cfbbres.c @@ -0,0 +1,233 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* $Xorg: cfbbres.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ +#include "X.h" +#include "misc.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "servermd.h" +#include "miline.h" + +/* Solid bresenham line */ +/* NOTES + e2 is used less often than e1, so it's not in a register +*/ + +void +cfbBresS(rop, and, xor, addrl, nlwidth, signdx, signdy, axis, x1, y1, e, e1, + e2, len) + int rop; + unsigned long and, xor; + unsigned long *addrl; /* pointer to base of bitmap */ + int nlwidth; /* width in longwords of bitmap */ + register int signdx; + int signdy; /* signs of directions */ + int axis; /* major axis (Y_AXIS or X_AXIS) */ + int x1, y1; /* initial point */ + register int e; /* error accumulator */ + register int e1; /* bresenham increments */ + int e2; + int len; /* length of line */ +{ + register int e3 = e2-e1; +#ifdef PIXEL_ADDR + register PixelType *addrp; /* Pixel pointer */ + + if (len == 0) + return; + /* point to first point */ + nlwidth <<= PWSH; + addrp = (PixelType *)(addrl) + (y1 * nlwidth) + x1; + if (signdy < 0) + nlwidth = -nlwidth; + e = e-e1; /* to make looping easier */ + + if (axis == Y_AXIS) + { + int t; + + t = nlwidth; + nlwidth = signdx; + signdx = t; + } + if (rop == GXcopy) + { + --len; +#define body {\ + *addrp = xor; \ + addrp += signdx; \ + e += e1; \ + if (e >= 0) \ + { \ + addrp += nlwidth; \ + e += e3; \ + } \ + } + while (len >= 4) + { + body body body body + len -= 4; + } + switch (len) + { + case 3: body case 2: body case 1: body + } +#undef body + *addrp = xor; + } + else /* not GXcopy */ + { + while(len--) + { + *addrp = DoRRop (*addrp, and, xor); + e += e1; + if (e >= 0) + { + addrp += nlwidth; + e += e3; + } + addrp += signdx; + } + } +#else /* !PIXEL_ADDR */ + register unsigned long tmp, bit; + unsigned long leftbit, rightbit; + + /* point to longword containing first point */ + addrl = (addrl + (y1 * nlwidth) + (x1 >> PWSH)); + if (signdy < 0) + nlwidth = -nlwidth; + e = e-e1; /* to make looping easier */ + + leftbit = cfbmask[0]; + rightbit = cfbmask[PPW-1]; + bit = cfbmask[x1 & PIM]; + + if (axis == X_AXIS) + { + if (signdx > 0) + { + while (len--) + { + *addrl = DoMaskRRop (*addrl, and, xor, bit); + bit = SCRRIGHT(bit,1); + e += e1; + if (e >= 0) + { + addrl += nlwidth; + e += e3; + } + if (!bit) + { + bit = leftbit; + addrl++; + } + } + } + else + { + while (len--) + { + *addrl = DoMaskRRop (*addrl, and, xor, bit); + e += e1; + bit = SCRLEFT(bit,1); + if (e >= 0) + { + addrl += nlwidth; + e += e3; + } + if (!bit) + { + bit = rightbit; + addrl--; + } + } + } + } /* if X_AXIS */ + else + { + if (signdx > 0) + { + while(len--) + { + *addrl = DoMaskRRop (*addrl, and, xor, bit); + e += e1; + if (e >= 0) + { + bit = SCRRIGHT(bit,1); + if (!bit) + { + bit = leftbit; + addrl++; + } + e += e3; + } + addrl += nlwidth; + } + } + else + { + while(len--) + { + *addrl = DoMaskRRop (*addrl, and, xor, bit); + e += e1; + if (e >= 0) + { + bit = SCRLEFT(bit,1); + if (!bit) + { + bit = rightbit; + addrl--; + } + e += e3; + } + addrl += nlwidth; + } + } + } /* else Y_AXIS */ +#endif +} diff --git a/cfb/cfbbresd.c b/cfb/cfbbresd.c new file mode 100644 index 000000000..6612803ae --- /dev/null +++ b/cfb/cfbbresd.c @@ -0,0 +1,258 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* $Xorg: cfbbresd.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ +#include "X.h" +#include "misc.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "miline.h" + +/* Dashed bresenham line */ + +void +cfbBresD(rrops, + pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash, + addrl, nlwidth, + signdx, signdy, axis, x1, y1, e, e1, e2, len) + cfbRRopPtr rrops; + int *pdashIndex; /* current dash */ + unsigned char *pDash; /* dash list */ + int numInDashList; /* total length of dash list */ + int *pdashOffset; /* offset into current dash */ + int isDoubleDash; + unsigned long *addrl; /* pointer to base of bitmap */ + int nlwidth; /* width in longwords of bitmap */ + int signdx, signdy; /* signs of directions */ + int axis; /* major axis (Y_AXIS or X_AXIS) */ + int x1, y1; /* initial point */ + register int e; /* error accumulator */ + register int e1; /* bresenham increments */ + int e2; + int len; /* length of line */ +{ +#ifdef PIXEL_ADDR + register PixelType *addrp; +#endif + register int e3 = e2-e1; + int dashIndex; + int dashOffset; + int dashRemaining; + unsigned long xorFg, andFg, xorBg, andBg; + Bool isCopy; + int thisDash; + + dashOffset = *pdashOffset; + dashIndex = *pdashIndex; + isCopy = (rrops[0].rop == GXcopy && rrops[1].rop == GXcopy); + xorFg = rrops[0].xor; + andFg = rrops[0].and; + xorBg = rrops[1].xor; + andBg = rrops[1].and; + dashRemaining = pDash[dashIndex] - dashOffset; + if ((thisDash = dashRemaining) >= len) + { + thisDash = len; + dashRemaining -= len; + } + e = e-e1; /* to make looping easier */ + +#define BresStep(minor,major) {if ((e += e1) >= 0) { e += e3; minor; } major;} + +#define NextDash {\ + dashIndex++; \ + if (dashIndex == numInDashList) \ + dashIndex = 0; \ + dashRemaining = pDash[dashIndex]; \ + if ((thisDash = dashRemaining) >= len) \ + { \ + dashRemaining -= len; \ + thisDash = len; \ + } \ +} + +#ifdef PIXEL_ADDR + +#define Loop(store) while (thisDash--) {\ + store; \ + BresStep(addrp+=signdy,addrp+=signdx) \ + } + /* point to first point */ + nlwidth <<= PWSH; + addrp = (PixelType *)(addrl) + (y1 * nlwidth) + x1; + signdy *= nlwidth; + if (axis == Y_AXIS) + { + int t; + + t = signdx; + signdx = signdy; + signdy = t; + } + + if (isCopy) + { + for (;;) + { + len -= thisDash; + if (dashIndex & 1) { + if (isDoubleDash) { + Loop(*addrp = xorBg) + } else { + Loop(;) + } + } else { + Loop(*addrp = xorFg) + } + if (!len) + break; + NextDash + } + } + else + { + for (;;) + { + len -= thisDash; + if (dashIndex & 1) { + if (isDoubleDash) { + Loop(*addrp = DoRRop(*addrp,andBg, xorBg)) + } else { + Loop(;) + } + } else { + Loop(*addrp = DoRRop(*addrp,andFg, xorFg)) + } + if (!len) + break; + NextDash + } + } +#else /* !PIXEL_ADDR */ + { + register unsigned long tmp; + unsigned long startbit, bit; + + /* point to longword containing first point */ + addrl = (addrl + (y1 * nlwidth) + (x1 >> PWSH)); + signdy = signdy * nlwidth; + + if (signdx > 0) + startbit = cfbmask[0]; + else + startbit = cfbmask[PPW-1]; + bit = cfbmask[x1 & PIM]; + +#define X_Loop(store) while(thisDash--) {\ + store; \ + BresStep(addrl += signdy, \ + if (signdx > 0) \ + bit = SCRRIGHT(bit,1); \ + else \ + bit = SCRLEFT(bit,1); \ + if (!bit) \ + { \ + bit = startbit; \ + addrl += signdx; \ + }) \ + } +#define Y_Loop(store) while(thisDash--) {\ + store; \ + BresStep(if (signdx > 0) \ + bit = SCRRIGHT(bit,1); \ + else \ + bit = SCRLEFT(bit,1); \ + if (!bit) \ + { \ + bit = startbit; \ + addrl += signdx; \ + }, \ + addrl += signdy) \ + } + + if (axis == X_AXIS) + { + for (;;) + { + len -= thisDash; + if (dashIndex & 1) { + if (isDoubleDash) { + X_Loop(*addrl = DoMaskRRop(*addrl, andBg, xorBg, bit)); + } else { + X_Loop(;) + } + } else { + X_Loop(*addrl = DoMaskRRop(*addrl, andFg, xorFg, bit)); + } + if (!len) + break; + NextDash + } + } /* if X_AXIS */ + else + { + for (;;) + { + len -= thisDash; + if (dashIndex & 1) { + if (isDoubleDash) { + Y_Loop(*addrl = DoMaskRRop(*addrl, andBg, xorBg, bit)); + } else { + Y_Loop(;) + } + } else { + Y_Loop(*addrl = DoMaskRRop(*addrl, andFg, xorFg, bit)); + } + if (!len) + break; + NextDash + } + } /* else Y_AXIS */ + } +#endif + *pdashIndex = dashIndex; + *pdashOffset = pDash[dashIndex] - dashRemaining; +} diff --git a/cfb/cfbbstore.c b/cfb/cfbbstore.c new file mode 100644 index 000000000..ae0303dce --- /dev/null +++ b/cfb/cfbbstore.c @@ -0,0 +1,147 @@ +/*- + * cfbbstore.c -- + * Functions required by the backing-store implementation in MI. + * + * Copyright (c) 1987 by the Regents of the University of California + * + * 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. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * + */ +/* $Xorg: cfbbstore.c,v 1.3 2000/08/17 19:48:13 cpqbld Exp $ */ + +#include "cfb.h" +#include "X.h" +#include "mibstore.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" + +/*- + *----------------------------------------------------------------------- + * cfbSaveAreas -- + * Function called by miSaveAreas to actually fetch the areas to be + * saved into the backing pixmap. This is very simple to do, since + * cfbDoBitblt is designed for this very thing. The region to save is + * already destination-relative and we're given the offset to the + * window origin, so we have only to create an array of points of the + * u.l. corners of the boxes in the region translated to the screen + * coordinate system and fetch the screen pixmap out of its devPrivate + * field.... + * + * Results: + * None. + * + * Side Effects: + * Data are copied from the screen into the pixmap. + * + *----------------------------------------------------------------------- + */ +void +cfbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin) + PixmapPtr pPixmap; /* Backing pixmap */ + RegionPtr prgnSave; /* Region to save (pixmap-relative) */ + int xorg; /* X origin of region */ + int yorg; /* Y origin of region */ + WindowPtr pWin; +{ + register DDXPointPtr pPt; + DDXPointPtr pPtsInit; + register BoxPtr pBox; + register int i; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + PixmapPtr pScrPix; + + i = REGION_NUM_RECTS(prgnSave); + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnSave); + pPt = pPtsInit; + while (--i >= 0) { + pPt->x = pBox->x1 + xorg; + pPt->y = pBox->y1 + yorg; + pPt++; + pBox++; + } + +#ifdef CFB_NEED_SCREEN_PRIVATE + pScrPix = (PixmapPtr) pScreen->devPrivates[cfbScreenPrivateIndex].ptr; +#else + pScrPix = (PixmapPtr) pScreen->devPrivate; +#endif + + cfbDoBitbltCopy((DrawablePtr) pScrPix, (DrawablePtr)pPixmap, + GXcopy, prgnSave, pPtsInit, ~0L); + + DEALLOCATE_LOCAL (pPtsInit); +} + +/*- + *----------------------------------------------------------------------- + * cfbRestoreAreas -- + * Function called by miRestoreAreas to actually fetch the areas to be + * restored from the backing pixmap. This is very simple to do, since + * cfbDoBitblt is designed for this very thing. The region to restore is + * already destination-relative and we're given the offset to the + * window origin, so we have only to create an array of points of the + * u.l. corners of the boxes in the region translated to the pixmap + * coordinate system and fetch the screen pixmap out of its devPrivate + * field.... + * + * Results: + * None. + * + * Side Effects: + * Data are copied from the pixmap into the screen. + * + *----------------------------------------------------------------------- + */ +void +cfbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin) + PixmapPtr pPixmap; /* Backing pixmap */ + RegionPtr prgnRestore; /* Region to restore (screen-relative)*/ + int xorg; /* X origin of window */ + int yorg; /* Y origin of window */ + WindowPtr pWin; +{ + register DDXPointPtr pPt; + DDXPointPtr pPtsInit; + register BoxPtr pBox; + register int i; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + PixmapPtr pScrPix; + + i = REGION_NUM_RECTS(prgnRestore); + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnRestore); + pPt = pPtsInit; + while (--i >= 0) { + pPt->x = pBox->x1 - xorg; + pPt->y = pBox->y1 - yorg; + pPt++; + pBox++; + } + +#ifdef CFB_NEED_SCREEN_PRIVATE + pScrPix = (PixmapPtr) pScreen->devPrivates[cfbScreenPrivateIndex].ptr; +#else + pScrPix = (PixmapPtr) pScreen->devPrivate; +#endif + + cfbDoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix, + GXcopy, prgnRestore, pPtsInit, ~0L); + + DEALLOCATE_LOCAL (pPtsInit); +} diff --git a/cfb/cfbcmap.c b/cfb/cfbcmap.c new file mode 100644 index 000000000..103860e86 --- /dev/null +++ b/cfb/cfbcmap.c @@ -0,0 +1,587 @@ +/* $Xorg: cfbcmap.c,v 1.3 2000/08/17 19:48:13 cpqbld Exp $ */ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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 "Xproto.h" +#include "scrnintstr.h" +#include "colormapst.h" +#include "resource.h" + +#ifdef STATIC_COLOR + +static ColormapPtr InstalledMaps[MAXSCREENS]; + +int +cfbListInstalledColormaps(pScreen, pmaps) + ScreenPtr pScreen; + Colormap *pmaps; +{ + /* By the time we are processing requests, we can guarantee that there + * is always a colormap installed */ + *pmaps = InstalledMaps[pScreen->myNum]->mid; + return (1); +} + + +void +cfbInstallColormap(pmap) + ColormapPtr pmap; +{ + int index = pmap->pScreen->myNum; + ColormapPtr oldpmap = InstalledMaps[index]; + + if(pmap != oldpmap) + { + /* Uninstall pInstalledMap. No hardware changes required, just + * notify all interested parties. */ + if(oldpmap != (ColormapPtr)None) + WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); + /* Install pmap */ + InstalledMaps[index] = pmap; + WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); + + } +} + +void +cfbUninstallColormap(pmap) + ColormapPtr pmap; +{ + int index = pmap->pScreen->myNum; + ColormapPtr curpmap = InstalledMaps[index]; + + if(pmap == curpmap) + { + if (pmap->mid != pmap->pScreen->defColormap) + { + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + (*pmap->pScreen->InstallColormap)(curpmap); + } + } +} + +#endif + +void +cfbResolveColor(pred, pgreen, pblue, pVisual) + unsigned short *pred, *pgreen, *pblue; + register VisualPtr pVisual; +{ + int shift = 16 - pVisual->bitsPerRGBValue; + unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1; + + if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor)) + { + /* rescale to rgb bits */ + *pred = ((*pred >> shift) * 65535) / lim; + *pgreen = ((*pgreen >> shift) * 65535) / lim; + *pblue = ((*pblue >> shift) * 65535) / lim; + } + else if (pVisual->class == GrayScale) + { + /* rescale to gray then rgb bits */ + *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; + *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; + } + else if (pVisual->class == StaticGray) + { + unsigned limg = pVisual->ColormapEntries - 1; + /* rescale to gray then [0..limg] then [0..65535] then rgb bits */ + *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; + *pred = ((((*pred * (limg + 1))) >> 16) * 65535) / limg; + *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; + } + else + { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + limg = pVisual->greenMask >> pVisual->offsetGreen; + limb = pVisual->blueMask >> pVisual->offsetBlue; + /* rescale to [0..limN] then [0..65535] then rgb bits */ + *pred = ((((((*pred * (limr + 1)) >> 16) * + 65535) / limr) >> shift) * 65535) / lim; + *pgreen = ((((((*pgreen * (limg + 1)) >> 16) * + 65535) / limg) >> shift) * 65535) / lim; + *pblue = ((((((*pblue * (limb + 1)) >> 16) * + 65535) / limb) >> shift) * 65535) / lim; + } +} + +Bool +cfbInitializeColormap(pmap) + register ColormapPtr pmap; +{ + register unsigned i; + register VisualPtr pVisual; + unsigned lim, maxent, shift; + + pVisual = pmap->pVisual; + lim = (1 << pVisual->bitsPerRGBValue) - 1; + shift = 16 - pVisual->bitsPerRGBValue; + maxent = pVisual->ColormapEntries - 1; + if (pVisual->class == TrueColor) + { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + limg = pVisual->greenMask >> pVisual->offsetGreen; + limb = pVisual->blueMask >> pVisual->offsetBlue; + for(i = 0; i <= maxent; i++) + { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = + ((((i * 65535) / limr) >> shift) * 65535) / lim; + pmap->green[i].co.local.green = + ((((i * 65535) / limg) >> shift) * 65535) / lim; + pmap->blue[i].co.local.blue = + ((((i * 65535) / limb) >> shift) * 65535) / lim; + } + } + else if (pVisual->class == StaticColor) + { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + limg = pVisual->greenMask >> pVisual->offsetGreen; + limb = pVisual->blueMask >> pVisual->offsetBlue; + for(i = 0; i <= maxent; i++) + { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = + ((((((i & pVisual->redMask) >> pVisual->offsetRed) + * 65535) / limr) >> shift) * 65535) / lim; + pmap->red[i].co.local.green = + ((((((i & pVisual->greenMask) >> pVisual->offsetGreen) + * 65535) / limg) >> shift) * 65535) / lim; + pmap->red[i].co.local.blue = + ((((((i & pVisual->blueMask) >> pVisual->offsetBlue) + * 65535) / limb) >> shift) * 65535) / lim; + } + } + else if (pVisual->class == StaticGray) + { + for(i = 0; i <= maxent; i++) + { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) + * 65535) / lim; + pmap->red[i].co.local.green = pmap->red[i].co.local.red; + pmap->red[i].co.local.blue = pmap->red[i].co.local.red; + } + } + return TRUE; +} + +/* When simulating DirectColor on PseudoColor hardware, multiple + entries of the colormap must be updated + */ + +#define AddElement(mask) { \ + pixel = red | green | blue; \ + for (i = 0; i < nresult; i++) \ + if (outdefs[i].pixel == pixel) \ + break; \ + if (i == nresult) \ + { \ + nresult++; \ + outdefs[i].pixel = pixel; \ + outdefs[i].flags = 0; \ + } \ + outdefs[i].flags |= (mask); \ + outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \ + outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \ + outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \ +} + +cfbExpandDirectColors (pmap, ndef, indefs, outdefs) + ColormapPtr pmap; + int ndef; + xColorItem *indefs, *outdefs; +{ + int minred, mingreen, minblue; + register int red, green, blue; + int maxred, maxgreen, maxblue; + int stepred, stepgreen, stepblue; + VisualPtr pVisual; + register int pixel; + register int nresult; + register int i; + + pVisual = pmap->pVisual; + + stepred = 1 << pVisual->offsetRed; + stepgreen = 1 << pVisual->offsetGreen; + stepblue = 1 << pVisual->offsetBlue; + maxred = pVisual->redMask; + maxgreen = pVisual->greenMask; + maxblue = pVisual->blueMask; + nresult = 0; + for (;ndef--; indefs++) + { + if (indefs->flags & DoRed) + { + red = indefs->pixel & pVisual->redMask; + for (green = 0; green <= maxgreen; green += stepgreen) + { + for (blue = 0; blue <= maxblue; blue += stepblue) + { + AddElement (DoRed) + } + } + } + if (indefs->flags & DoGreen) + { + green = indefs->pixel & pVisual->greenMask; + for (red = 0; red <= maxred; red += stepred) + { + for (blue = 0; blue <= maxblue; blue += stepblue) + { + AddElement (DoGreen) + } + } + } + if (indefs->flags & DoBlue) + { + blue = indefs->pixel & pVisual->blueMask; + for (red = 0; red <= maxred; red += stepred) + { + for (green = 0; green <= maxgreen; green += stepgreen) + { + AddElement (DoBlue) + } + } + } + } + return nresult; +} + +Bool +cfbCreateDefColormap(pScreen) + ScreenPtr pScreen; +{ +/* + * In the following sources PC X server vendors may want to delete + * "_not_tog" from "#ifdef WIN32_not_tog" + */ +#ifdef WIN32_not_tog + /* + * these are the MS-Windows desktop colors, adjusted for X's 16-bit + * color specifications. + */ + static xColorItem citems[] = { + { 0, 0, 0, 0, 0, 0 }, + { 1, 0x8000, 0, 0, 0, 0 }, + { 2, 0, 0x8000, 0, 0, 0 }, + { 3, 0x8000, 0x8000, 0, 0, 0 }, + { 4, 0, 0, 0x8000, 0, 0 }, + { 5, 0x8000, 0, 0x8000, 0, 0 }, + { 6, 0, 0x8000, 0x8000, 0, 0 }, + { 7, 0xc000, 0xc000, 0xc000, 0, 0 }, + { 8, 0xc000, 0xdc00, 0xc000, 0, 0 }, + { 9, 0xa600, 0xca00, 0xf000, 0, 0 }, + { 246, 0xff00, 0xfb00, 0xf000, 0, 0 }, + { 247, 0xa000, 0xa000, 0xa400, 0, 0 }, + { 248, 0x8000, 0x8000, 0x8000, 0, 0 }, + { 249, 0xff00, 0, 0, 0, 0 }, + { 250, 0, 0xff00, 0, 0, 0 }, + { 251, 0xff00, 0xff00, 0, 0, 0 }, + { 252, 0, 0, 0xff00, 0, 0 }, + { 253, 0xff00, 0, 0xff00, 0, 0 }, + { 254, 0, 0xff00, 0xff00, 0, 0 }, + { 255, 0xff00, 0xff00, 0xff00, 0, 0 } + }; +#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0] + int i; +#else + unsigned short zero = 0, ones = 0xFFFF; +#endif + Pixel wp, bp; + VisualPtr pVisual; + ColormapPtr cmap; + + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++) + ; + + if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, + (pVisual->class & DynamicClass) ? AllocNone : AllocAll, + 0) + != Success) + return FALSE; + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; +#ifdef WIN32_not_tog + for (i = 0; i < NUM_DESKTOP_COLORS; i++) { + if (AllocColor (cmap, + &citems[i].red, &citems[i].green, &citems[i].blue, + &citems[i].pixel, 0) != Success) + return FALSE; + } +#else + if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != + Success) || + (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != + Success)) + return FALSE; + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; +#endif + (*pScreen->InstallColormap)(cmap); + return TRUE; +} + +extern int defaultColorVisualClass; + +#define _RZ(d) ((d + 2) / 3) +#define _RS(d) 0 +#define _RM(d) ((1 << _RZ(d)) - 1) +#define _GZ(d) ((d - _RZ(d) + 1) / 2) +#define _GS(d) _RZ(d) +#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d)) +#define _BZ(d) (d - _RZ(d) - _GZ(d)) +#define _BS(d) (_RZ(d) + _GZ(d)) +#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d)) +#define _CE(d) (1 << _RZ(d)) + +#define MAX_PSEUDO_DEPTH 10 /* largest DAC size I know */ + +#define StaticGrayMask (1 << StaticGray) +#define GrayScaleMask (1 << GrayScale) +#define StaticColorMask (1 << StaticColor) +#define PseudoColorMask (1 << PseudoColor) +#define TrueColorMask (1 << TrueColor) +#define DirectColorMask (1 << DirectColor) + +#define ALL_VISUALS (StaticGrayMask|\ + GrayScaleMask|\ + StaticColorMask|\ + PseudoColorMask|\ + TrueColorMask|\ + DirectColorMask) + +#define LARGE_VISUALS (TrueColorMask|\ + DirectColorMask) + +typedef struct _cfbVisuals { + struct _cfbVisuals *next; + int depth; + int bitsPerRGB; + int visuals; + int count; +} cfbVisualsRec, *cfbVisualsPtr; + +static int cfbVisualPriority[] = { + PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray +}; + +#define NUM_PRIORITY 6 + +static cfbVisualsPtr cfbVisuals; + +Bool +cfbSetVisualTypes (depth, visuals, bitsPerRGB) + int depth; + int visuals; +{ + cfbVisualsPtr new, *prev, v; + int count; + + new = (cfbVisualsPtr) xalloc (sizeof *new); + if (!new) + return FALSE; + new->next = 0; + new->depth = depth; + new->visuals = visuals; + new->bitsPerRGB = bitsPerRGB; + count = (visuals >> 1) & 033333333333; + count = visuals - count - ((count >> 1) & 033333333333); + count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ + new->count = count; + for (prev = &cfbVisuals; v = *prev; prev = &v->next); + *prev = new; + return TRUE; +} + +/* + * Given a list of formats for a screen, create a list + * of visuals and depths for the screen which coorespond to + * the set which can be used with this version of cfb. + */ + +Bool +cfbInitVisuals (visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, sizes, bitsPerRGB) + VisualPtr *visualp; + DepthPtr *depthp; + int *nvisualp, *ndepthp; + int *rootDepthp; + VisualID *defaultVisp; + unsigned long sizes; + int bitsPerRGB; +{ + int i, j, k; + VisualPtr visual; + DepthPtr depth; + VisualID *vid; + int d, b; + int f; + int ndepth, nvisual; + int nvtype; + int vtype; + VisualID defaultVisual; + cfbVisualsPtr visuals, nextVisuals; + + /* none specified, we'll guess from pixmap formats */ + if (!cfbVisuals) + { + for (f = 0; f < screenInfo.numPixmapFormats; f++) + { + d = screenInfo.formats[f].depth; + b = screenInfo.formats[f].bitsPerPixel; + if (sizes & (1 << (b - 1))) + { + if (d > MAX_PSEUDO_DEPTH) + vtype = LARGE_VISUALS; + else if (d == 1) + vtype = StaticGrayMask; + else + vtype = ALL_VISUALS; + } + else + vtype = 0; + if (!cfbSetVisualTypes (d, vtype, bitsPerRGB)) + return FALSE; + } + } + nvisual = 0; + ndepth = 0; + for (visuals = cfbVisuals; visuals; visuals = nextVisuals) + { + nextVisuals = visuals->next; + ndepth++; + nvisual += visuals->count; + } + depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec)); + visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec)); + if (!depth || !visual) + { + xfree (depth); + xfree (visual); + return FALSE; + } + *depthp = depth; + *visualp = visual; + *ndepthp = ndepth; + *nvisualp = nvisual; + for (visuals = cfbVisuals; visuals; visuals = nextVisuals) + { + nextVisuals = visuals->next; + d = visuals->depth; + vtype = visuals->visuals; + nvtype = visuals->count; + vid = NULL; + if (nvtype) + { + vid = (VisualID *) xalloc (nvtype * sizeof (VisualID)); + if (!vid) + return FALSE; + } + depth->depth = d; + depth->numVids = nvtype; + depth->vids = vid; + depth++; + for (i = 0; i < NUM_PRIORITY; i++) { + if (! (vtype & (1 << cfbVisualPriority[i]))) + continue; + visual->class = cfbVisualPriority[i]; + visual->bitsPerRGBValue = visuals->bitsPerRGB; + visual->ColormapEntries = 1 << d; + visual->nplanes = d; + visual->vid = *vid = FakeClientID (0); + switch (visual->class) { + case PseudoColor: + case GrayScale: + case StaticGray: + visual->redMask = 0; + visual->greenMask = 0; + visual->blueMask = 0; + visual->offsetRed = 0; + visual->offsetGreen = 0; + visual->offsetBlue = 0; + break; + case DirectColor: + case TrueColor: + visual->ColormapEntries = _CE(d); + /* fall through */ + case StaticColor: + visual->redMask = _RM(d); + visual->greenMask = _GM(d); + visual->blueMask = _BM(d); + visual->offsetRed = _RS(d); + visual->offsetGreen = _GS(d); + visual->offsetBlue = _BS(d); + } + vid++; + visual++; + } + xfree (visuals); + } + cfbVisuals = NULL; + visual = *visualp; + depth = *depthp; + for (i = 0; i < ndepth; i++) + { + if (*rootDepthp && *rootDepthp != depth[i].depth) + continue; + for (j = 0; j < depth[i].numVids; j++) + { + for (k = 0; k < nvisual; k++) + if (visual[k].vid == depth[i].vids[j]) + break; + if (k == nvisual) + continue; + if (defaultColorVisualClass < 0 || + visual[k].class == defaultColorVisualClass) + break; + } + if (j != depth[i].numVids) + break; + } + if (i == ndepth) { + i = 0; + j = 0; + } + *rootDepthp = depth[i].depth; + *defaultVisp = depth[i].vids[j]; + return TRUE; +} diff --git a/cfb/cfbfillarc.c b/cfb/cfbfillarc.c new file mode 100644 index 000000000..89d184983 --- /dev/null +++ b/cfb/cfbfillarc.c @@ -0,0 +1,265 @@ +/************************************************************ + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +/* $Xorg: cfbfillarc.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xprotostr.h" +#include "miscstruct.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "mifillarc.h" +#include "cfbrrop.h" +#include "mi.h" + +/* gcc 1.35 is stupid */ +#if defined(__GNUC__) && defined(mc68020) +#define STUPID volatile +#else +#define STUPID +#endif + +static void +RROP_NAME(cfbFillEllipseSolid) (pDraw, pGC, arc) + DrawablePtr pDraw; + GCPtr pGC; + xArc *arc; +{ + STUPID int x, y, e; + STUPID int yk, xk, ym, xm, dx, dy, xorg, yorg; + miFillArcRec info; + unsigned long *addrlt, *addrlb; + register unsigned long *addrl; + register int n; + int nlwidth; + RROP_DECLARE + register int xpos; + register int slw; + unsigned long startmask, endmask; + int nlmiddle; + + cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt) + + RROP_FETCH_GC(pGC); + miFillArcSetup(arc, &info); + MIFILLARCSETUP(); + xorg += pDraw->x; + yorg += pDraw->y; + addrlb = addrlt; + addrlt += nlwidth * (yorg - y); + addrlb += nlwidth * (yorg + y + dy); + while (y) + { + addrlt += nlwidth; + addrlb -= nlwidth; + MIFILLARCSTEP(slw); + if (!slw) + continue; + xpos = xorg - x; + addrl = addrlt + (xpos >> PWSH); + if (((xpos & PIM) + slw) <= PPW) + { + maskpartialbits(xpos, slw, startmask); + RROP_SOLID_MASK(addrl,startmask); + if (miFillArcLower(slw)) + { + addrl = addrlb + (xpos >> PWSH); + RROP_SOLID_MASK(addrl, startmask); + } + continue; + } + maskbits(xpos, slw, startmask, endmask, nlmiddle); + if (startmask) + { + RROP_SOLID_MASK(addrl, startmask); + addrl++; + } + n = nlmiddle; + RROP_SPAN(addrl,n) + + if (endmask) + RROP_SOLID_MASK(addrl, endmask); + if (!miFillArcLower(slw)) + continue; + addrl = addrlb + (xpos >> PWSH); + if (startmask) + { + RROP_SOLID_MASK(addrl, startmask); + addrl++; + } + n = nlmiddle; + RROP_SPAN(addrl, n); + if (endmask) + RROP_SOLID_MASK(addrl, endmask); + } +} + +#define FILLSPAN(xl,xr,addr) \ + if (xr >= xl) \ + { \ + n = xr - xl + 1; \ + addrl = addr + (xl >> PWSH); \ + if (((xl & PIM) + n) <= PPW) \ + { \ + maskpartialbits(xl, n, startmask); \ + RROP_SOLID_MASK(addrl, startmask); \ + } \ + else \ + { \ + maskbits(xl, n, startmask, endmask, n); \ + if (startmask) \ + { \ + RROP_SOLID_MASK(addrl, startmask); \ + addrl++; \ + } \ + while (n--) \ + { \ + RROP_SOLID(addrl); \ + ++addrl; \ + } \ + if (endmask) \ + RROP_SOLID_MASK(addrl, endmask); \ + } \ + } + +#define FILLSLICESPANS(flip,addr) \ + if (!flip) \ + { \ + FILLSPAN(xl, xr, addr); \ + } \ + else \ + { \ + xc = xorg - x; \ + FILLSPAN(xc, xr, addr); \ + xc += slw - 1; \ + FILLSPAN(xl, xc, addr); \ + } + +static void +RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc) + DrawablePtr pDraw; + GCPtr pGC; + xArc *arc; +{ + int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; + register int x, y, e; + miFillArcRec info; + miArcSliceRec slice; + int xl, xr, xc; + unsigned long *addrlt, *addrlb; + register unsigned long *addrl; + register int n; + int nlwidth; + RROP_DECLARE + unsigned long startmask, endmask; + + cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt) + + RROP_FETCH_GC(pGC); + miFillArcSetup(arc, &info); + miFillArcSliceSetup(arc, &slice, pGC); + MIFILLARCSETUP(); + xorg += pDraw->x; + yorg += pDraw->y; + addrlb = addrlt; + addrlt += nlwidth * (yorg - y); + addrlb += nlwidth * (yorg + y + dy); + slice.edge1.x += pDraw->x; + slice.edge2.x += pDraw->x; + while (y > 0) + { + addrlt += nlwidth; + addrlb -= nlwidth; + MIFILLARCSTEP(slw); + MIARCSLICESTEP(slice.edge1); + MIARCSLICESTEP(slice.edge2); + if (miFillSliceUpper(slice)) + { + MIARCSLICEUPPER(xl, xr, slice, slw); + FILLSLICESPANS(slice.flip_top, addrlt); + } + if (miFillSliceLower(slice)) + { + MIARCSLICELOWER(xl, xr, slice, slw); + FILLSLICESPANS(slice.flip_bot, addrlb); + } + } +} + +void +RROP_NAME(cfbPolyFillArcSolid) (pDraw, pGC, narcs, parcs) + DrawablePtr pDraw; + GCPtr pGC; + int narcs; + xArc *parcs; +{ + register xArc *arc; + register int i; + int x2, y2; + BoxRec box; + RegionPtr cclip; + + cclip = cfbGetCompositeClip(pGC); + for (arc = parcs, i = narcs; --i >= 0; arc++) + { + if (miFillArcEmpty(arc)) + continue; + if (miCanFillArc(arc)) + { + box.x1 = arc->x + pDraw->x; + box.y1 = arc->y + pDraw->y; + /* + * Because box.x2 and box.y2 get truncated to 16 bits, and the + * RECT_IN_REGION test treats the resulting number as a signed + * integer, the RECT_IN_REGION test alone can go the wrong way. + * This can result in a server crash because the rendering + * routines in this file deal directly with cpu addresses + * of pixels to be stored, and do not clip or otherwise check + * that all such addresses are within their respective pixmaps. + * So we only allow the RECT_IN_REGION test to be used for + * values that can be expressed correctly in a signed short. + */ + x2 = box.x1 + (int)arc->width + 1; + box.x2 = x2; + y2 = box.y1 + (int)arc->height + 1; + box.y2 = y2; + if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) && + (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) + { + if ((arc->angle2 >= FULLCIRCLE) || + (arc->angle2 <= -FULLCIRCLE)) + RROP_NAME(cfbFillEllipseSolid)(pDraw, pGC, arc); + else + RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc); + continue; + } + } + miPolyFillArc(pDraw, pGC, 1, arc); + } +} diff --git a/cfb/cfbfillrct.c b/cfb/cfbfillrct.c new file mode 100644 index 000000000..a0b72e7c4 --- /dev/null +++ b/cfb/cfbfillrct.c @@ -0,0 +1,286 @@ +/* + * Fill rectangles. + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* $Xorg: cfbfillrct.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "mergerop.h" + + +void +cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot) + DrawablePtr pDrawable; + int n; + BoxPtr rects; + PixmapPtr tile; + int xrot, yrot; +{ + if (tile->drawable.width & PIM) + cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L); + else + cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L); +} + +void +cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; + BoxPtr pBox; +{ + int xrot, yrot; + void (*fill)(); + + xrot = pDrawable->x + pGC->patOrg.x; + yrot = pDrawable->y + pGC->patOrg.y; + if (pGC->tile.pixmap->drawable.width & PIM) + { + fill = cfbFillBoxTileOddGeneral; + if ((pGC->planemask & PMSK) == PMSK) + { + if (pGC->alu == GXcopy) + fill = cfbFillBoxTileOddCopy; + } + } + else + { + fill = cfbFillBoxTile32sGeneral; + if ((pGC->planemask & PMSK) == PMSK) + { + if (pGC->alu == GXcopy) + fill = cfbFillBoxTile32sCopy; + } + } + (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask); +} + +#define NUM_STACK_RECTS 1024 + +void +cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit) + DrawablePtr pDrawable; + register GCPtr pGC; + int nrectFill; /* number of rectangles to fill */ + xRectangle *prectInit; /* Pointer to first rectangle to fill */ +{ + xRectangle *prect; + RegionPtr prgnClip; + register BoxPtr pbox; + register BoxPtr pboxClipped; + BoxPtr pboxClippedBase; + BoxPtr pextent; + BoxRec stackRects[NUM_STACK_RECTS]; + cfbPrivGC *priv; + int numRects; + void (*BoxFill)(); + int n; + int xorg, yorg; + + priv = cfbGetGCPrivate(pGC); + prgnClip = priv->pCompositeClip; + + BoxFill = 0; + switch (pGC->fillStyle) + { + case FillSolid: + switch (priv->rop) { + case GXcopy: + BoxFill = cfbFillRectSolidCopy; + break; + case GXxor: + BoxFill = cfbFillRectSolidXor; + break; + default: + BoxFill = cfbFillRectSolidGeneral; + break; + } + break; + case FillTiled: + if (!cfbGetGCPrivate(pGC)->pRotatedPixmap) + BoxFill = cfbFillRectTileOdd; + else + { + if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK) + BoxFill = cfbFillRectTile32Copy; + else + BoxFill = cfbFillRectTile32General; + } + break; +#if PSZ == 8 + case FillStippled: + if (!cfbGetGCPrivate(pGC)->pRotatedPixmap) + BoxFill = cfb8FillRectStippledUnnatural; + else + BoxFill = cfb8FillRectTransparentStippled32; + break; + case FillOpaqueStippled: + if (!cfbGetGCPrivate(pGC)->pRotatedPixmap) + BoxFill = cfb8FillRectStippledUnnatural; + else + BoxFill = cfb8FillRectOpaqueStippled32; + break; +#endif + } + prect = prectInit; + 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 = 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) + (*BoxFill) (pDrawable, pGC, + pboxClipped-pboxClippedBase, pboxClippedBase); + if (pboxClippedBase != stackRects) + DEALLOCATE_LOCAL(pboxClippedBase); +} diff --git a/cfb/cfbfillsp.c b/cfb/cfbfillsp.c new file mode 100644 index 000000000..b0de9bd7d --- /dev/null +++ b/cfb/cfbfillsp.c @@ -0,0 +1,960 @@ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ + +/* $Xorg: cfbfillsp.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" + +#include "mergerop.h" + +#if PSZ == 8 +#include "cfb8bit.h" +#endif + +#define MFB_CONSTS_ONLY +#include "maskbits.h" + +#include "mi.h" +#include "mispans.h" + +/* scanline filling for color frame buffer + written by drewry, oct 1986 modified by smarks + changes for compatibility with Little-endian systems Jul 1987; MIT:yba. + + these routines all clip. they assume that anything that has called +them has already translated the points (i.e. pGC->miTranslate is +non-zero, which is howit gets set in cfbCreateGC().) + + the number of new scnalines created by clipping == +MaxRectsPerBand * nSpans. + + FillSolid is overloaded to be used for OpaqueStipple as well, +if fgPixel == bgPixel. +Note that for solids, PrivGC.rop == PrivGC.ropOpStip + + + FillTiled is overloaded to be used for OpaqueStipple, if +fgPixel != bgPixel. based on the fill style, it uses +{RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip} +*/ + +#ifdef notdef +#include <stdio.h> +static +dumpspans(n, ppt, pwidth) + int n; + DDXPointPtr ppt; + int *pwidth; +{ + fprintf(stderr,"%d spans\n", n); + while (n--) { + fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth); + ppt++; + pwidth++; + } + fprintf(stderr, "\n"); +} +#endif + +/* Fill spans with tiles that aren't 32 bits wide */ +void +cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) +DrawablePtr pDrawable; +GC *pGC; +int nInit; /* number of spans to fill */ +DDXPointPtr pptInit; /* pointer to list of start points */ +int *pwidthInit; /* pointer to list of n widths */ +int fSorted; +{ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + void (*fill)(); + int xrot, yrot; + + if (!(pGC->planemask)) + return; + + if (pGC->tile.pixmap->drawable.width & PIM) + { + fill = cfbFillSpanTileOddGeneral; + if ((pGC->planemask & PMSK) == PMSK) + { + if (pGC->alu == GXcopy) + fill = cfbFillSpanTileOddCopy; + } + } + else + { + fill = cfbFillSpanTile32sGeneral; + if ((pGC->planemask & PMSK) == PMSK) + { + if (pGC->alu == GXcopy) + fill = cfbFillSpanTile32sCopy; + } + } + n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) ); + if ( n == 0 ) + return; + pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!ppt || !pwidth) + { + if (ppt) DEALLOCATE_LOCAL(ppt); + if (pwidth) DEALLOCATE_LOCAL(pwidth); + return; + } + n = miClipSpans( cfbGetCompositeClip(pGC), + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + xrot = pDrawable->x + pGC->patOrg.x; + yrot = pDrawable->y + pGC->patOrg.y; + + (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask); + + DEALLOCATE_LOCAL(ppt); + DEALLOCATE_LOCAL(pwidth); +} + +#if PSZ == 8 + +void +cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) +DrawablePtr pDrawable; +GC *pGC; +int nInit; /* number of spans to fill */ +DDXPointPtr pptInit; /* pointer to list of start points */ +int *pwidthInit; /* pointer to list of n widths */ +int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + DDXPointPtr ppt; /* pointer to list of start points */ + int *pwidth; /* pointer to list of n widths */ + int *pwidthFree;/* copies of the pointers to free */ + DDXPointPtr pptFree; + unsigned long *pdstBase; /* pointer to start of bitmap */ + int nlwDst; /* width in longwords of bitmap */ + register unsigned long *pdst; /* pointer to current word in bitmap */ + PixmapPtr pStipple; /* pointer to stipple we want to fill with */ + int nlw; + int x, y, w, xrem, xSrc, ySrc; + int stwidth, stippleWidth; + int stippleHeight; + register unsigned long bits, inputBits; + register int partBitsLeft; + int nextPartBits; + int bitsLeft, bitsWhole; + unsigned long *srcTemp, *srcStart; + unsigned long *psrcBase; + unsigned long startmask, endmask; + + if (pGC->fillStyle == FillStippled) + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); + else + cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); + + if (cfb8StippleRRop == GXnoop) + return; + + n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) ); + if ( n == 0 ) + return; + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans( cfbGetCompositeClip(pGC), + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + /* + * OK, so what's going on here? We have two Drawables: + * + * The Stipple: + * Depth = 1 + * Width = stippleWidth + * Words per scanline = stwidth + * Pointer to pixels = pStipple->devPrivate.ptr + */ + + pStipple = pGC->stipple; + + stwidth = pStipple->devKind >> PWSH; + stippleWidth = pStipple->drawable.width; + stippleHeight = pStipple->drawable.height; + psrcBase = (unsigned long *) pStipple->devPrivate.ptr; + + /* + * The Target: + * Depth = PSZ + * Width = determined from *pwidth + * Words per scanline = nlwDst + * Pointer to pixels = addrlBase + */ + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase) + + /* 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. + */ + + modulus (pGC->patOrg.x, stippleWidth, xSrc); + xSrc += pDrawable->x - stippleWidth; + modulus (pGC->patOrg.y, stippleHeight, ySrc); + ySrc += pDrawable->y - stippleHeight; + + bitsWhole = stippleWidth; + + while (n--) + { + x = ppt->x; + y = ppt->y; + ppt++; + w = *pwidth++; + pdst = pdstBase + y * nlwDst + (x >> PWSH); + y = (y - ySrc) % stippleHeight; + srcStart = psrcBase + y * stwidth; + xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth; + srcTemp = srcStart + (xrem >> MFB_PWSH); + bitsLeft = stippleWidth - (xrem & ~MFB_PIM); + xrem &= MFB_PIM; + NextUnnaturalStippleWord + if (partBitsLeft < xrem) + FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d", + partBitsLeft, xrem); + NextSomeBits (inputBits, xrem); + partBitsLeft -= xrem; + if (((x & PIM) + w) <= PPW) + { + maskpartialbits (x, w, startmask) + NextUnnaturalStippleBits + *pdst = MaskRRopPixels(*pdst,bits,startmask); + } + else + { + maskbits (x, w, startmask, endmask, nlw); + nextPartBits = (x & (PGSZB-1)) + w; + if (nextPartBits < partBitsLeft) + { + if (startmask) + { + MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask) + pdst++; + NextBitGroup (inputBits); + } + while (nlw--) + { + RRopBitGroup (pdst, GetBitGroup (inputBits)); + pdst++; + NextBitGroup (inputBits); + } + if (endmask) + { + MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask) + } + } + else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft) + { + NextUnnaturalStippleBitsFast + if (startmask) + { + *pdst = MaskRRopPixels(*pdst,bits,startmask); + pdst++; + NextUnnaturalStippleBitsFast + } + while (nlw--) + { + *pdst = RRopPixels(*pdst,bits); + pdst++; + NextUnnaturalStippleBitsFast + } + if (endmask) + *pdst = MaskRRopPixels (*pdst,bits,endmask); + } + else + { + NextUnnaturalStippleBits + if (startmask) + { + *pdst = MaskRRopPixels(*pdst,bits,startmask); + pdst++; + NextUnnaturalStippleBits + } + while (nlw--) + { + *pdst = RRopPixels(*pdst,bits); + pdst++; + NextUnnaturalStippleBits + } + if (endmask) + *pdst = MaskRRopPixels(*pdst,bits,endmask); + } + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +#else /* PSZ != 8 */ + +/* Fill spans with stipples that aren't 32 bits wide */ +void +cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) +DrawablePtr pDrawable; +GC *pGC; +int nInit; /* number of spans to fill */ +DDXPointPtr pptInit; /* pointer to list of start points */ +int *pwidthInit; /* pointer to list of n widths */ +int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + register DDXPointPtr ppt; /* pointer to list of start points */ + register int *pwidth; /* pointer to list of n widths */ + int iline; /* first line of tile to use */ + unsigned long *addrlBase; /* pointer to start of bitmap */ + int nlwidth; /* width in longwords of bitmap */ + register unsigned long *pdst; /* pointer to current word in bitmap */ + PixmapPtr pStipple; /* pointer to stipple we want to fill with */ + register int w; + int width, x, xrem, xSrc, ySrc; + unsigned long tmpSrc, tmpDst1, tmpDst2; + int stwidth, stippleWidth; + unsigned long *psrcS; + int rop, stiprop; + int stippleHeight; + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + unsigned long fgfill, bgfill; + + if (!(pGC->planemask)) + return; + + n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) ); + if ( n == 0 ) + return; + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans( cfbGetCompositeClip(pGC), + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + rop = pGC->alu; + if (pGC->fillStyle == FillStippled) { + switch (rop) { + case GXand: + case GXcopy: + case GXnoop: + case GXor: + stiprop = rop; + break; + default: + stiprop = rop; + rop = GXcopy; + } + } + fgfill = PFILL(pGC->fgPixel); + bgfill = PFILL(pGC->bgPixel); + + /* + * OK, so what's going on here? We have two Drawables: + * + * The Stipple: + * Depth = 1 + * Width = stippleWidth + * Words per scanline = stwidth + * Pointer to pixels = pStipple->devPrivate.ptr + */ + pStipple = pGC->stipple; + + stwidth = pStipple->devKind / PGSZB; + stippleWidth = pStipple->drawable.width; + stippleHeight = pStipple->drawable.height; + + /* + * The Target: + * Depth = PSZ + * Width = determined from *pwidth + * Words per scanline = nlwidth + * Pointer to pixels = addrlBase + */ + + cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase) + + /* 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. + */ + modulus (pGC->patOrg.x, stippleWidth, xSrc); + xSrc += pDrawable->x - stippleWidth; + modulus (pGC->patOrg.y, stippleHeight, ySrc); + ySrc += pDrawable->y - stippleHeight; + + while (n--) + { + iline = (ppt->y - ySrc) % stippleHeight; + x = ppt->x; + pdst = addrlBase + (ppt->y * nlwidth); + psrcS = (unsigned long *) pStipple->devPrivate.ptr + (iline * stwidth); + + if (*pwidth) + { + width = *pwidth; + while(width > 0) + { + int xtemp, tmpx; + register unsigned long *ptemp; + register unsigned long *pdsttmp; + /* + * Do a stripe through the stipple & destination w pixels + * wide. w is not more than: + * - the width of the destination + * - the width of the stipple + * - the distance between x and the next word + * boundary in the destination + * - the distance between x and the next word + * boundary in the stipple + */ + + /* width of dest/stipple */ + xrem = (x - xSrc) % stippleWidth; + w = min((stippleWidth - xrem), width); + /* dist to word bound in dest */ + w = min(w, PPW - (x & PIM)); + /* dist to word bound in stip */ + w = min(w, MFB_PPW - (x & MFB_PIM)); + + xtemp = (xrem & MFB_PIM); + ptemp = (unsigned long *)(psrcS + (xrem >> MFB_PWSH)); + tmpx = x & PIM; + pdsttmp = pdst + (x>>PWSH); + switch ( pGC->fillStyle ) { + case FillOpaqueStippled: + getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1); + getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2); + break; + case FillStippled: + /* Fill tmpSrc with the source pixels */ + getbits(pdsttmp, tmpx, w, tmpSrc); + getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1); + if (rop != stiprop) { + putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop); + } else { + tmpSrc = fgfill; + } + getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2); + break; + } + tmpDst2 |= tmpDst1; + putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop); + x += w; + width -= w; + } + } + ppt++; + pwidth++; + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +#endif /* PSZ == 8 */ + +#if PSZ == 8 + +void +cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + DDXPointPtr ppt; /* pointer to list of start points */ + int *pwidth; /* pointer to list of n widths */ + unsigned long *src; /* pointer to bits in stipple, if needed */ + int stippleHeight; /* height of the stipple */ + PixmapPtr stipple; + + int nlwDst; /* width in longwords of the dest pixmap */ + int x,y,w; /* current span */ + unsigned long startmask; + unsigned long endmask; + register unsigned long *dst; /* pointer to bits we're writing */ + register int nlw; + unsigned long *dstTmp; + int nlwTmp; + + unsigned long *pbits; /* pointer to start of pixmap */ + register unsigned long xor; + register unsigned long mask; + register unsigned long bits; /* bits from stipple */ + int wEnd; + + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); + n = nInit * miFindMaxBand(devPriv->pCompositeClip); + if ( n == 0 ) + return; + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(devPriv->pCompositeClip, + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + stipple = devPriv->pRotatedPixmap; + src = (unsigned long *)stipple->devPrivate.ptr; + stippleHeight = stipple->drawable.height; + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + + while (n--) + { + w = *pwidth++; + x = ppt->x; + y = ppt->y; + ppt++; + dst = pbits + (y * nlwDst) + (x >> PWSH); + if (((x & PIM) + w) <= PPW) + { + maskpartialbits(x, w, startmask); + endmask = 0; + nlw = 0; + } + else + { + maskbits (x, w, startmask, endmask, nlw); + } + bits = src[y % stippleHeight]; + RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM))); + if (cfb8StippleRRop == GXcopy) + { + xor = devPriv->xor; + if (w < (PGSZ*2)) + { + if (startmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dst = (*dst & ~(mask & startmask)) | + (xor & (mask & startmask)); + dst++; + RotBitsLeft (bits, PGSZB); + } + while (nlw--) + { + WriteBitGroup (dst,xor,GetBitGroup(bits)) + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dst = (*dst & ~(mask & endmask)) | + (xor & (mask & endmask)); + } + } + else + { /* XXX constants probably not OK here */ + wEnd = 7 - (nlw & 7); + nlw = (nlw >> 3) + 1; + dstTmp = dst; + nlwTmp = nlw; + if (startmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dstTmp = (*dstTmp & ~(mask & startmask)) | + (xor & (mask & startmask)); + dstTmp++; + RotBitsLeft (bits, PGSZB); + } + w = 7 - wEnd; + while (w--) + { + dst = dstTmp; + dstTmp++; + nlw = nlwTmp; +#if defined(__GNUC__) && defined(mc68020) + mask = cfb8PixelMasks[GetBitGroup(bits)]; + xor = xor & mask; + mask = ~mask; + while (nlw--) + { + *dst = (*dst & mask) | xor; + dst += 8; + } + xor = devPriv->xor; +#else +#define SwitchBitsLoop(body) \ + while (nlw--) \ + { \ + body \ + dst += 8; \ + } + SwitchBitGroup(dst, xor, GetBitGroup(bits)); +#undef SwitchBitsLoop +#endif + NextBitGroup (bits); + } + nlwTmp--; + w = wEnd + 1; + if (endmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + dst = dstTmp + (nlwTmp << 3); + *dst = (*dst & ~(mask & endmask)) | + (xor & (mask & endmask)); + } + while (w--) + { + nlw = nlwTmp; + dst = dstTmp; + dstTmp++; +#if defined(__GNUC__) && defined(mc68020) + mask = cfb8PixelMasks[GetBitGroup(bits)]; + xor = xor & mask; + mask = ~mask; + while (nlw--) + { + *dst = (*dst & mask) | xor; + dst += 8; + } + xor = devPriv->xor; +#else +#define SwitchBitsLoop(body) \ + while (nlw--) \ + { \ + body \ + dst += 8; \ + } + SwitchBitGroup(dst, xor, GetBitGroup(bits)); +#undef SwitchBitsLoop +#endif + NextBitGroup (bits); + } + } + } + else + { + if (startmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, startmask); + dst++; + RotBitsLeft (bits, PGSZB); + } + while (nlw--) + { + RRopBitGroup(dst, GetBitGroup(bits)); + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, endmask); + } + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +void +cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + DDXPointPtr ppt; /* pointer to list of start points */ + int *pwidth; /* pointer to list of n widths */ + unsigned long *src; /* pointer to bits in stipple, if needed */ + int stippleHeight; /* height of the stipple */ + PixmapPtr stipple; + + int nlwDst; /* width in longwords of the dest pixmap */ + int x,y,w; /* current span */ + unsigned long startmask; + unsigned long endmask; + register unsigned long *dst; /* pointer to bits we're writing */ + register int nlw; + unsigned long *dstTmp; + int nlwTmp; + + unsigned long *pbits; /* pointer to start of pixmap */ + register unsigned long xor; + register unsigned long mask; + register unsigned long bits; /* bits from stipple */ + int wEnd; + + int *pwidthFree; /* copies of the pointers to free */ + DDXPointPtr pptFree; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); + + cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); + + n = nInit * miFindMaxBand(devPriv->pCompositeClip); + if ( n == 0 ) + return; + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(devPriv->pCompositeClip, + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + stipple = devPriv->pRotatedPixmap; + src = (unsigned long *)stipple->devPrivate.ptr; + stippleHeight = stipple->drawable.height; + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + + while (n--) + { + w = *pwidth++; + x = ppt->x; + y = ppt->y; + ppt++; + dst = pbits + (y * nlwDst) + (x >> PWSH); + if (((x & PIM) + w) <= PPW) + { + maskpartialbits(x, w, startmask); + endmask = 0; + nlw = 0; + } + else + { + maskbits (x, w, startmask, endmask, nlw); + } + bits = src[y % stippleHeight]; + RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM))); + if (cfb8StippleRRop == GXcopy) + { + xor = devPriv->xor; + if (w < PGSZ*2) + { + if (startmask) + { + *dst = *dst & ~startmask | + GetPixelGroup (bits) & startmask; + dst++; + RotBitsLeft (bits, PGSZB); + } + while (nlw--) + { + *dst++ = GetPixelGroup(bits); + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + *dst = *dst & ~endmask | + GetPixelGroup (bits) & endmask; + } + } + else + { /* XXX consts probably not OK here */ + wEnd = 7 - (nlw & 7); + nlw = (nlw >> 3) + 1; + dstTmp = dst; + nlwTmp = nlw; + if (startmask) + { + *dstTmp = *dstTmp & ~startmask | + GetPixelGroup (bits) & startmask; + dstTmp++; + RotBitsLeft (bits, PGSZB); + } + w = 7 - wEnd; + while (w--) + { + nlw = nlwTmp; + dst = dstTmp; + dstTmp++; + xor = GetPixelGroup (bits); + while (nlw--) + { + *dst = xor; + dst += 8; + } + NextBitGroup (bits); + } + nlwTmp--; + w = wEnd + 1; + if (endmask) + { + dst = dstTmp + (nlwTmp << 3); + *dst = (*dst & ~endmask) | + GetPixelGroup (bits) & endmask; + } + while (w--) + { + nlw = nlwTmp; + dst = dstTmp; + dstTmp++; + xor = GetPixelGroup (bits); + while (nlw--) + { + *dst = xor; + dst += 8; + } + NextBitGroup (bits); + } + } + } + else + { + if (startmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, startmask); + dst++; + RotBitsLeft (bits, PGSZB); + } + while (nlw--) + { + RRopBitGroup(dst, GetBitGroup(bits)); + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, endmask); + } + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} + +#endif /* PSZ == 8 */ diff --git a/cfb/cfbgc.c b/cfb/cfbgc.c new file mode 100644 index 000000000..62e0cbd76 --- /dev/null +++ b/cfb/cfbgc.c @@ -0,0 +1,791 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ + +/* $Xorg: cfbgc.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "region.h" + +#include "mistruct.h" +#include "mibstore.h" +#include "migc.h" + +#include "cfbmskbits.h" +#include "cfb8bit.h" + +#if PSZ == 8 +# define useTEGlyphBlt cfbTEGlyphBlt8 +#else +# ifdef WriteBitGroup +# define useTEGlyphBlt cfbImageGlyphBlt8 +# else +# define useTEGlyphBlt cfbTEGlyphBlt +# endif +#endif + +#ifdef WriteBitGroup +# define useImageGlyphBlt cfbImageGlyphBlt8 +# define usePolyGlyphBlt cfbPolyGlyphBlt8 +#else +# define useImageGlyphBlt miImageGlyphBlt +# define usePolyGlyphBlt miPolyGlyphBlt +#endif + +#ifdef FOUR_BIT_CODE +# define usePushPixels cfbPushPixels8 +#else +#ifndef LOWMEMFTPT +# define usePushPixels mfbPushPixels +#else +# define usePushPixels miPushPixels +#endif /* ifndef LOWMEMFTPT */ +#endif + +#ifdef PIXEL_ADDR +# define ZeroPolyArc cfbZeroPolyArcSS8Copy +#else +# define ZeroPolyArc miZeroPolyArc +#endif + +GCFuncs cfbGCFuncs = { + cfbValidateGC, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip, +}; + +GCOps cfbTEOps1Rect = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfbCopyArea, + cfbCopyPlane, + cfbPolyPoint, +#ifdef PIXEL_ADDR + cfb8LineSS1Rect, + cfb8SegmentSS1Rect, +#else + cfbLineSS, + cfbSegmentSS, +#endif + miPolyRectangle, + ZeroPolyArc, + cfbFillPoly1RectCopy, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useTEGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +GCOps cfbNonTEOps1Rect = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfbCopyArea, + cfbCopyPlane, + cfbPolyPoint, +#ifdef PIXEL_ADDR + cfb8LineSS1Rect, + cfb8SegmentSS1Rect, +#else + cfbLineSS, + cfbSegmentSS, +#endif + miPolyRectangle, + ZeroPolyArc, + cfbFillPoly1RectCopy, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useImageGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +GCOps cfbTEOps = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfbCopyArea, + cfbCopyPlane, + cfbPolyPoint, + cfbLineSS, + cfbSegmentSS, + miPolyRectangle, + ZeroPolyArc, + miFillPolygon, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useTEGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +GCOps cfbNonTEOps = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfbCopyArea, + cfbCopyPlane, + cfbPolyPoint, + cfbLineSS, + cfbSegmentSS, + miPolyRectangle, +#ifdef PIXEL_ADDR + cfbZeroPolyArcSS8Copy, +#else + miZeroPolyArc, +#endif + miFillPolygon, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useImageGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +GCOps * +cfbMatchCommon (pGC, devPriv) + GCPtr pGC; + cfbPrivGCPtr devPriv; +{ + if (pGC->lineWidth != 0) + return 0; + if (pGC->lineStyle != LineSolid) + return 0; + if (pGC->fillStyle != FillSolid) + return 0; + if (devPriv->rop != GXcopy) + return 0; + if (pGC->font && + FONTMAXBOUNDS(pGC->font,rightSideBearing) - + FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 && + FONTMINBOUNDS(pGC->font,characterWidth) >= 0) + { + if (TERMINALFONT(pGC->font) +#ifdef FOUR_BIT_CODE + && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB +#endif + ) +#ifdef NO_ONE_RECT + return &cfbTEOps1Rect; +#else + if (devPriv->oneRect) + return &cfbTEOps1Rect; + else + return &cfbTEOps; +#endif + else +#ifdef NO_ONE_RECT + return &cfbNonTEOps1Rect; +#else + if (devPriv->oneRect) + return &cfbNonTEOps1Rect; + else + return &cfbNonTEOps; +#endif + } + return 0; +} + +Bool +cfbCreateGC(pGC) + register GCPtr pGC; +{ + cfbPrivGC *pPriv; + + if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD) + return (mfbCreateGC(pGC)); + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + /* + * some of the output primitives aren't really necessary, since they + * will be filled in ValidateGC because of dix/CreateGC() setting all + * the change bits. Others are necessary because although they depend + * on being a color frame buffer, they don't change + */ + + pGC->ops = &cfbNonTEOps; + pGC->funcs = &cfbGCFuncs; + + /* cfb wants to translate before scan conversion */ + pGC->miTranslate = 1; + + pPriv = cfbGetGCPrivate(pGC); + pPriv->rop = pGC->alu; + pPriv->oneRect = FALSE; + pPriv->fExpose = TRUE; + pPriv->freeCompClip = FALSE; + pPriv->pRotatedPixmap = (PixmapPtr) NULL; + return TRUE; +} + +/* Clipping conventions + if the drawable is a window + CT_REGION ==> pCompositeClip really is the composite + CT_other ==> pCompositeClip is the window clip region + if the drawable is a pixmap + CT_REGION ==> pCompositeClip is the translated client region + clipped to the pixmap boundary + CT_other ==> pCompositeClip is the pixmap bounding box +*/ + +void +cfbValidateGC(pGC, changes, pDrawable) + register GCPtr pGC; + unsigned long changes; + DrawablePtr pDrawable; +{ + int mask; /* stateChanges */ + int index; /* used for stepping through bitfields */ + int new_rrop; + int new_line, new_text, new_fillspans, new_fillarea; + int new_rotate; + int xrot, yrot; + /* flags for changing the proc vector */ + cfbPrivGCPtr devPriv; + int oneRect; + + new_rotate = pGC->lastWinOrg.x != pDrawable->x || + pGC->lastWinOrg.y != pDrawable->y; + + pGC->lastWinOrg.x = pDrawable->x; + pGC->lastWinOrg.y = pDrawable->y; + devPriv = cfbGetGCPrivate(pGC); + + new_rrop = FALSE; + new_line = FALSE; + new_text = FALSE; + new_fillspans = FALSE; + new_fillarea = FALSE; + + /* + * 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); +#ifdef NO_ONE_RECT + devPriv->oneRect = FALSE; +#else + oneRect = REGION_NUM_RECTS(devPriv->pCompositeClip) == 1; + if (oneRect != devPriv->oneRect) + new_line = TRUE; + devPriv->oneRect = oneRect; +#endif + } + + mask = changes; + while (mask) { + index = lowbit (mask); + mask &= ~index; + + /* + * this switch acculmulates a list of which procedures might have + * to change due to changes in the GC. in some cases (e.g. + * changing one 16 bit tile for another) we might not really need + * a change, but the code is being paranoid. this sort of batching + * wins if, for example, the alu and the font have been changed, + * or any other pair of items that both change the same thing. + */ + switch (index) { + case GCFunction: + case GCForeground: + new_rrop = TRUE; + break; + case GCPlaneMask: + new_rrop = TRUE; + new_text = TRUE; + break; + case GCBackground: + break; + case GCLineStyle: + case GCLineWidth: + new_line = TRUE; + break; + case GCJoinStyle: + case GCCapStyle: + break; + case GCFillStyle: + new_text = TRUE; + new_fillspans = TRUE; + new_line = TRUE; + new_fillarea = TRUE; + break; + case GCFillRule: + break; + case GCTile: + new_fillspans = TRUE; + new_fillarea = TRUE; + break; + + case GCStipple: + if (pGC->stipple) + { + int width = pGC->stipple->drawable.width; + PixmapPtr nstipple; + + if ((width <= PGSZ) && !(width & (width - 1)) && + (nstipple = cfbCopyPixmap(pGC->stipple))) + { + cfbPadPixmap(nstipple); + (*pGC->pScreen->DestroyPixmap)(pGC->stipple); + pGC->stipple = nstipple; + } + } + new_fillspans = TRUE; + new_fillarea = TRUE; + break; + + case GCTileStipXOrigin: + new_rotate = TRUE; + break; + + case GCTileStipYOrigin: + new_rotate = TRUE; + break; + + case GCFont: + new_text = TRUE; + break; + case GCSubwindowMode: + break; + case GCGraphicsExposures: + break; + case GCClipXOrigin: + break; + case GCClipYOrigin: + break; + case GCClipMask: + break; + case GCDashOffset: + break; + case GCDashList: + break; + case GCArcMode: + break; + default: + break; + } + } + + /* + * If the drawable has changed, ensure suitable + * entries are in the proc vector. + */ + if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) { + new_fillspans = TRUE; /* deal with FillSpans later */ + } + + if (new_rotate || new_fillspans) + { + Bool new_pix = FALSE; + + xrot = pGC->patOrg.x + pDrawable->x; + yrot = pGC->patOrg.y + pDrawable->y; + + switch (pGC->fillStyle) + { + case FillTiled: + if (!pGC->tileIsPixel) + { + int width = pGC->tile.pixmap->drawable.width * PSZ; + + if ((width <= PGSZ) && !(width & (width - 1))) + { + cfbCopyRotatePixmap(pGC->tile.pixmap, + &devPriv->pRotatedPixmap, + xrot, yrot); + new_pix = TRUE; + } + } + break; +#ifdef FOUR_BIT_CODE + case FillStippled: + case FillOpaqueStippled: + { + int width = pGC->stipple->drawable.width; + + if ((width <= PGSZ) && !(width & (width - 1))) + { + mfbCopyRotatePixmap(pGC->stipple, + &devPriv->pRotatedPixmap, xrot, yrot); + new_pix = TRUE; + } + } + break; +#endif + } + if (!new_pix && devPriv->pRotatedPixmap) + { + (*pGC->pScreen->DestroyPixmap)(devPriv->pRotatedPixmap); + devPriv->pRotatedPixmap = (PixmapPtr) NULL; + } + } + + if (new_rrop) + { + int old_rrop; + + old_rrop = devPriv->rop; + devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel, + pGC->planemask, + &devPriv->and, &devPriv->xor); + if (old_rrop == devPriv->rop) + new_rrop = FALSE; + else + { +#ifdef PIXEL_ADDR + new_line = TRUE; +#endif +#ifdef WriteBitGroup + new_text = TRUE; +#endif + new_fillspans = TRUE; + new_fillarea = TRUE; + } + } + + if (new_rrop || new_fillspans || new_text || new_fillarea || new_line) + { + GCOps *newops; + + if (newops = cfbMatchCommon (pGC, devPriv)) + { + if (pGC->ops->devPrivate.val) + miDestroyGCOps (pGC->ops); + pGC->ops = newops; + new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0; + } + else + { + if (!pGC->ops->devPrivate.val) + { + pGC->ops = miCreateGCOps (pGC->ops); + pGC->ops->devPrivate.val = 1; + } + } + } + + /* deal with the changes we've collected */ + if (new_line) + { + pGC->ops->FillPolygon = miFillPolygon; +#ifdef NO_ONE_RECT + if (pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillPolygon = cfbFillPoly1RectCopy; + break; + default: + pGC->ops->FillPolygon = cfbFillPoly1RectGeneral; + break; + } + } +#else + if (devPriv->oneRect && pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillPolygon = cfbFillPoly1RectCopy; + break; + default: + pGC->ops->FillPolygon = cfbFillPoly1RectGeneral; + break; + } + } +#endif + if (pGC->lineWidth == 0) + { +#ifdef PIXEL_ADDR + if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)) + { + switch (devPriv->rop) + { + case GXxor: + pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor; + break; + case GXcopy: + pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy; + break; + default: + pGC->ops->PolyArc = cfbZeroPolyArcSS8General; + break; + } + } + else +#endif + pGC->ops->PolyArc = miZeroPolyArc; + } + else + pGC->ops->PolyArc = miPolyArc; + pGC->ops->PolySegment = miPolySegment; + switch (pGC->lineStyle) + { + case LineSolid: + if(pGC->lineWidth == 0) + { + if (pGC->fillStyle == FillSolid) + { +#if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT) + if (devPriv->oneRect && + ((pDrawable->x >= pGC->pScreen->width - 32768) && + (pDrawable->y >= pGC->pScreen->height - 32768))) + { + pGC->ops->Polylines = cfb8LineSS1Rect; + pGC->ops->PolySegment = cfb8SegmentSS1Rect; + } else +#endif +#ifdef NO_ONE_RECT + { + pGC->ops->Polylines = cfb8LineSS1Rect; + pGC->ops->PolySegment = cfb8SegmentSS1Rect; + } +#else + { + pGC->ops->Polylines = cfbLineSS; + pGC->ops->PolySegment = cfbSegmentSS; + } +#endif + } + else + pGC->ops->Polylines = miZeroLine; + } + else + pGC->ops->Polylines = miWideLine; + break; + case LineOnOffDash: + case LineDoubleDash: + if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) + { + pGC->ops->Polylines = cfbLineSD; + pGC->ops->PolySegment = cfbSegmentSD; + } else + pGC->ops->Polylines = miWideDash; + break; + } + } + + if (new_text && (pGC->font)) + { + if (FONTMAXBOUNDS(pGC->font,rightSideBearing) - + FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 || + FONTMINBOUNDS(pGC->font,characterWidth) < 0) + { + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + pGC->ops->ImageGlyphBlt = miImageGlyphBlt; + } + else + { +#ifdef WriteBitGroup + if (pGC->fillStyle == FillSolid) + { + if (devPriv->rop == GXcopy) + pGC->ops->PolyGlyphBlt = cfbPolyGlyphBlt8; + else +#ifdef FOUR_BIT_CODE + pGC->ops->PolyGlyphBlt = cfbPolyGlyphRop8; +#else + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; +#endif + } + else +#endif + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + /* special case ImageGlyphBlt for terminal emulator fonts */ +#if !defined(WriteBitGroup) || PSZ == 8 + if (TERMINALFONT(pGC->font) && + (pGC->planemask & PMSK) == PMSK +#ifdef FOUR_BIT_CODE + && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB +#endif + ) + { + pGC->ops->ImageGlyphBlt = useTEGlyphBlt; + } + else +#endif + { +#ifdef WriteBitGroup + if (devPriv->rop == GXcopy && + pGC->fillStyle == FillSolid && + (pGC->planemask & PMSK) == PMSK) + pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8; + else +#endif + pGC->ops->ImageGlyphBlt = miImageGlyphBlt; + } + } + } + + + if (new_fillspans) { + switch (pGC->fillStyle) { + case FillSolid: + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillSpans = cfbSolidSpansCopy; + break; + case GXxor: + pGC->ops->FillSpans = cfbSolidSpansXor; + break; + default: + pGC->ops->FillSpans = cfbSolidSpansGeneral; + break; + } + break; + case FillTiled: + if (devPriv->pRotatedPixmap) + { + if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK) + pGC->ops->FillSpans = cfbTile32FSCopy; + else + pGC->ops->FillSpans = cfbTile32FSGeneral; + } + else + pGC->ops->FillSpans = cfbUnnaturalTileFS; + break; + case FillStippled: +#ifdef FOUR_BIT_CODE + if (devPriv->pRotatedPixmap) + pGC->ops->FillSpans = cfb8Stipple32FS; + else +#endif + pGC->ops->FillSpans = cfbUnnaturalStippleFS; + break; + case FillOpaqueStippled: +#ifdef FOUR_BIT_CODE + if (devPriv->pRotatedPixmap) + pGC->ops->FillSpans = cfb8OpaqueStipple32FS; + else +#endif + pGC->ops->FillSpans = cfbUnnaturalStippleFS; + break; + default: + FatalError("cfbValidateGC: illegal fillStyle\n"); + } + } /* end of new_fillspans */ + + if (new_fillarea) { +#ifndef FOUR_BIT_CODE + pGC->ops->PolyFillRect = miPolyFillRect; + if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) + { + pGC->ops->PolyFillRect = cfbPolyFillRect; + } +#endif +#ifdef FOUR_BIT_CODE +#ifndef LOWMEMFTPT + pGC->ops->PushPixels = mfbPushPixels; +#else + pGC->ops->PushPixels = miPushPixels; +#endif /* ifndef LOWMEMFTPT */ + if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy) + pGC->ops->PushPixels = cfbPushPixels8; +#endif + pGC->ops->PolyFillArc = miPolyFillArc; + if (pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) + { + case GXcopy: + pGC->ops->PolyFillArc = cfbPolyFillArcSolidCopy; + break; + default: + pGC->ops->PolyFillArc = cfbPolyFillArcSolidGeneral; + break; + } + } + } +} diff --git a/cfb/cfbgetsp.c b/cfb/cfbgetsp.c new file mode 100644 index 000000000..a2c9966df --- /dev/null +++ b/cfb/cfbgetsp.c @@ -0,0 +1,164 @@ +/* $Xorg: cfbgetsp.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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 "Xmd.h" +#include "servermd.h" + +#include "misc.h" +#include "region.h" +#include "gc.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" + +/* GetSpans -- for each span, gets bits from drawable starting at ppt[i] + * and continuing for pwidth[i] bits + * Each scanline returned will be server scanline padded, i.e., it will come + * out to an integral number of words. + */ +void +cfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart) + DrawablePtr pDrawable; /* drawable from which to get bits */ + int wMax; /* largest value of all *pwidths */ + register DDXPointPtr ppt; /* points to start copying from */ + int *pwidth; /* list of number of bits to copy */ + int nspans; /* number of scanlines to copy */ + char *pchardstStart; /* where to put the bits */ +{ + PixelGroup *pdstStart = (PixelGroup *)pchardstStart; + register PixelGroup *pdst; /* where to put the bits */ + register PixelGroup *psrc; /* where to get the bits */ + register PixelGroup tmpSrc; /* scratch buffer for bits */ + PixelGroup *psrcBase; /* start of src bitmap */ + int widthSrc; /* width of pixmap in bytes */ + register DDXPointPtr pptLast; /* one past last point to get */ + int xEnd; /* last pixel to copy from */ + register int nstart; + int nend; + PixelGroup startmask, endmask; + int nlMiddle, nl, srcBit; + int w; + PixelGroup *pdstNext; + + switch (pDrawable->bitsPerPixel) { + case 1: + mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart); + return; + case PSZ: + break; + default: + FatalError("cfbGetSpans: invalid depth\n"); + } + + + cfbGetLongWidthAndPointer (pDrawable, widthSrc, psrcBase) + +#ifdef PIXEL_ADDR + if ((nspans == 1) && (*pwidth == 1)) + { + tmpSrc = *((PixelType *)(psrcBase + (ppt->y * widthSrc)) + + ppt->x); +#if BITMAP_BIT_ORDER == MSBFirst + tmpSrc <<= (sizeof (unsigned long) - sizeof (PixelType)) * 8; +#endif + *pdstStart = tmpSrc; + return; + } +#endif + pdst = pdstStart; + pptLast = ppt + nspans; + while(ppt < pptLast) + { + xEnd = min(ppt->x + *pwidth, widthSrc << PWSH); + psrc = psrcBase + ppt->y * widthSrc + (ppt->x >> PWSH); + w = xEnd - ppt->x; + srcBit = ppt->x & PIM; + pdstNext = pdst + ((w + PPW - 1) >> PWSH); + + if (srcBit + w <= PPW) + { + getbits(psrc, srcBit, w, tmpSrc); + putbits(tmpSrc, 0, w, pdst, ~((unsigned long)0)); + pdst++; + } + else + { + maskbits(ppt->x, w, startmask, endmask, nlMiddle); + nstart = 0; + if (startmask) + { + nstart = PPW - srcBit; + getbits(psrc, srcBit, nstart, tmpSrc); + putbits(tmpSrc, 0, nstart, pdst, ~((unsigned long)0)); + if(srcBit + nstart >= PPW) + psrc++; + } + nl = nlMiddle; + while (nl--) + { + tmpSrc = *psrc; + putbits(tmpSrc, nstart, PPW, pdst, ~((unsigned long)0)); + psrc++; + pdst++; + } + if (endmask) + { + nend = xEnd & PIM; + getbits(psrc, 0, nend, tmpSrc); + putbits(tmpSrc, nstart, nend, pdst, ~((unsigned long)0)); + } + pdst = pdstNext; + } + ppt++; + pwidth++; + } +} diff --git a/cfb/cfbglblt8.c b/cfb/cfbglblt8.c new file mode 100644 index 000000000..b87bc8513 --- /dev/null +++ b/cfb/cfbglblt8.c @@ -0,0 +1,441 @@ +/* $Xorg: cfbglblt8.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* + * Poly glyph blt. Accepts an arbitrary font <= 32 bits wide, in Copy mode + * only. + */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +#define BOX_OVERLAP(box1, box2, xoffset, yoffset) \ + ((box1)->x1 <= ((int) (box2)->x2 + (xoffset)) && \ + ((int) (box2)->x1 + (xoffset)) <= (box1)->x2 && \ + (box1)->y1 <= ((int) (box2)->y2 + (yoffset)) && \ + ((int) (box2)->y1 + (yoffset)) <= (box1)->y2) + +#define BOX_CONTAINS(box1, box2, xoffset, yoffset) \ + ((box1)->x1 <= ((int) (box2)->x1 + (xoffset)) && \ + ((int) (box2)->x2 + (xoffset)) <= (box1)->x2 && \ + (box1)->y1 <= ((int) (box2)->y1 + (yoffset)) && \ + ((int) (box2)->y2 + (yoffset)) <= (box1)->y2) + +#if defined(FOUR_BIT_CODE) || defined(WriteBitGroup) && !defined(GLYPHROP) + +#if GLYPHPADBYTES != 4 +#define USE_LEFTBITS +#endif + +#ifdef USE_LEFTBITS +typedef unsigned char *glyphPointer; +extern unsigned long endtab[]; + +#define GlyphBits(bits,width,dst) getleftbits(bits,width,dst); \ + (dst) &= widthMask; \ + (bits) += widthGlyph; +#define GlyphBitsS(bits,width,dst,off) GlyphBits(bits,width,dst); \ + dst = BitRight (dst, off); +#else +typedef CARD32 *glyphPointer; + +#define GlyphBits(bits,width,dst) dst = *bits++; +#define GlyphBitsS(bits,width,dst,off) dst = BitRight(*bits++, off); +#endif + +#ifdef GLYPHROP +#define cfbPolyGlyphBlt8 cfbPolyGlyphRop8 +#define cfbPolyGlyphBlt8Clipped cfbPolyGlyphRop8Clipped + +#undef WriteBitGroup +#define WriteBitGroup(dst,pixel,bits) RRopBitGroup(dst,bits) + +#endif + +static void cfbPolyGlyphBlt8Clipped(); + +#if defined(HAS_STIPPLE_CODE) && !defined(GLYPHROP) && !defined(USE_LEFTBITS) +#define USE_STIPPLE_CODE +#endif + +#if defined(__GNUC__) && !defined(GLYPHROP) && (defined(mc68020) || defined(mc68000) || defined(__mc68000__)) && !defined(USE_LEFTBITS) +#ifdef USE_STIPPLE_CODE +#undef USE_STIPPLE_CODE +#endif +#endif + +#define DST_INC (PGSZB >> PWSH) + +/* cfbStippleStack/cfbStippleStackTE are coded in assembly language. + * They are only provided on some architecures. + */ +#ifdef USE_STIPPLE_CODE +extern void cfbStippleStack (), cfbStippleStackTE (); +#endif + +void +cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + register unsigned long c; +#ifndef GLYPHROP + register unsigned long pixel; +#endif + register unsigned long *dst; + register glyphPointer glyphBits; + register int xoff; + + FontPtr pfont = pGC->font; + CharInfoPtr pci; + unsigned long *dstLine; + unsigned long *pdstBase; + int hTmp; + int bwidthDst; + int widthDst; + int h; + int ew; + BoxRec bbox; /* for clipping */ + int widthDiff; + int w; + RegionPtr clip; + BoxPtr extents; +#ifdef USE_LEFTBITS + int widthGlyph; + unsigned long widthMask; +#endif +#ifndef STIPPLE +#ifdef USE_STIPPLE_CODE + void (*stipple)(); + + stipple = cfbStippleStack; + if (FONTCONSTMETRICS(pfont)) + stipple = cfbStippleStackTE; +#endif +#endif + + x += pDrawable->x; + y += pDrawable->y; + + /* compute an approximate (but covering) bounding box */ + bbox.x1 = 0; + if ((ppci[0]->metrics.leftSideBearing < 0)) + bbox.x1 = ppci[0]->metrics.leftSideBearing; + h = nglyph - 1; + w = ppci[h]->metrics.rightSideBearing; + while (--h >= 0) + w += ppci[h]->metrics.characterWidth; + bbox.x2 = w; + bbox.y1 = -FONTMAXBOUNDS(pfont,ascent); + bbox.y2 = FONTMAXBOUNDS(pfont,descent); + + clip = cfbGetCompositeClip(pGC); + extents = &clip->extents; + + if (!clip->data) + { + if (!BOX_CONTAINS(extents, &bbox, x, y)) + { + if (BOX_OVERLAP (extents, &bbox, x, y)) + cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y, + nglyph, ppci, pglyphBase); + return; + } + } + else + { + /* check to make sure some of the text appears on the screen */ + if (!BOX_OVERLAP (extents, &bbox, x, y)) + return; + + bbox.x1 += x; + bbox.x2 += x; + bbox.y1 += y; + bbox.y2 += y; + + switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox)) + { + case rgnPART: + cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y, + nglyph, ppci, pglyphBase); + case rgnOUT: + return; + } + } + +#ifdef GLYPHROP + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); +#else + pixel = cfbGetGCPrivate(pGC)->xor; +#endif + + cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long) + + widthDst = bwidthDst / PGSZB; + while (nglyph--) + { + pci = *ppci++; + glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci); + xoff = x + pci->metrics.leftSideBearing; + dstLine = pdstBase + + (y - pci->metrics.ascent) * widthDst + (xoff >> PWSH); + x += pci->metrics.characterWidth; + if (hTmp = pci->metrics.descent + pci->metrics.ascent) + { + xoff &= PIM; +#ifdef STIPPLE + STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff); +#else +#ifdef USE_STIPPLE_CODE + (*stipple)(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff); +#else +#ifdef USE_LEFTBITS + w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; + widthGlyph = PADGLYPHWIDTHBYTES(w); + widthMask = endtab[w]; +#endif + do { + dst = dstLine; + dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst); + GlyphBits(glyphBits, w, c) + WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff))); + dst += DST_INC; + c = BitLeft(c,PGSZB - xoff); + while (c) + { + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst += DST_INC; + } + } while (--hTmp); +#endif /* USE_STIPPLE_CODE else */ +#endif /* STIPPLE else */ + } + } +} + +static void +cfbPolyGlyphBlt8Clipped (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + unsigned char *pglyphBase; /* start of array of glyphs */ +{ + register unsigned long c; +#ifndef GLYPHROP + register unsigned long pixel; +#endif + register unsigned long *dst; + register glyphPointer glyphBits; + register int xoff; + unsigned long c1; + + CharInfoPtr pci; + FontPtr pfont = pGC->font; + unsigned long *dstLine; + unsigned long *pdstBase; + CARD32 *cTmp, *clips; + int maxAscent, maxDescent; + int minLeftBearing; + int hTmp; + int widthDst; + int bwidthDst; + int ew; + int xG, yG; + BoxPtr pBox; + int numRects; + int widthDiff; + int w; + RegionPtr pRegion; + int yBand; +#ifdef GLYPHROP + unsigned long bits; +#endif +#ifdef USE_LEFTBITS + int widthGlyph; + unsigned long widthMask; +#endif + +#ifdef GLYPHROP + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); +#else + pixel = cfbGetGCPrivate(pGC)->xor; +#endif + + cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long) + + widthDst = bwidthDst / PGSZB; + maxAscent = FONTMAXBOUNDS(pfont,ascent); + maxDescent = FONTMAXBOUNDS(pfont,descent); + minLeftBearing = FONTMINBOUNDS(pfont,leftSideBearing); + + pRegion = cfbGetCompositeClip(pGC); + + pBox = REGION_RECTS(pRegion); + numRects = REGION_NUM_RECTS (pRegion); + while (numRects && pBox->y2 <= y - maxAscent) + { + ++pBox; + --numRects; + } + if (!numRects || pBox->y1 >= y + maxDescent) + return; + yBand = pBox->y1; + while (numRects && pBox->y1 == yBand && pBox->x2 <= x + minLeftBearing) + { + ++pBox; + --numRects; + } + if (!numRects) + return; + clips = (CARD32 *)ALLOCATE_LOCAL ((maxAscent + maxDescent) * + sizeof (CARD32)); + while (nglyph--) + { + pci = *ppci++; + glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci); + w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; + xG = x + pci->metrics.leftSideBearing; + yG = y - pci->metrics.ascent; + x += pci->metrics.characterWidth; + if (hTmp = pci->metrics.descent + pci->metrics.ascent) + { + dstLine = pdstBase + yG * widthDst + (xG >> PWSH); + xoff = xG & PIM; +#ifdef USE_LEFTBITS + w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; + widthGlyph = PADGLYPHWIDTHBYTES(w); + widthMask = endtab[w]; +#endif + switch (cfb8ComputeClipMasks32 (pBox, numRects, xG, yG, w, hTmp, clips)) + { + case rgnPART: +#ifdef USE_LEFTBITS + cTmp = clips; + do { + dst = dstLine; + dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst); + GlyphBits(glyphBits, w, c) + c &= *cTmp++; + if (c) + { + WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff))); + c = BitLeft(c,PGSZB - xoff); + dst += DST_INC; + while (c) + { + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst += DST_INC; + } + } + } while (--hTmp); + break; +#else /* !USE_LEFT_BITS */ + { + int h; + + h = hTmp; + do + { + --h; + clips[h] = clips[h] & glyphBits[h]; + } while (h); + } + glyphBits = clips; + /* fall through */ +#endif /* USE_LEFT_BITS */ + case rgnIN: +#ifdef STIPPLE + STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff); +#else +#ifdef USE_STIPPLE_CODE + cfbStippleStackTE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff); +#else + do { + dst = dstLine; + dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst); + GlyphBits(glyphBits, w, c) + if (c) + { + /* This code originally could read memory locations + * that were not mapped. Hence we have to check the + * trailing bits to see whether they are zero and if + * then skip them correctly. This is no problem for + * the GXcopy case, since there only the pixels that + * are non-zero are written ... + */ +#ifndef GLYPHROP + WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff))); + c = BitLeft(c,PGSZB - xoff); + dst += DST_INC; +#else /* GLYPHROP */ + if (bits = GetBitGroup(BitRight(c,xoff))) + WriteBitGroup(dst, pixel, bits); + c = BitLeft(c,PGSZB - xoff); + dst += DST_INC; + + while (c && ((bits = GetBitGroup(c)) == 0)) + { + NextBitGroup(c); + dst += DST_INC; + } +#endif /* GLYPHROP */ + while (c) + { + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst += DST_INC; + } + } + } while (--hTmp); +#endif /* USE_STIPPLE_CODE else */ +#endif /* STIPPLE else */ + break; + } + } + } + DEALLOCATE_LOCAL (clips); +} + +#endif /* FOUR_BIT_CODE */ diff --git a/cfb/cfbhrzvert.c b/cfb/cfbhrzvert.c new file mode 100644 index 000000000..3fe9262ad --- /dev/null +++ b/cfb/cfbhrzvert.c @@ -0,0 +1,179 @@ +/*********************************************************** + +Copyright 1987,1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* $Xorg: cfbhrzvert.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +#include "X.h" + +#include "gc.h" +#include "window.h" +#include "pixmap.h" +#include "region.h" + +#include "cfb.h" +#include "cfbmskbits.h" + +/* horizontal solid line + abs(len) > 1 +*/ +cfbHorzS(rop, and, xor, addrl, nlwidth, x1, y1, len) +register int rop; +register unsigned long and; +register unsigned long xor; +register unsigned long *addrl; /* pointer to base of bitmap */ +int nlwidth; /* width in longwords of bitmap */ +int x1; /* initial point */ +int y1; +int len; /* length of line */ +{ + register int nlmiddle; + register unsigned long startmask; + register unsigned long endmask; + + addrl = addrl + (y1 * nlwidth) + (x1 >> PWSH); + + /* all bits inside same longword */ + if ( ((x1 & PIM) + len) < PPW) + { + maskpartialbits(x1, len, startmask); + *addrl = DoMaskRRop (*addrl, and, xor, startmask); + } + else + { + maskbits(x1, len, startmask, endmask, nlmiddle); + if (rop == GXcopy) + { + if (startmask) + { + *addrl = (*addrl & ~startmask) | (xor & startmask); + addrl++; + } + while (nlmiddle--) + *addrl++ = xor; + if (endmask) + *addrl = (*addrl & ~endmask) | (xor & endmask); + } + else + { + if (startmask) + { + *addrl = DoMaskRRop (*addrl, and, xor, startmask); + addrl++; + } + if (rop == GXxor) + { + while (nlmiddle--) + *addrl++ ^= xor; + } + else + { + while (nlmiddle--) + { + *addrl = DoRRop (*addrl, and, xor); + addrl++; + } + } + if (endmask) + *addrl = DoMaskRRop (*addrl, and, xor, endmask); + } + } +} + +/* vertical solid line */ + +cfbVertS(rop, and, xor, addrl, nlwidth, x1, y1, len) +int rop; +register unsigned long and, xor; +register unsigned long *addrl; /* pointer to base of bitmap */ +register int nlwidth; /* width in longwords of bitmap */ +int x1, y1; /* initial point */ +register int len; /* length of line */ +{ +#ifdef PIXEL_ADDR + register PixelType *bits = (PixelType *) addrl; + + nlwidth <<= PWSH; + bits = bits + (y1 * nlwidth) + x1; + + /* + * special case copy and xor to avoid a test per pixel + */ + if (rop == GXcopy) + { + while (len--) + { + *bits = xor; + bits += nlwidth; + } + } + else if (rop == GXxor) + { + while (len--) + { + *bits ^= xor; + bits += nlwidth; + } + } + else + { + while (len--) + { + *bits = DoRRop(*bits, and, xor); + bits += nlwidth; + } + } +#else /* !PIXEL_ADDR */ + addrl = addrl + (y1 * nlwidth) + (x1 >> PWSH); + + and |= ~cfbmask[x1 & PIM]; + xor &= cfbmask[x1 & PIM]; + + while (len--) + { + *addrl = DoRRop (*addrl, and, xor); + addrl += nlwidth; + } +#endif +} diff --git a/cfb/cfbigblt8.c b/cfb/cfbigblt8.c new file mode 100644 index 000000000..7e20e2578 --- /dev/null +++ b/cfb/cfbigblt8.c @@ -0,0 +1,97 @@ +/* + * $Xorg: cfbigblt8.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +void +cfbImageGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; + pointer pglyphBase; +{ + ExtentInfoRec info; /* used by QueryGlyphExtents() */ + xRectangle backrect; + int fillStyle; + int alu; + int fgPixel; + int rop; + int xor; + int and; + int pm; + cfbPrivGC *priv; + + QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); + + if (info.overallWidth >= 0) + { + backrect.x = x; + backrect.width = info.overallWidth; + } + else + { + backrect.x = x + info.overallWidth; + backrect.width = -info.overallWidth; + } + backrect.y = y - FONTASCENT(pGC->font); + backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + + priv = cfbGetGCPrivate(pGC); + + /* this code cheats by knowing that ValidateGC isn't + * necessary for PolyFillRect + */ + + fgPixel = pGC->fgPixel; + + pGC->fgPixel = pGC->bgPixel; + priv->xor = PFILL(pGC->bgPixel); + + (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &backrect); + + pGC->fgPixel = fgPixel; + + priv->xor = PFILL(pGC->fgPixel); + + (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + +} diff --git a/cfb/cfbimage.c b/cfb/cfbimage.c new file mode 100644 index 000000000..af0fcc11d --- /dev/null +++ b/cfb/cfbimage.c @@ -0,0 +1,200 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* $Xorg: cfbimage.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ + +#include "X.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "servermd.h" + +#ifdef LOWMEMFTPT +#include "mi.h" +#endif /* ifdef LOWMEMFTPT */ + +void +cfbPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage) + DrawablePtr pDraw; + GCPtr pGC; + int depth, x, y, w, h; + int leftPad; + int format; + char *pImage; +{ + int bitsPerPixel; + PixmapPtr pPixmap; + + if ((w == 0) || (h == 0)) + return; + + if (format != XYPixmap) + { + pPixmap = GetScratchPixmapHeader(pDraw->pScreen, w+leftPad, h, depth, + BitsPerPixel(depth), PixmapBytePad(w+leftPad, depth), + (pointer)pImage); + if (!pPixmap) + return; + + cfbGetGCPrivate(pGC)->fExpose = FALSE; + if (format == ZPixmap) + (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, + leftPad, 0, w, h, x, y); + else + (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, pDraw, pGC, + leftPad, 0, w, h, x, y, 1); + cfbGetGCPrivate(pGC)->fExpose = TRUE; + FreeScratchPixmapHeader(pPixmap); + } + else + { + unsigned long oldFg, oldBg; + XID gcv[3]; + unsigned long oldPlanemask; + unsigned long i; + long bytesPer; + + depth = pGC->depth; + oldPlanemask = pGC->planemask; + oldFg = pGC->fgPixel; + oldBg = pGC->bgPixel; + gcv[0] = ~0L; + gcv[1] = 0; + DoChangeGC(pGC, GCForeground | GCBackground, gcv, 0); + bytesPer = (long)h * BitmapBytePad(w + leftPad); + + for (i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer) + { + if (i & oldPlanemask) + { + gcv[0] = i; + DoChangeGC(pGC, GCPlaneMask, gcv, 0); + ValidateGC(pDraw, pGC); + (*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad, + XYBitmap, pImage); + } + } + gcv[0] = oldPlanemask; + gcv[1] = oldFg; + gcv[2] = oldBg; + DoChangeGC(pGC, GCPlaneMask | GCForeground | GCBackground, gcv, 0); + } +} + +void +cfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine) + DrawablePtr pDrawable; + int sx, sy, w, h; + unsigned int format; + unsigned long planeMask; + char *pdstLine; +{ + BoxRec box; + DDXPointRec ptSrc; + RegionRec rgnDst; + ScreenPtr pScreen; + PixmapPtr pPixmap; + + if ((w == 0) || (h == 0)) + return; + if (pDrawable->bitsPerPixel == 1) + { +#ifndef LOWMEMFTPT + mfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); +#else + miGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); +#endif /* ifndef LOWMEMFTPT */ + return; + } + pScreen = pDrawable->pScreen; + if (format == ZPixmap) + { + pPixmap = GetScratchPixmapHeader(pScreen, w, h, + pDrawable->depth, pDrawable->bitsPerPixel, + PixmapBytePad(w,pDrawable->depth), (pointer)pdstLine); + if (!pPixmap) + return; + if ((planeMask & PMSK) != PMSK) + bzero((char *)pdstLine, pPixmap->devKind * h); + ptSrc.x = sx + pDrawable->x; + ptSrc.y = sy + pDrawable->y; + box.x1 = 0; + box.y1 = 0; + box.x2 = w; + box.y2 = h; + REGION_INIT(pScreen, &rgnDst, &box, 1); + cfbDoBitblt(pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst, + &ptSrc, planeMask); + REGION_UNINIT(pScreen, &rgnDst); + FreeScratchPixmapHeader(pPixmap); + } + else + { +#if PSZ == 8 + pPixmap = GetScratchPixmapHeader(pScreen, w, h, /*depth*/ 1, + /*bpp*/ 1, BitmapBytePad(w), (pointer)pdstLine); + if (!pPixmap) + return; + + ptSrc.x = sx + pDrawable->x; + ptSrc.y = sy + pDrawable->y; + box.x1 = 0; + box.y1 = 0; + box.x2 = w; + box.y2 = h; + REGION_INIT(pScreen, &rgnDst, &box, 1); + cfbCopyImagePlane (pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst, + &ptSrc, planeMask); + REGION_UNINIT(pScreen, &rgnDst); + FreeScratchPixmapHeader(pPixmap); +#else + miGetImage (pDrawable, sx, sy, w, h, format, planeMask, pdstLine); +#endif + } +} diff --git a/cfb/cfbline.c b/cfb/cfbline.c new file mode 100644 index 000000000..019d93720 --- /dev/null +++ b/cfb/cfbline.c @@ -0,0 +1,743 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* $Xorg: cfbline.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +#include "X.h" + +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "mistruct.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "miline.h" + +/* single-pixel lines on a color frame buffer + + NON-SLOPED LINES + horizontal lines are always drawn left to right; we have to +move the endpoints right by one after they're swapped. + horizontal lines will be confined to a single band of a +region. the code finds that band (giving up if the lower +bound of the band is above the line we're drawing); then it +finds the first box in that band that contains part of the +line. we clip the line to subsequent boxes in that band. + vertical lines are always drawn top to bottom (y-increasing.) +this requires adding one to the y-coordinate of each endpoint +after swapping. + + SLOPED LINES + when clipping a sloped line, we bring the second point inside +the clipping box, rather than one beyond it, and then add 1 to +the length of the line before drawing it. this lets us use +the same box for finding the outcodes for both endpoints. since +the equation for clipping the second endpoint to an edge gives us +1 beyond the edge, we then have to move the point towards the +first point by one step on the major axis. + eventually, there will be a diagram here to explain what's going +on. the method uses Cohen-Sutherland outcodes to determine +outsideness, and a method similar to Pike's layers for doing the +actual clipping. + +*/ + +void +#ifdef POLYSEGMENT +cfbSegmentSS (pDrawable, pGC, nseg, pSeg) + DrawablePtr pDrawable; + GCPtr pGC; + int nseg; + register xSegment *pSeg; +#else +cfbLineSS (pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; /* number of points */ + DDXPointPtr pptInit; +#endif +{ + int nboxInit; + register int nbox; + BoxPtr pboxInit; + register BoxPtr pbox; +#ifndef POLYSEGMENT + register DDXPointPtr ppt; /* pointer to list of translated points */ +#endif + + unsigned int oc1; /* outcode of point 1 */ + unsigned int oc2; /* outcode of point 2 */ + + unsigned long *addrl; /* address of destination pixmap */ + int nlwidth; /* width in longwords of destination pixmap */ + int xorg, yorg; /* origin of window */ + + int adx; /* abs values of dx and dy */ + int ady; + int signdx; /* sign of dx and dy */ + int signdy; + int e, e1, e2; /* bresenham error and increments */ + int len; /* length of segment */ + int axis; /* major axis */ + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + + /* a bunch of temporaries */ + int tmp; + register int y1, y2; + register int x1, x2; + RegionPtr cclip; + cfbPrivGCPtr devPriv; + unsigned long xor, and; + int alu; + + devPriv = cfbGetGCPrivate(pGC); + cclip = devPriv->pCompositeClip; + pboxInit = REGION_RECTS(cclip); + nboxInit = REGION_NUM_RECTS(cclip); + + cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrl) + + alu = devPriv->rop; + xor = devPriv->xor; + and = devPriv->and; + xorg = pDrawable->x; + yorg = pDrawable->y; +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) + { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + if (x1 == x2) /* vertical line */ + { + /* make the line go top to bottom of screen, keeping + endpoint semantics + */ + if (y1 > y2) + { + register int tmp; + + tmp = y2; + y2 = y1 + 1; + y1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + y1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) + y2++; +#endif + /* get to first band that might contain part of line */ + while ((nbox) && (pbox->y2 <= y1)) + { + pbox++; + nbox--; + } + + if (nbox) + { + /* stop when lower edge of box is beyond end of line */ + while((nbox) && (y2 >= pbox->y1)) + { + if ((x1 >= pbox->x1) && (x1 < pbox->x2)) + { + int y1t, y2t; + /* this box has part of the line in it */ + y1t = max(y1, pbox->y1); + y2t = min(y2, pbox->y2); + if (y1t != y2t) + { + cfbVertS (alu, and, xor, + addrl, nlwidth, + x1, y1t, y2t-y1t); + } + } + nbox--; + pbox++; + } + } +#ifndef POLYSEGMENT + y2 = ppt->y + yorg; +#endif + } + else if (y1 == y2) /* horizontal line */ + { + /* force line from left to right, keeping + endpoint semantics + */ + if (x1 > x2) + { + register int tmp; + + tmp = x2; + x2 = x1 + 1; + x1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + x1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) + x2++; +#endif + + /* find the correct band */ + while( (nbox) && (pbox->y2 <= y1)) + { + pbox++; + nbox--; + } + + /* try to draw the line, if we haven't gone beyond it */ + if ((nbox) && (pbox->y1 <= y1)) + { + /* when we leave this band, we're done */ + tmp = pbox->y1; + while((nbox) && (pbox->y1 == tmp)) + { + int x1t, x2t; + + if (pbox->x2 <= x1) + { + /* skip boxes until one might contain start point */ + nbox--; + pbox++; + continue; + } + + /* stop if left of box is beyond right of line */ + if (pbox->x1 >= x2) + { + nbox = 0; + break; + } + + x1t = max(x1, pbox->x1); + x2t = min(x2, pbox->x2); + if (x1t != x2t) + { + cfbHorzS (alu, and, xor, + addrl, nlwidth, + x1t, y1, x2t-x1t); + } + nbox--; + pbox++; + } + } +#ifndef POLYSEGMENT + x2 = ppt->x + xorg; +#endif + } + else /* sloped line */ + { + CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, + 1, 1, octant); + + if (adx > ady) + { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + } + else + { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + SetYMajorOctant(octant); + } + + FIXUP_ERROR(e, octant, bias); + + /* we have bresenham parameters and two points. + all we have to do now is clip and draw. + */ + + while(nbox--) + { + oc1 = 0; + oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if ((oc1 | oc2) == 0) + { + if (axis == X_AXIS) + len = adx; + else + len = ady; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + len++; +#endif + cfbBresS (alu, and, xor, + addrl, nlwidth, + signdx, signdy, axis, x1, y1, + e, e1, e2, len); + break; + } + else if (oc1 & oc2) + { + pbox++; + } + else + { + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int clipdx, clipdy; + int err; + + if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, + pbox->y2-1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) + { + pbox++; + continue; + } + + if (axis == X_AXIS) + len = abs(new_x2 - new_x1); + else + len = abs(new_y2 - new_y1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) + { + /* unwind bresenham error term to first point */ + if (clip1) + { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + if (axis == X_AXIS) + err = e+((clipdy*e2) + ((clipdx-clipdy)*e1)); + else + err = e+((clipdx*e2) + ((clipdy-clipdx)*e1)); + } + else + err = e; + cfbBresS(alu, and, xor, + addrl, nlwidth, + signdx, signdy, axis, new_x1, new_y1, + err, e1, e2, len); + } + pbox++; + } + } /* while (nbox--) */ + } /* sloped line */ + } /* while (nline--) */ + +#ifndef POLYSEGMENT + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) + { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) + { + if ((x2 >= pbox->x1) && + (y2 >= pbox->y1) && + (x2 < pbox->x2) && + (y2 < pbox->y2)) + { + unsigned long mask; + unsigned long scrbits; + + mask = cfbmask[x2 & PIM]; + addrl += (y2 * nlwidth) + (x2 >> PWSH); + scrbits = *addrl; + *addrl = (scrbits & ~mask) | + (DoRRop (scrbits, and, xor) & mask); + break; + } + else + pbox++; + } + } +#endif +} + +/* + * Draw dashed 1-pixel lines. + */ + +void +#ifdef POLYSEGMENT +cfbSegmentSD (pDrawable, pGC, nseg, pSeg) + DrawablePtr pDrawable; + register GCPtr pGC; + int nseg; + register xSegment *pSeg; +#else +cfbLineSD( pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + register GCPtr pGC; + int mode; /* Origin or Previous */ + int npt; /* number of points */ + DDXPointPtr pptInit; +#endif +{ + int nboxInit; + register int nbox; + BoxPtr pboxInit; + register BoxPtr pbox; +#ifndef POLYSEGMENT + register DDXPointPtr ppt; /* pointer to list of translated points */ +#endif + + register unsigned int oc1; /* outcode of point 1 */ + register unsigned int oc2; /* outcode of point 2 */ + + unsigned long *addrl; /* address of destination pixmap */ + int nlwidth; /* width in longwords of destination pixmap */ + int xorg, yorg; /* origin of window */ + + int adx; /* abs values of dx and dy */ + int ady; + int signdx; /* sign of dx and dy */ + int signdy; + int e, e1, e2; /* bresenham error and increments */ + int len; /* length of segment */ + int axis; /* major axis */ + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + int x1, x2, y1, y2; + RegionPtr cclip; + cfbRRopRec rrops[2]; + unsigned char *pDash; + int dashOffset; + int numInDashList; + int dashIndex; + int isDoubleDash; + int dashIndexTmp, dashOffsetTmp; + int unclippedlen; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); + cclip = devPriv->pCompositeClip; + rrops[0].rop = devPriv->rop; + rrops[0].and = devPriv->and; + rrops[0].xor = devPriv->xor; + if (pGC->alu == GXcopy) + { + rrops[1].rop = GXcopy; + rrops[1].and = 0; + rrops[1].xor = PFILL (pGC->bgPixel); + } + else + { + rrops[1].rop = cfbReduceRasterOp (pGC->alu, + pGC->bgPixel, pGC->planemask, + &rrops[1].and, &rrops[1].xor); + } + pboxInit = REGION_RECTS(cclip); + nboxInit = REGION_NUM_RECTS(cclip); + + cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrl) + + /* compute initial dash values */ + + pDash = (unsigned char *) pGC->dash; + numInDashList = pGC->numInDashList; + isDoubleDash = (pGC->lineStyle == LineDoubleDash); + dashIndex = 0; + dashOffset = 0; + miStepDash ((int)pGC->dashOffset, &dashIndex, pDash, + numInDashList, &dashOffset); + + xorg = pDrawable->x; + yorg = pDrawable->y; +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) + { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); + + if (adx > ady) + { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + unclippedlen = adx; + } + else + { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + unclippedlen = ady; + SetYMajorOctant(octant); + } + + FIXUP_ERROR(e, octant, bias); + + /* we have bresenham parameters and two points. + all we have to do now is clip and draw. + */ + + while(nbox--) + { + oc1 = 0; + oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if ((oc1 | oc2) == 0) + { +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) + unclippedlen++; + dashIndexTmp = dashIndex; + dashOffsetTmp = dashOffset; + cfbBresD (rrops, + &dashIndexTmp, pDash, numInDashList, + &dashOffsetTmp, isDoubleDash, + addrl, nlwidth, + signdx, signdy, axis, x1, y1, + e, e1, e2, unclippedlen); + break; +#else + cfbBresD (rrops, + &dashIndex, pDash, numInDashList, + &dashOffset, isDoubleDash, + addrl, nlwidth, + signdx, signdy, axis, x1, y1, + e, e1, e2, unclippedlen); + goto dontStep; +#endif + } + else if (oc1 & oc2) + { + pbox++; + } + else /* have to clip */ + { + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int clipdx, clipdy; + int err; + int dashIndexTmp, dashOffsetTmp; + + if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, + pbox->y2-1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) + { + pbox++; + continue; + } + + dashIndexTmp = dashIndex; + dashOffsetTmp = dashOffset; + + if (clip1) + { + int dlen; + + if (axis == X_AXIS) + dlen = abs(new_x1 - x1); + else + dlen = abs(new_y1 - y1); + miStepDash (dlen, &dashIndexTmp, pDash, + numInDashList, &dashOffsetTmp); + } + + if (axis == X_AXIS) + len = abs(new_x2 - new_x1); + else + len = abs(new_y2 - new_y1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) + { + /* unwind bresenham error term to first point */ + if (clip1) + { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + if (axis == X_AXIS) + err = e+((clipdy*e2) + ((clipdx-clipdy)*e1)); + else + err = e+((clipdx*e2) + ((clipdy-clipdx)*e1)); + } + else + err = e; + cfbBresD (rrops, + &dashIndexTmp, pDash, numInDashList, + &dashOffsetTmp, isDoubleDash, + addrl, nlwidth, + signdx, signdy, axis, new_x1, new_y1, + err, e1, e2, len); + } + pbox++; + } + } /* while (nbox--) */ +#ifndef POLYSEGMENT + /* + * walk the dash list around to the next line + */ + miStepDash (unclippedlen, &dashIndex, pDash, + numInDashList, &dashOffset); +dontStep: ; +#endif + } /* while (nline--) */ + +#ifndef POLYSEGMENT + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((dashIndex & 1) == 0 || isDoubleDash) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) + { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) + { + if ((x2 >= pbox->x1) && + (y2 >= pbox->y1) && + (x2 < pbox->x2) && + (y2 < pbox->y2)) + { + unsigned long mask; + int pix; + + pix = 0; + if (dashIndex & 1) + pix = 1; + mask = cfbmask[x2 & PIM]; + addrl += (y2 * nlwidth) + (x2 >> PWSH); + *addrl = DoMaskRRop (*addrl, rrops[pix].and, rrops[pix].xor, mask); + break; + } + else + pbox++; + } + } +#endif +} diff --git a/cfb/cfbmap.h b/cfb/cfbmap.h new file mode 100644 index 000000000..75a79eb1e --- /dev/null +++ b/cfb/cfbmap.h @@ -0,0 +1,187 @@ +/* + * $Xorg: cfbmap.h,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1991, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * Map names around so that multiple depths can be supported simultaneously + */ + +/* a losing vendor cpp dumps core if we define NAME in terms of CATNAME */ + +#if PSZ != 8 +#if PSZ == 32 +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) cfb32##subname +#else +#define NAME(subname) cfb32/**/subname +#endif +#endif + +#if PSZ == 16 +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) cfb16##subname +#else +#define NAME(subname) cfb16/**/subname +#endif +#endif + +#if PSZ == 4 +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) cfb4##subname +#else +#define NAME(subname) cfb4/**/subname +#endif +#endif + +#ifndef NAME +cfb can not hack PSZ yet +#endif + +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define CATNAME(prefix,subname) prefix##subname +#else +#define CATNAME(prefix,subname) prefix/**/subname +#endif + +#define cfbScreenPrivateIndex NAME(ScreenPrivateIndex) +#define QuartetBitsTable NAME(QuartetBitsTable) +#define QuartetPixelMaskTable NAME(QuartetPixelMaskTable) +#define cfbAllocatePrivates NAME(AllocatePrivates) +#define cfbBSFuncRec NAME(BSFuncRec) +#define cfbBitBlt NAME(BitBlt) +#define cfbBresD NAME(BresD) +#define cfbBresS NAME(BresS) +#define cfbChangeWindowAttributes NAME(ChangeWindowAttributes) +#define cfbCloseScreen NAME(CloseScreen) +#define cfbCopyArea NAME(CopyArea) +#define cfbCopyImagePlane NAME(CopyImagePlane) +#define cfbCopyPixmap NAME(CopyPixmap) +#define cfbCopyPlane NAME(CopyPlane) +#define cfbCopyRotatePixmap NAME(CopyRotatePixmap) +#define cfbCopyWindow NAME(CopyWindow) +#define cfbCreateGC NAME(CreateGC) +#define cfbCreatePixmap NAME(CreatePixmap) +#define cfbCreateWindow NAME(CreateWindow) +#define cfbCreateScreenResources NAME(CreateScreenResources) +#define cfbDestroyPixmap NAME(DestroyPixmap) +#define cfbDestroyWindow NAME(DestroyWindow) +#define cfbDoBitblt NAME(DoBitblt) +#define cfbDoBitbltCopy NAME(DoBitbltCopy) +#define cfbDoBitbltGeneral NAME(DoBitbltGeneral) +#define cfbDoBitbltOr NAME(DoBitbltOr) +#define cfbDoBitbltXor NAME(DoBitbltXor) +#define cfbFillBoxSolid NAME(FillBoxSolid) +#define cfbFillBoxTile32 NAME(FillBoxTile32) +#define cfbFillBoxTile32sCopy NAME(FillBoxTile32sCopy) +#define cfbFillBoxTile32sGeneral NAME(FillBoxTile32sGeneral) +#define cfbFillBoxTileOdd NAME(FillBoxTileOdd) +#define cfbFillBoxTileOddCopy NAME(FillBoxTileOddCopy) +#define cfbFillBoxTileOddGeneral NAME(FillBoxTileOddGeneral) +#define cfbFillPoly1RectCopy NAME(FillPoly1RectCopy) +#define cfbFillPoly1RectGeneral NAME(FillPoly1RectGeneral) +#define cfbFillRectSolidCopy NAME(FillRectSolidCopy) +#define cfbFillRectSolidGeneral NAME(FillRectSolidGeneral) +#define cfbFillRectSolidXor NAME(FillRectSolidXor) +#define cfbFillRectTile32Copy NAME(FillRectTile32Copy) +#define cfbFillRectTile32General NAME(FillRectTile32General) +#define cfbFillRectTileOdd NAME(FillRectTileOdd) +#define cfbFillSpanTile32sCopy NAME(FillSpanTile32sCopy) +#define cfbFillSpanTile32sGeneral NAME(FillSpanTile32sGeneral) +#define cfbFillSpanTileOddCopy NAME(FillSpanTileOddCopy) +#define cfbFillSpanTileOddGeneral NAME(FillSpanTileOddGeneral) +#define cfbFinishScreenInit NAME(FinishScreenInit) +#define cfbGCFuncs NAME(GCFuncs) +#define cfbGetImage NAME(GetImage) +#define cfbGetSpans NAME(GetSpans) +#define cfbHorzS NAME(HorzS) +#define cfbImageGlyphBlt8 NAME(ImageGlyphBlt8) +#define cfbLineSD NAME(LineSD) +#define cfbLineSS NAME(LineSS) +#define cfbMapWindow NAME(MapWindow) +#define cfbMatchCommon NAME(MatchCommon) +#define cfbNonTEOps NAME(NonTEOps) +#define cfbNonTEOps1Rect NAME(NonTEOps1Rect) +#define cfbPadPixmap NAME(PadPixmap) +#define cfbPaintWindow NAME(PaintWindow) +#define cfbPolyGlyphBlt8 NAME(PolyGlyphBlt8) +#define cfbPolyGlyphRop8 NAME(PolyGlyphRop8) +#define cfbPolyFillArcSolidCopy NAME(PolyFillArcSolidCopy) +#define cfbPolyFillArcSolidGeneral NAME(PolyFillArcSolidGeneral) +#define cfbPolyFillRect NAME(PolyFillRect) +#define cfbPolyPoint NAME(PolyPoint) +#define cfbPositionWindow NAME(PositionWindow) +#define cfbPutImage NAME(PutImage) +#define cfbReduceRasterOp NAME(ReduceRasterOp) +#define cfbRestoreAreas NAME(RestoreAreas) +#define cfbSaveAreas NAME(SaveAreas) +#define cfbScreenInit NAME(ScreenInit) +#define cfbSegmentSD NAME(SegmentSD) +#define cfbSegmentSS NAME(SegmentSS) +#define cfbSetScanline NAME(SetScanline) +#define cfbSetSpans NAME(SetSpans) +#define cfbSetupScreen NAME(SetupScreen) +#define cfbSolidSpansCopy NAME(SolidSpansCopy) +#define cfbSolidSpansGeneral NAME(SolidSpansGeneral) +#define cfbSolidSpansXor NAME(SolidSpansXor) +#define cfbStippleStack NAME(StippleStack) +#define cfbStippleStackTE NAME(StippleStackTE) +#define cfbTEGlyphBlt NAME(TEGlyphBlt) +#define cfbTEOps NAME(TEOps) +#define cfbTEOps1Rect NAME(TEOps1Rect) +#define cfbTile32FSCopy NAME(Tile32FSCopy) +#define cfbTile32FSGeneral NAME(Tile32FSGeneral) +#define cfbUnmapWindow NAME(UnmapWindow) +#define cfbUnnaturalStippleFS NAME(UnnaturalStippleFS) +#define cfbUnnaturalTileFS NAME(UnnaturalTileFS) +#define cfbValidateGC NAME(ValidateGC) +#define cfbVertS NAME(VertS) +#define cfbXRotatePixmap NAME(XRotatePixmap) +#define cfbYRotatePixmap NAME(YRotatePixmap) +#define cfbendpartial NAME(endpartial) +#define cfbendtab NAME(endtab) +#define cfbmask NAME(mask) +#define cfbrmask NAME(rmask) +#define cfbstartpartial NAME(startpartial) +#define cfbstarttab NAME(starttab) +#define cfb8LineSS1Rect NAME(LineSS1Rect) +#define cfb8SegmentSS1Rect NAME(SegmentSS1Rect) +#define cfb8ClippedLineCopy NAME(ClippedLineCopy) +#define cfb8ClippedLineXor NAME(ClippedLineXor) +#define cfb8ClippedLineGeneral NAME(ClippedLineGeneral ) +#define cfb8SegmentSS1RectCopy NAME(SegmentSS1RectCopy) +#define cfb8SegmentSS1RectXor NAME(SegmentSS1RectXor) +#define cfb8SegmentSS1RectGeneral NAME(SegmentSS1RectGeneral ) +#define cfb8SegmentSS1RectShiftCopy NAME(SegmentSS1RectShiftCopy) +#define cfb8LineSS1RectCopy NAME(LineSS1RectCopy) +#define cfb8LineSS1RectXor NAME(LineSS1RectXor) +#define cfb8LineSS1RectGeneral NAME(LineSS1RectGeneral ) +#define cfb8LineSS1RectPreviousCopy NAME(LineSS1RectPreviousCopy) +#define cfbZeroPolyArcSS8Copy NAME(ZeroPolyArcSSCopy) +#define cfbZeroPolyArcSS8Xor NAME(ZeroPolyArcSSXor) +#define cfbZeroPolyArcSS8General NAME(ZeroPolyArcSSGeneral) + +#endif /* PSZ != 8 */ diff --git a/cfb/cfbmskbits.c b/cfb/cfbmskbits.c new file mode 100644 index 000000000..4c26e3576 --- /dev/null +++ b/cfb/cfbmskbits.c @@ -0,0 +1,1210 @@ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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. + +********************************************************/ + +/* $Xorg: cfbmskbits.c,v 1.3 2000/08/17 19:48:14 cpqbld Exp $ */ + +/* + * ========================================================================== + * Converted to Color Frame Buffer by smarks@sun, April-May 1987. The "bit + * numbering" in the doc below really means "byte numbering" now. + * ========================================================================== + */ + +/* + these tables are used by several macros in the cfb code. + + the vax numbers everything left to right, so bit indices on the +screen match bit indices in longwords. the pc-rt and Sun number +bits on the screen the way they would be written on paper, +(i.e. msb to the left), and so a bit index n on the screen is +bit index 32-n in a longword + + see also cfbmskbits.h +*/ +#include <X.h> +#include <Xmd.h> +#include <servermd.h> +#include "cfb.h" +#include "cfbmskbits.h" + +#define _cfbBits(a) (PixelGroup)(a) + +#if (BITMAP_BIT_ORDER == MSBFirst) +#define cfbBits(v) _cfbBits(v) +#else /* BITMAP_BIT_ORDER == LSBFirst */ +#define cfbFlip2(a) ((((a) & 0x1) << 1) | (((a) & 0x2) >> 1)) +#define cfbFlip4(a) ((cfbFlip2(a) << 2) | cfbFlip2(a >> 2)) +#define cfbFlip8(a) ((cfbFlip4(a) << 4) | cfbFlip4(a >> 4)) +#define cfbFlip16(a) ((cfbFlip8(a) << 8) | cfbFlip8(a >> 8)) +#define cfbFlip32(a) ((cfbFlip16(a) << 16) | cfbFlip16(a >> 16)) +#if PGSZ == 32 +#define cfbBits(a) cfbFlip32(_cfbBits(a)) +#else /* PGSZ == 64 */ +#define cfbFlip64(a) ((cfbFlip32(a) << 32) | cfbFlip32(a >> 32)) +#define cfbBits(a) cfbFlip64(_cfbBits(a)) +#endif /* PGSZ */ +#endif /* BITMAP_BIT_ORDER */ + +/* NOTE: +the first element in starttab could be 0xffffffff. making it 0 +lets us deal with a full first word in the middle loop, rather +than having to do the multiple reads and masks that we'd +have to do if we thought it was partial. +*/ +#if PSZ == 4 +#if PGSZ == 32 +PixelGroup cfbstarttab[] = + { + cfbBits(0x00000000), + cfbBits(0x0FFFFFFF), + cfbBits(0x00FFFFFF), + cfbBits(0x000FFFFF), + cfbBits(0x0000FFFF), + cfbBits(0x00000FFF), + cfbBits(0x000000FF), + cfbBits(0x0000000F) + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x00000000), + cfbBits(0xF0000000), + cfbBits(0xFF000000), + cfbBits(0xFFF00000), + cfbBits(0xFFFF0000), + cfbBits(0xFFFFF000), + cfbBits(0xFFFFFF00), + cfbBits(0xFFFFFFF0) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstarttab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0x0FFFFFFFFFFFFFFF), + cfbBits(0x00FFFFFFFFFFFFFF), + cfbBits(0x000FFFFFFFFFFFFF), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x00000FFFFFFFFFFF), + cfbBits(0x000000FFFFFFFFFF), + cfbBits(0x0000000FFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x000000000FFFFFFF), + cfbBits(0x0000000000FFFFFF), + cfbBits(0x00000000000FFFFF), + cfbBits(0x000000000000FFFF), + cfbBits(0x0000000000000FFF), + cfbBits(0x00000000000000FF), + cfbBits(0x000000000000000F), + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0xF000000000000000), + cfbBits(0xFF00000000000000), + cfbBits(0xFFF0000000000000), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFF00000000000), + cfbBits(0xFFFFFF0000000000), + cfbBits(0xFFFFFFF000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFF0000000), + cfbBits(0xFFFFFFFFFF000000), + cfbBits(0xFFFFFFFFFFF00000), + cfbBits(0xFFFFFFFFFFFF0000), + cfbBits(0xFFFFFFFFFFFFF000), + cfbBits(0xFFFFFFFFFFFFFF00), + cfbBits(0xFFFFFFFFFFFFFFF0), + }; +#endif /* PGSZ */ +#endif /* PSZ == 4 */ + +#if PSZ == 8 +#if PGSZ == 32 +PixelGroup cfbstarttab[] = + { + cfbBits(0x00000000), + cfbBits(0x00FFFFFF), + cfbBits(0x0000FFFF), + cfbBits(0x000000FF) + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x00000000), + cfbBits(0xFF000000), + cfbBits(0xFFFF0000), + cfbBits(0xFFFFFF00) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstarttab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0x00FFFFFFFFFFFFFF), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x000000FFFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x0000000000FFFFFF), + cfbBits(0x000000000000FFFF), + cfbBits(0x00000000000000FF) + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0xFF00000000000000), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFFF0000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFFF000000), + cfbBits(0xFFFFFFFFFFFF0000), + cfbBits(0xFFFFFFFFFFFFFF00) + }; +#endif /* PGSZ */ +#endif /* PSZ == 8 */ + +#if PSZ == 16 +#if PGSZ == 32 +PixelGroup cfbstarttab[] = + { + cfbBits(0x00000000), + cfbBits(0x0000FFFF), + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x00000000), + cfbBits(0xFFFF0000), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstarttab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x000000000000FFFF), + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFFFFF0000), + }; +#endif /* PGSZ */ +#endif + +#if PSZ == 32 +#if PGSZ == 32 +PixelGroup cfbstarttab[] = + { + cfbBits(0x00000000), + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x00000000), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstarttab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0x00000000FFFFFFFF), + }; +PixelGroup cfbendtab[] = + { + cfbBits(0x0000000000000000), + cfbBits(0xFFFFFFFF00000000), + }; +#endif /* PGSZ */ +#endif /* PSZ == 32 */ + +/* a hack, for now, since the entries for 0 need to be all + 1 bits, not all zeros. + this means the code DOES NOT WORK for segments of length + 0 (which is only a problem in the horizontal line code.) +*/ +#if PSZ == 4 +#if PGSZ == 32 +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0x0FFFFFFF), + cfbBits(0x00FFFFFF), + cfbBits(0x000FFFFF), + cfbBits(0x0000FFFF), + cfbBits(0x00000FFF), + cfbBits(0x000000FF), + cfbBits(0x0000000F) + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0xF0000000), + cfbBits(0xFF000000), + cfbBits(0xFFF00000), + cfbBits(0xFFFF0000), + cfbBits(0xFFFFF000), + cfbBits(0xFFFFFF00), + cfbBits(0xFFFFFFF0) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0x0FFFFFFFFFFFFFFF), + cfbBits(0x00FFFFFFFFFFFFFF), + cfbBits(0x000FFFFFFFFFFFFF), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x00000FFFFFFFFFFF), + cfbBits(0x000000FFFFFFFFFF), + cfbBits(0x0000000FFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x000000000FFFFFFF), + cfbBits(0x0000000000FFFFFF), + cfbBits(0x00000000000FFFFF), + cfbBits(0x000000000000FFFF), + cfbBits(0x0000000000000FFF), + cfbBits(0x00000000000000FF), + cfbBits(0x000000000000000F), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0xF000000000000000), + cfbBits(0xFF00000000000000), + cfbBits(0xFFF0000000000000), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFF00000000000), + cfbBits(0xFFFFFF0000000000), + cfbBits(0xFFFFFFF000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFF0000000), + cfbBits(0xFFFFFFFFFF000000), + cfbBits(0xFFFFFFFFFFF00000), + cfbBits(0xFFFFFFFFFFFF0000), + cfbBits(0xFFFFFFFFFFFFF000), + cfbBits(0xFFFFFFFFFFFFFF00), + cfbBits(0xFFFFFFFFFFFFFFF0), + }; +#endif /* PGSZ */ +#endif /* PSZ == 4 */ + +#if PSZ == 8 +#if PGSZ == 32 +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0x00FFFFFF), + cfbBits(0x0000FFFF), + cfbBits(0x000000FF) + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0xFF000000), + cfbBits(0xFFFF0000), + cfbBits(0xFFFFFF00) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0x00FFFFFFFFFFFFFF), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x000000FFFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x0000000000FFFFFF), + cfbBits(0x000000000000FFFF), + cfbBits(0x00000000000000FF), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0xFF00000000000000), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFFF0000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFFF000000), + cfbBits(0xFFFFFFFFFFFF0000), + cfbBits(0xFFFFFFFFFFFFFF00), + }; +#endif /* PGSZ */ +#endif /* PSZ == 8 */ + +#if PSZ == 16 +#if PGSZ == 32 +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0x0000FFFF), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFF), + cfbBits(0xFFFF0000), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + cfbBits(0x000000000000FFFF), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0xFFFF000000000000), + cfbBits(0xFFFFFFFF00000000), + cfbBits(0xFFFFFFFFFFFF0000), + }; +#endif /* PGSZ */ +#endif /* PSZ == 16 */ + +#if PSZ == 32 +#if PGSZ == 32 +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFF), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFF), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbstartpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0x00000000FFFFFFFF), + }; + +PixelGroup cfbendpartial[] = + { + cfbBits(0xFFFFFFFFFFFFFFFF), + cfbBits(0xFFFFFFFF00000000), + }; +#endif /* PGSZ */ +#endif /* PSZ == 32 */ + +/* used for masking bits in bresenham lines + mask[n] is used to mask out all but bit n in a longword (n is a +screen position). + rmask[n] is used to mask out the single bit at position n (n +is a screen posiotion.) +*/ + +#if PSZ == 4 +#if PGSZ == 32 +PixelGroup cfbmask[] = + { + cfbBits(0xF0000000), + cfbBits(0x0F000000), + cfbBits(0x00F00000), + cfbBits(0x000F0000), + cfbBits(0x0000F000), + cfbBits(0x00000F00), + cfbBits(0x000000F0), + cfbBits(0x0000000F) + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x0FFFFFFF), + cfbBits(0xF0FFFFFF), + cfbBits(0xFF0FFFFF), + cfbBits(0xFFF0FFFF), + cfbBits(0xFFFF0FFF), + cfbBits(0xFFFFF0FF), + cfbBits(0xFFFFFF0F), + cfbBits(0xFFFFFFF0) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbmask[] = + { + cfbBits(0xF000000000000000), + cfbBits(0x0F00000000000000), + cfbBits(0x00F0000000000000), + cfbBits(0x000F000000000000), + cfbBits(0x0000F00000000000), + cfbBits(0x00000F0000000000), + cfbBits(0x000000F000000000), + cfbBits(0x0000000F00000000), + cfbBits(0x00000000F0000000), + cfbBits(0x000000000F000000), + cfbBits(0x0000000000F00000), + cfbBits(0x00000000000F0000), + cfbBits(0x000000000000F000), + cfbBits(0x0000000000000F00), + cfbBits(0x00000000000000F0), + cfbBits(0x000000000000000F), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x0FFFFFFFFFFFFFFF), + cfbBits(0xF0FFFFFFFFFFFFFF), + cfbBits(0xFF0FFFFFFFFFFFFF), + cfbBits(0xFFF0FFFFFFFFFFFF), + cfbBits(0xFFFF0FFFFFFFFFFF), + cfbBits(0xFFFFF0FFFFFFFFFF), + cfbBits(0xFFFFFF0FFFFFFFFF), + cfbBits(0xFFFFFFF0FFFFFFFF), + cfbBits(0xFFFFFFFF0FFFFFFF), + cfbBits(0xFFFFFFFFF0FFFFFF), + cfbBits(0xFFFFFFFFFF0FFFFF), + cfbBits(0xFFFFFFFFFFF0FFFF), + cfbBits(0xFFFFFFFFFFFF0FFF), + cfbBits(0xFFFFFFFFFFFFF0FF), + cfbBits(0xFFFFFFFFFFFFFF0F), + cfbBits(0xFFFFFFFFFFFFFFF0), + }; +#endif /* PGSZ */ +#endif /* PSZ == 4 */ + +#if PSZ == 8 +#if PGSZ == 32 +PixelGroup cfbmask[] = + { + cfbBits(0xFF000000), + cfbBits(0x00FF0000), + cfbBits(0x0000FF00), + cfbBits(0x000000FF) + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x00FFFFFF), + cfbBits(0xFF00FFFF), + cfbBits(0xFFFF00FF), + cfbBits(0xFFFFFF00) + }; +#else /* PGSZ == 64 */ +PixelGroup cfbmask[] = + { + cfbBits(0xFF00000000000000), + cfbBits(0x00FF000000000000), + cfbBits(0x0000FF0000000000), + cfbBits(0x000000FF00000000), + cfbBits(0x00000000FF000000), + cfbBits(0x0000000000FF0000), + cfbBits(0x000000000000FF00), + cfbBits(0x00000000000000FF), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x00FFFFFFFFFFFFFF), + cfbBits(0xFF00FFFFFFFFFFFF), + cfbBits(0xFFFF00FFFFFFFFFF), + cfbBits(0xFFFFFF00FFFFFFFF), + cfbBits(0xFFFFFFFF00FFFFFF), + cfbBits(0xFFFFFFFFFF00FFFF), + cfbBits(0xFFFFFFFFFFFF00FF), + cfbBits(0xFFFFFFFFFFFFFF00), + }; +#endif /* PGSZ */ +#endif /* PSZ == 8 */ + +#if PSZ == 16 +#if PGSZ == 32 +PixelGroup cfbmask[] = + { + cfbBits(0xFFFF0000), + cfbBits(0x0000FFFF), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x0000FFFF), + cfbBits(0xFFFF0000), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbmask[] = + { + cfbBits(0xFFFF000000000000), + cfbBits(0x0000FFFF00000000), + cfbBits(0x00000000FFFF0000), + cfbBits(0x000000000000FFFF), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x0000FFFFFFFFFFFF), + cfbBits(0xFFFF0000FFFFFFFF), + cfbBits(0xFFFFFFFF0000FFFF), + cfbBits(0xFFFFFFFFFFFF0000), + }; +#endif /* PGSZ */ +#endif /* PSZ == 16 */ + +#if PSZ == 32 +#if PGSZ == 32 +PixelGroup cfbmask[] = + { + cfbBits(0xFFFFFFFF), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0xFFFFFFFF), + }; +#else /* PGSZ == 64 */ +PixelGroup cfbmask[] = + { + cfbBits(0xFFFFFFFF00000000), + cfbBits(0x00000000FFFFFFFF), + }; +PixelGroup cfbrmask[] = + { + cfbBits(0x00000000FFFFFFFF), + cfbBits(0xFFFFFFFF00000000), + }; +#endif /* PGSZ */ +#endif /* PSZ == 32 */ + +/* + * QuartetBitsTable contains PPW+1 masks whose binary values are masks in the + * low order quartet that contain the number of bits specified in the + * index. This table is used by getstipplepixels. + */ +#if PSZ == 4 +PixelGroup QuartetBitsTable[] = { +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 00000000 */ + 0x00000080, /* 1 - 10000000 */ + 0x000000C0, /* 2 - 11000000 */ + 0x000000E0, /* 3 - 11100000 */ + 0x000000F0, /* 4 - 11110000 */ + 0x000000F8, /* 5 - 11111000 */ + 0x000000FC, /* 6 - 11111100 */ + 0x000000FE, /* 7 - 11111110 */ + 0x000000FF /* 8 - 11111111 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 00000000 */ + 0x00000001, /* 1 - 00000001 */ + 0x00000003, /* 2 - 00000011 */ + 0x00000007, /* 3 - 00000111 */ + 0x0000000F, /* 4 - 00001111 */ + 0x0000001F, /* 5 - 00011111 */ + 0x0000003F, /* 6 - 00111111 */ + 0x0000007F, /* 7 - 01111111 */ + 0x000000FF /* 8 - 11111111 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 0000000000000000 */ + 0x00008000, /* 1 - 1000000000000000 */ + 0x0000C000, /* 2 - 1100000000000000 */ + 0x0000E000, /* 3 - 1110000000000000 */ + 0x0000F000, /* 4 - 1111000000000000 */ + 0x0000F800, /* 5 - 1111100000000000 */ + 0x0000FC00, /* 6 - 1111110000000000 */ + 0x0000FE00, /* 7 - 1111111000000000 */ + 0x0000FF00, /* 8 - 1111111100000000 */ + 0x0000FF80, /* 9 - 1111111110000000 */ + 0x0000FFC0, /* 10- 1111111111000000 */ + 0x0000FFE0, /* 11- 1111111111100000 */ + 0x0000FFF0, /* 12- 1111111111110000 */ + 0x0000FFF8, /* 13- 1111111111111000 */ + 0x0000FFFC, /* 14- 1111111111111100 */ + 0x0000FFFE, /* 15- 1111111111111110 */ + 0x0000FFFF, /* 16- 1111111111111111 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 0000000000000000 */ + 0x00000001, /* 1 - 0000000000000001 */ + 0x00000003, /* 2 - 0000000000000011 */ + 0x00000007, /* 3 - 0000000000000111 */ + 0x0000000F, /* 4 - 0000000000001111 */ + 0x0000001F, /* 5 - 0000000000011111 */ + 0x0000003F, /* 6 - 0000000000111111 */ + 0x0000007F, /* 7 - 0000000001111111 */ + 0x000000FF, /* 8 - 0000000011111111 */ + 0x000001FF, /* 9 - 0000000111111111 */ + 0x000003FF, /* 10- 0000001111111111 */ + 0x000007FF, /* 11- 0000011111111111 */ + 0x00000FFF, /* 12- 0000111111111111 */ + 0x00001FFF, /* 13- 0001111111111111 */ + 0x00003FFF, /* 14- 0011111111111111 */ + 0x00007FFF, /* 15- 0111111111111111 */ + 0x0000FFFF, /* 16- 1111111111111111 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#endif /* PGSZ */ +}; +#endif /* PSZ == 4 */ + +#if PSZ == 8 +PixelGroup QuartetBitsTable[] = { +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 0000 */ + 0x00000008, /* 1 - 1000 */ + 0x0000000C, /* 2 - 1100 */ + 0x0000000E, /* 3 - 1110 */ + 0x0000000F /* 4 - 1111 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 0000 */ + 0x00000001, /* 1 - 0001 */ + 0x00000003, /* 2 - 0011 */ + 0x00000007, /* 3 - 0111 */ + 0x0000000F /* 4 - 1111 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 00000000 */ + 0x00000080, /* 1 - 10000000 */ + 0x000000C0, /* 2 - 11000000 */ + 0x000000E0, /* 3 - 11100000 */ + 0x000000F0, /* 4 - 11110000 */ + 0x000000F8, /* 5 - 11111000 */ + 0x000000FC, /* 6 - 11111100 */ + 0x000000FE, /* 7 - 11111110 */ + 0x000000FF /* 8 - 11111111 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 00000000 */ + 0x00000001, /* 1 - 00000001 */ + 0x00000003, /* 2 - 00000011 */ + 0x00000007, /* 3 - 00000111 */ + 0x0000000F, /* 4 - 10000111 */ + 0x0000001F, /* 5 - 00011111 */ + 0x0000003F, /* 6 - 00111111 */ + 0x0000007F, /* 7 - 01111111 */ + 0x000000FF /* 8 - 11111111 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#endif /* PGSZ */ +}; +#endif /* PSZ == 8 */ + +#if PSZ == 16 +PixelGroup QuartetBitsTable[] = { +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 00 */ + 0x00000002, /* 1 - 10 */ + 0x00000003, /* 2 - 11 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 00 */ + 0x00000001, /* 1 - 01 */ + 0x00000003, /* 2 - 11 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 0000 */ + 0x00000008, /* 1 - 1000 */ + 0x0000000C, /* 2 - 1100 */ + 0x0000000E, /* 3 - 1110 */ + 0x0000000F, /* 4 - 1111 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 0000 */ + 0x00000001, /* 1 - 0001 */ + 0x00000003, /* 2 - 0011 */ + 0x00000007, /* 3 - 0111 */ + 0x0000000F, /* 4 - 1111 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#endif /* PGSZ */ +}; +#endif /* PSZ == 16 */ + +#if PSZ == 32 +PixelGroup QuartetBitsTable[] = { +#if PGSZ == 32 +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 0 */ + 0x00000001, /* 1 - 1 */ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 0 */ + 0x00000001, /* 1 - 1 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#else /* PGSZ == 64 */ +#if (BITMAP_BIT_ORDER == MSBFirst) + 0x00000000, /* 0 - 00 */ + 0x00000002, /* 1 - 10 */ + 0x00000003, /* 2 - 11*/ +#else /* (BITMAP_BIT_ORDER == LSBFirst */ + 0x00000000, /* 0 - 00 */ + 0x00000001, /* 1 - 01 */ + 0x00000003, /* 2 - 11 */ +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ +#endif /* PGSZ */ +}; +#endif /* PSZ == 32 */ + +/* + * QuartetPixelMaskTable is used by getstipplepixels to get a pixel mask + * corresponding to a quartet of bits. Note: the bit/byte order dependency + * is handled by QuartetBitsTable above. + */ +#if PSZ == 4 +#if PGSZ == 32 +PixelGroup QuartetPixelMaskTable[] = { + 0x00000000, + 0x0000000F, + 0x000000F0, + 0x000000FF, + 0x00000F00, + 0x00000F0F, + 0x00000FF0, + 0x00000FFF, + 0x0000F000, + 0x0000F00F, + 0x0000F0F0, + 0x0000F0FF, + 0x0000FF00, + 0x0000FF0F, + 0x0000FFF0, + 0x0000FFFF, + 0x000F0000, + 0x000F000F, + 0x000F00F0, + 0x000F00FF, + 0x000F0F00, + 0x000F0F0F, + 0x000F0FF0, + 0x000F0FFF, + 0x000FF000, + 0x000FF00F, + 0x000FF0F0, + 0x000FF0FF, + 0x000FFF00, + 0x000FFF0F, + 0x000FFFF0, + 0x000FFFFF, + 0x00F00000, + 0x00F0000F, + 0x00F000F0, + 0x00F000FF, + 0x00F00F00, + 0x00F00F0F, + 0x00F00FF0, + 0x00F00FFF, + 0x00F0F000, + 0x00F0F00F, + 0x00F0F0F0, + 0x00F0F0FF, + 0x00F0FF00, + 0x00F0FF0F, + 0x00F0FFF0, + 0x00F0FFFF, + 0x00FF0000, + 0x00FF000F, + 0x00FF00F0, + 0x00FF00FF, + 0x00FF0F00, + 0x00FF0F0F, + 0x00FF0FF0, + 0x00FF0FFF, + 0x00FFF000, + 0x00FFF00F, + 0x00FFF0F0, + 0x00FFF0FF, + 0x00FFFF00, + 0x00FFFF0F, + 0x00FFFFF0, + 0x00FFFFFF, + 0x0F000000, + 0x0F00000F, + 0x0F0000F0, + 0x0F0000FF, + 0x0F000F00, + 0x0F000F0F, + 0x0F000FF0, + 0x0F000FFF, + 0x0F00F000, + 0x0F00F00F, + 0x0F00F0F0, + 0x0F00F0FF, + 0x0F00FF00, + 0x0F00FF0F, + 0x0F00FFF0, + 0x0F00FFFF, + 0x0F0F0000, + 0x0F0F000F, + 0x0F0F00F0, + 0x0F0F00FF, + 0x0F0F0F00, + 0x0F0F0F0F, + 0x0F0F0FF0, + 0x0F0F0FFF, + 0x0F0FF000, + 0x0F0FF00F, + 0x0F0FF0F0, + 0x0F0FF0FF, + 0x0F0FFF00, + 0x0F0FFF0F, + 0x0F0FFFF0, + 0x0F0FFFFF, + 0x0FF00000, + 0x0FF0000F, + 0x0FF000F0, + 0x0FF000FF, + 0x0FF00F00, + 0x0FF00F0F, + 0x0FF00FF0, + 0x0FF00FFF, + 0x0FF0F000, + 0x0FF0F00F, + 0x0FF0F0F0, + 0x0FF0F0FF, + 0x0FF0FF00, + 0x0FF0FF0F, + 0x0FF0FFF0, + 0x0FF0FFFF, + 0x0FFF0000, + 0x0FFF000F, + 0x0FFF00F0, + 0x0FFF00FF, + 0x0FFF0F00, + 0x0FFF0F0F, + 0x0FFF0FF0, + 0x0FFF0FFF, + 0x0FFFF000, + 0x0FFFF00F, + 0x0FFFF0F0, + 0x0FFFF0FF, + 0x0FFFFF00, + 0x0FFFFF0F, + 0x0FFFFFF0, + 0x0FFFFFFF, + 0xF0000000, + 0xF000000F, + 0xF00000F0, + 0xF00000FF, + 0xF0000F00, + 0xF0000F0F, + 0xF0000FF0, + 0xF0000FFF, + 0xF000F000, + 0xF000F00F, + 0xF000F0F0, + 0xF000F0FF, + 0xF000FF00, + 0xF000FF0F, + 0xF000FFF0, + 0xF000FFFF, + 0xF00F0000, + 0xF00F000F, + 0xF00F00F0, + 0xF00F00FF, + 0xF00F0F00, + 0xF00F0F0F, + 0xF00F0FF0, + 0xF00F0FFF, + 0xF00FF000, + 0xF00FF00F, + 0xF00FF0F0, + 0xF00FF0FF, + 0xF00FFF00, + 0xF00FFF0F, + 0xF00FFFF0, + 0xF00FFFFF, + 0xF0F00000, + 0xF0F0000F, + 0xF0F000F0, + 0xF0F000FF, + 0xF0F00F00, + 0xF0F00F0F, + 0xF0F00FF0, + 0xF0F00FFF, + 0xF0F0F000, + 0xF0F0F00F, + 0xF0F0F0F0, + 0xF0F0F0FF, + 0xF0F0FF00, + 0xF0F0FF0F, + 0xF0F0FFF0, + 0xF0F0FFFF, + 0xF0FF0000, + 0xF0FF000F, + 0xF0FF00F0, + 0xF0FF00FF, + 0xF0FF0F00, + 0xF0FF0F0F, + 0xF0FF0FF0, + 0xF0FF0FFF, + 0xF0FFF000, + 0xF0FFF00F, + 0xF0FFF0F0, + 0xF0FFF0FF, + 0xF0FFFF00, + 0xF0FFFF0F, + 0xF0FFFFF0, + 0xF0FFFFFF, + 0xFF000000, + 0xFF00000F, + 0xFF0000F0, + 0xFF0000FF, + 0xFF000F00, + 0xFF000F0F, + 0xFF000FF0, + 0xFF000FFF, + 0xFF00F000, + 0xFF00F00F, + 0xFF00F0F0, + 0xFF00F0FF, + 0xFF00FF00, + 0xFF00FF0F, + 0xFF00FFF0, + 0xFF00FFFF, + 0xFF0F0000, + 0xFF0F000F, + 0xFF0F00F0, + 0xFF0F00FF, + 0xFF0F0F00, + 0xFF0F0F0F, + 0xFF0F0FF0, + 0xFF0F0FFF, + 0xFF0FF000, + 0xFF0FF00F, + 0xFF0FF0F0, + 0xFF0FF0FF, + 0xFF0FFF00, + 0xFF0FFF0F, + 0xFF0FFFF0, + 0xFF0FFFFF, + 0xFFF00000, + 0xFFF0000F, + 0xFFF000F0, + 0xFFF000FF, + 0xFFF00F00, + 0xFFF00F0F, + 0xFFF00FF0, + 0xFFF00FFF, + 0xFFF0F000, + 0xFFF0F00F, + 0xFFF0F0F0, + 0xFFF0F0FF, + 0xFFF0FF00, + 0xFFF0FF0F, + 0xFFF0FFF0, + 0xFFF0FFFF, + 0xFFFF0000, + 0xFFFF000F, + 0xFFFF00F0, + 0xFFFF00FF, + 0xFFFF0F00, + 0xFFFF0F0F, + 0xFFFF0FF0, + 0xFFFF0FFF, + 0xFFFFF000, + 0xFFFFF00F, + 0xFFFFF0F0, + 0xFFFFF0FF, + 0xFFFFFF00, + 0xFFFFFF0F, + 0xFFFFFFF0, + 0xFFFFFFFF, +}; +#else /* PGSZ == 64 */ +No QuartetPixelMaskTable for psz=PSZ +this would be a 64K entry table, a bit much I think. +Try breaking things in two: +mask = table[index&0xff00]<<32 | table[index&0xff] +#endif /* PGSZ */ +#endif /* PSZ == 4 */ + +#if PSZ == 8 +PixelGroup QuartetPixelMaskTable[] = { +#if PGSZ == 32 + 0x00000000, + 0x000000FF, + 0x0000FF00, + 0x0000FFFF, + 0x00FF0000, + 0x00FF00FF, + 0x00FFFF00, + 0x00FFFFFF, + 0xFF000000, + 0xFF0000FF, + 0xFF00FF00, + 0xFF00FFFF, + 0xFFFF0000, + 0xFFFF00FF, + 0xFFFFFF00, + 0xFFFFFFFF +#else /* PGSZ == 64 */ + 0x0000000000000000, 0x00000000000000FF, + 0x000000000000FF00, 0x000000000000FFFF, + 0x0000000000FF0000, 0x0000000000FF00FF, + 0x0000000000FFFF00, 0x0000000000FFFFFF, + 0x00000000FF000000, 0x00000000FF0000FF, + 0x00000000FF00FF00, 0x00000000FF00FFFF, + 0x00000000FFFF0000, 0x00000000FFFF00FF, + 0x00000000FFFFFF00, 0x00000000FFFFFFFF, + 0x000000FF00000000, 0x000000FF000000FF, + 0x000000FF0000FF00, 0x000000FF0000FFFF, + 0x000000FF00FF0000, 0x000000FF00FF00FF, + 0x000000FF00FFFF00, 0x000000FF00FFFFFF, + 0x000000FFFF000000, 0x000000FFFF0000FF, + 0x000000FFFF00FF00, 0x000000FFFF00FFFF, + 0x000000FFFFFF0000, 0x000000FFFFFF00FF, + 0x000000FFFFFFFF00, 0x000000FFFFFFFFFF, + 0x0000FF0000000000, 0x0000FF00000000FF, + 0x0000FF000000FF00, 0x0000FF000000FFFF, + 0x0000FF0000FF0000, 0x0000FF0000FF00FF, + 0x0000FF0000FFFF00, 0x0000FF0000FFFFFF, + 0x0000FF00FF000000, 0x0000FF00FF0000FF, + 0x0000FF00FF00FF00, 0x0000FF00FF00FFFF, + 0x0000FF00FFFF0000, 0x0000FF00FFFF00FF, + 0x0000FF00FFFFFF00, 0x0000FF00FFFFFFFF, + 0x0000FFFF00000000, 0x0000FFFF000000FF, + 0x0000FFFF0000FF00, 0x0000FFFF0000FFFF, + 0x0000FFFF00FF0000, 0x0000FFFF00FF00FF, + 0x0000FFFF00FFFF00, 0x0000FFFF00FFFFFF, + 0x0000FFFFFF000000, 0x0000FFFFFF0000FF, + 0x0000FFFFFF00FF00, 0x0000FFFFFF00FFFF, + 0x0000FFFFFFFF0000, 0x0000FFFFFFFF00FF, + 0x0000FFFFFFFFFF00, 0x0000FFFFFFFFFFFF, + 0x00FF000000000000, 0x00FF0000000000FF, + 0x00FF00000000FF00, 0x00FF00000000FFFF, + 0x00FF000000FF0000, 0x00FF000000FF00FF, + 0x00FF000000FFFF00, 0x00FF000000FFFFFF, + 0x00FF0000FF000000, 0x00FF0000FF0000FF, + 0x00FF0000FF00FF00, 0x00FF0000FF00FFFF, + 0x00FF0000FFFF0000, 0x00FF0000FFFF00FF, + 0x00FF0000FFFFFF00, 0x00FF0000FFFFFFFF, + 0x00FF00FF00000000, 0x00FF00FF000000FF, + 0x00FF00FF0000FF00, 0x00FF00FF0000FFFF, + 0x00FF00FF00FF0000, 0x00FF00FF00FF00FF, + 0x00FF00FF00FFFF00, 0x00FF00FF00FFFFFF, + 0x00FF00FFFF000000, 0x00FF00FFFF0000FF, + 0x00FF00FFFF00FF00, 0x00FF00FFFF00FFFF, + 0x00FF00FFFFFF0000, 0x00FF00FFFFFF00FF, + 0x00FF00FFFFFFFF00, 0x00FF00FFFFFFFFFF, + 0x00FFFF0000000000, 0x00FFFF00000000FF, + 0x00FFFF000000FF00, 0x00FFFF000000FFFF, + 0x00FFFF0000FF0000, 0x00FFFF0000FF00FF, + 0x00FFFF0000FFFF00, 0x00FFFF0000FFFFFF, + 0x00FFFF00FF000000, 0x00FFFF00FF0000FF, + 0x00FFFF00FF00FF00, 0x00FFFF00FF00FFFF, + 0x00FFFF00FFFF0000, 0x00FFFF00FFFF00FF, + 0x00FFFF00FFFFFF00, 0x00FFFF00FFFFFFFF, + 0x00FFFFFF00000000, 0x00FFFFFF000000FF, + 0x00FFFFFF0000FF00, 0x00FFFFFF0000FFFF, + 0x00FFFFFF00FF0000, 0x00FFFFFF00FF00FF, + 0x00FFFFFF00FFFF00, 0x00FFFFFF00FFFFFF, + 0x00FFFFFFFF000000, 0x00FFFFFFFF0000FF, + 0x00FFFFFFFF00FF00, 0x00FFFFFFFF00FFFF, + 0x00FFFFFFFFFF0000, 0x00FFFFFFFFFF00FF, + 0x00FFFFFFFFFFFF00, 0x00FFFFFFFFFFFFFF, + 0xFF00000000000000, 0xFF000000000000FF, + 0xFF0000000000FF00, 0xFF0000000000FFFF, + 0xFF00000000FF0000, 0xFF00000000FF00FF, + 0xFF00000000FFFF00, 0xFF00000000FFFFFF, + 0xFF000000FF000000, 0xFF000000FF0000FF, + 0xFF000000FF00FF00, 0xFF000000FF00FFFF, + 0xFF000000FFFF0000, 0xFF000000FFFF00FF, + 0xFF000000FFFFFF00, 0xFF000000FFFFFFFF, + 0xFF0000FF00000000, 0xFF0000FF000000FF, + 0xFF0000FF0000FF00, 0xFF0000FF0000FFFF, + 0xFF0000FF00FF0000, 0xFF0000FF00FF00FF, + 0xFF0000FF00FFFF00, 0xFF0000FF00FFFFFF, + 0xFF0000FFFF000000, 0xFF0000FFFF0000FF, + 0xFF0000FFFF00FF00, 0xFF0000FFFF00FFFF, + 0xFF0000FFFFFF0000, 0xFF0000FFFFFF00FF, + 0xFF0000FFFFFFFF00, 0xFF0000FFFFFFFFFF, + 0xFF00FF0000000000, 0xFF00FF00000000FF, + 0xFF00FF000000FF00, 0xFF00FF000000FFFF, + 0xFF00FF0000FF0000, 0xFF00FF0000FF00FF, + 0xFF00FF0000FFFF00, 0xFF00FF0000FFFFFF, + 0xFF00FF00FF000000, 0xFF00FF00FF0000FF, + 0xFF00FF00FF00FF00, 0xFF00FF00FF00FFFF, + 0xFF00FF00FFFF0000, 0xFF00FF00FFFF00FF, + 0xFF00FF00FFFFFF00, 0xFF00FF00FFFFFFFF, + 0xFF00FFFF00000000, 0xFF00FFFF000000FF, + 0xFF00FFFF0000FF00, 0xFF00FFFF0000FFFF, + 0xFF00FFFF00FF0000, 0xFF00FFFF00FF00FF, + 0xFF00FFFF00FFFF00, 0xFF00FFFF00FFFFFF, + 0xFF00FFFFFF000000, 0xFF00FFFFFF0000FF, + 0xFF00FFFFFF00FF00, 0xFF00FFFFFF00FFFF, + 0xFF00FFFFFFFF0000, 0xFF00FFFFFFFF00FF, + 0xFF00FFFFFFFFFF00, 0xFF00FFFFFFFFFFFF, + 0xFFFF000000000000, 0xFFFF0000000000FF, + 0xFFFF00000000FF00, 0xFFFF00000000FFFF, + 0xFFFF000000FF0000, 0xFFFF000000FF00FF, + 0xFFFF000000FFFF00, 0xFFFF000000FFFFFF, + 0xFFFF0000FF000000, 0xFFFF0000FF0000FF, + 0xFFFF0000FF00FF00, 0xFFFF0000FF00FFFF, + 0xFFFF0000FFFF0000, 0xFFFF0000FFFF00FF, + 0xFFFF0000FFFFFF00, 0xFFFF0000FFFFFFFF, + 0xFFFF00FF00000000, 0xFFFF00FF000000FF, + 0xFFFF00FF0000FF00, 0xFFFF00FF0000FFFF, + 0xFFFF00FF00FF0000, 0xFFFF00FF00FF00FF, + 0xFFFF00FF00FFFF00, 0xFFFF00FF00FFFFFF, + 0xFFFF00FFFF000000, 0xFFFF00FFFF0000FF, + 0xFFFF00FFFF00FF00, 0xFFFF00FFFF00FFFF, + 0xFFFF00FFFFFF0000, 0xFFFF00FFFFFF00FF, + 0xFFFF00FFFFFFFF00, 0xFFFF00FFFFFFFFFF, + 0xFFFFFF0000000000, 0xFFFFFF00000000FF, + 0xFFFFFF000000FF00, 0xFFFFFF000000FFFF, + 0xFFFFFF0000FF0000, 0xFFFFFF0000FF00FF, + 0xFFFFFF0000FFFF00, 0xFFFFFF0000FFFFFF, + 0xFFFFFF00FF000000, 0xFFFFFF00FF0000FF, + 0xFFFFFF00FF00FF00, 0xFFFFFF00FF00FFFF, + 0xFFFFFF00FFFF0000, 0xFFFFFF00FFFF00FF, + 0xFFFFFF00FFFFFF00, 0xFFFFFF00FFFFFFFF, + 0xFFFFFFFF00000000, 0xFFFFFFFF000000FF, + 0xFFFFFFFF0000FF00, 0xFFFFFFFF0000FFFF, + 0xFFFFFFFF00FF0000, 0xFFFFFFFF00FF00FF, + 0xFFFFFFFF00FFFF00, 0xFFFFFFFF00FFFFFF, + 0xFFFFFFFFFF000000, 0xFFFFFFFFFF0000FF, + 0xFFFFFFFFFF00FF00, 0xFFFFFFFFFF00FFFF, + 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFF00FF, + 0xFFFFFFFFFFFFFF00, 0xFFFFFFFFFFFFFFFF, +#endif /* PGSZ */ +}; +#endif /* PSZ == 8 */ + +#if PSZ == 16 +PixelGroup QuartetPixelMaskTable[] = { +#if PGSZ == 32 + 0x00000000, + 0x0000FFFF, + 0xFFFF0000, + 0xFFFFFFFF, +#else /* PGSZ == 64 */ + 0x0000000000000000, 0x000000000000FFFF, + 0x00000000FFFF0000, 0x00000000FFFFFFFF, + 0x0000FFFF00000000, 0x0000FFFF0000FFFF, + 0x0000FFFFFFFF0000, 0x0000FFFFFFFFFFFF, + 0xFFFF000000000000, 0xFFFF00000000FFFF, + 0xFFFF0000FFFF0000, 0xFFFF0000FFFFFFFF, + 0xFFFFFFFF00000000, 0xFFFFFFFF0000FFFF, + 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFFFFFF, +#endif /* PGSZ */ +}; +#endif /* PSZ == 16 */ + +#if PSZ == 32 +PixelGroup QuartetPixelMaskTable[] = { +#if PGSZ == 32 + 0x00000000, + 0xFFFFFFFF, +#else /* PGSZ == 64 */ + 0x0000000000000000, + 0x00000000FFFFFFFF, + 0xFFFFFFFF00000000, + 0xFFFFFFFFFFFFFFFF +#endif /* PGSZ */ +}; +#endif /* PSZ == 32 */ diff --git a/cfb/cfbmskbits.h b/cfb/cfbmskbits.h new file mode 100644 index 000000000..7de664157 --- /dev/null +++ b/cfb/cfbmskbits.h @@ -0,0 +1,672 @@ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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. + +********************************************************/ + +/* $Xorg: cfbmskbits.h,v 1.3 2000/08/17 19:48:14 cpqbld Exp $ */ +/* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" + +/* + * ========================================================================== + * Converted from mfb to support memory-mapped color framebuffer by smarks@sun, + * April-May 1987. + * + * The way I did the conversion was to consider each longword as an + * array of four bytes instead of an array of 32 one-bit pixels. So + * getbits() and putbits() retain much the same calling sequence, but + * they move bytes around instead of bits. Of course, this entails the + * removal of all of the one-bit-pixel dependencies from the other + * files, but the major bit-hacking stuff should be covered here. + * + * I've created some new macros that make it easier to understand what's + * going on in the pixel calculations, and that make it easier to change the + * pixel size. + * + * name explanation + * ---- ----------- + * PSZ pixel size (in bits) + * PGSZ pixel group size (in bits) + * PGSZB pixel group size (in bytes) + * PGSZBMSK mask with lowest PGSZB bits set to 1 + * PPW pixels per word (pixels per pixel group) + * PPWMSK mask with lowest PPW bits set to 1 + * PLST index of last pixel in a word (should be PPW-1) + * PIM pixel index mask (index within a pixel group) + * PWSH pixel-to-word shift (should be log2(PPW)) + * PMSK mask with lowest PSZ bits set to 1 + * + * + * Here are some sample values. In the notation cfbA,B: A is PSZ, and + * B is PGSZB. All the other values are derived from these + * two. This table does not show all combinations! + * + * name cfb8,4 cfb32,4 cfb8,8 cfb32,8 + * ---- ------ ------- ------ ------- + * PSZ 8 32 8 32 + * PGSZ 32 32 64 64 + * PGSZB 4 4 8 8 + * PGSZBMSK 0xF 0xF 0xFF 0xFF + * PPW 4 1 8 2 + * PPWMSK 0xF 0x1 0xFF 0x3 + * PLST 3 0 7 1 + * PIM 0x3 0x0 0x7 0x1 + * PWSH 2 0 3 1 + * PMSK 0xFF 0xFFFFFFFF 0xFF 0xFFFFFFFF + * + * + * I have also added a new macro, PFILL, that takes one pixel and + * replicates it throughout a word. This macro definition is dependent + * upon pixel and word size; it doesn't use macros like PPW and so + * forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) => + * 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro + * is used primarily for replicating a plane mask into a word. + * + * Color framebuffers operations also support the notion of a plane + * mask. This mask determines which planes of the framebuffer can be + * altered; the others are left unchanged. I have added another + * parameter to the putbits and putbitsrop macros that is the plane + * mask. + * ========================================================================== + */ + +/* + * PSZ needs to be defined before we get here. Usually it comes from a + * -DPSZ=foo on the compilation command line. + */ + +/* + * PixelGroup is the data type used to operate on groups of pixels. + * We typedef it here to unsigned long with the assumption that you + * want to manipulate as many pixels at a time as you can. If unsigned + * long is not appropriate for your server, define it to something else + * before including this file. In this case you will also have to define + * PGSZB to the size in bytes of PixelGroup. + */ +#ifndef PixelGroup +typedef unsigned long PixelGroup; +#ifdef LONG64 +#define PGSZB 8 +#else +#define PGSZB 4 +#endif /* LONG64 */ +#endif /* PixelGroup */ + +#define PGSZ (PGSZB << 3) +#define PPW (PGSZ/PSZ) +#define PLST (PPW-1) +#define PIM PLST +#define PMSK (((PixelGroup)1 << PSZ) - 1) +#define PPWMSK (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */ +#define PGSZBMSK (((PixelGroup)1 << PGSZB) - 1) + +/* set PWSH = log2(PPW) using brute force */ + +#if PPW == 1 +#define PWSH 0 +#else +#if PPW == 2 +#define PWSH 1 +#else +#if PPW == 4 +#define PWSH 2 +#else +#if PPW == 8 +#define PWSH 3 +#else +#if PPW == 16 +#define PWSH 4 +#endif /* PPW == 16 */ +#endif /* PPW == 8 */ +#endif /* PPW == 4 */ +#endif /* PPW == 2 */ +#endif /* PPW == 1 */ + +/* Defining PIXEL_ADDR means that individual pixels are addressable by this + * machine (as type PixelType). A possible CFB architecture which supported + * 8-bits-per-pixel on a non byte-addressable machine would not have this + * defined. + * + * Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine; + * eventually, stippling code for 16 and 32 bit devices should be written + * which would allow them to also use FOUR_BIT_CODE. There isn't that + * much to do in those cases, but it would make them quite a bit faster. + */ + +#if PSZ == 8 +#define PIXEL_ADDR +typedef CARD8 PixelType; +#define FOUR_BIT_CODE +#endif + +#if PSZ == 16 +#define PIXEL_ADDR +typedef CARD16 PixelType; +#endif + +#if PSZ == 32 +#undef PMSK +#define PMSK 0xFFFFFFFF +#define PIXEL_ADDR +typedef CARD32 PixelType; +#endif + + +/* the following notes use the following conventions: +SCREEN LEFT SCREEN RIGHT +in this file and maskbits.c, left and right refer to screen coordinates, +NOT bit numbering in registers. + +cfbstarttab[n] + pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's +cfbendtab[n] = + pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's + +cfbstartpartial[], cfbendpartial[] + these are used as accelerators for doing putbits and masking out +bits that are all contained between longword boudaries. the extra +256 bytes of data seems a small price to pay -- code is smaller, +and narrow things (e.g. window borders) go faster. + +the names may seem misleading; they are derived not from which end +of the word the bits are turned on, but at which end of a scanline +the table tends to be used. + +look at the tables and macros to understand boundary conditions. +(careful readers will note that starttab[n] = ~endtab[n] for n != 0) + +----------------------------------------------------------------------- +these two macros depend on the screen's bit ordering. +in both of them x is a screen position. they are used to +combine bits collected from multiple longwords into a +single destination longword, and to unpack a single +source longword into multiple destinations. + +SCRLEFT(dst, x) + takes dst[x, PPW] and moves them to dst[0, PPW-x] + the contents of the rest of dst are 0 ONLY IF + dst is UNSIGNED. + is cast as an unsigned. + this is a right shift on the VAX, left shift on + Sun and pc-rt. + +SCRRIGHT(dst, x) + takes dst[0,x] and moves them to dst[PPW-x, PPW] + the contents of the rest of dst are 0 ONLY IF + dst is UNSIGNED. + this is a left shift on the VAX, right shift on + Sun and pc-rt. + + +the remaining macros are cpu-independent; all bit order dependencies +are built into the tables and the two macros above. + +maskbits(x, w, startmask, endmask, nlw) + for a span of width w starting at position x, returns +a mask for ragged pixels at start, mask for ragged pixels at end, +and the number of whole longwords between the ends. + +maskpartialbits(x, w, mask) + works like maskbits(), except all the pixels are in the + same longword (i.e. (x&0xPIM + w) <= PPW) + +mask32bits(x, w, startmask, endmask, nlw) + as maskbits, but does not calculate nlw. it is used by + cfbGlyphBlt to put down glyphs <= PPW bits wide. + +getbits(psrc, x, w, dst) + starting at position x in psrc (x < PPW), collect w + pixels and put them in the screen left portion of dst. + psrc is a longword pointer. this may span longword boundaries. + it special-cases fetching all w bits from one longword. + + +--------+--------+ +--------+ + | | m |n| | ==> | m |n| | + +--------+--------+ +--------+ + x x+w 0 w + psrc psrc+1 dst + m = PPW - x + n = w - m + + implementation: + get m pixels, move to screen-left of dst, zeroing rest of dst; + get n pixels from next word, move screen-right by m, zeroing + lower m pixels of word. + OR the two things together. + +putbits(src, x, w, pdst, planemask) + starting at position x in pdst, put down the screen-leftmost + w bits of src. pdst is a longword pointer. this may + span longword boundaries. + it special-cases putting all w bits into the same longword. + + +--------+ +--------+--------+ + | m |n| | ==> | | m |n| | + +--------+ +--------+--------+ + 0 w x x+w + dst pdst pdst+1 + m = PPW - x + n = w - m + + implementation: + get m pixels, shift screen-right by x, zero screen-leftmost x + pixels; zero rightmost m bits of *pdst and OR in stuff + from before the semicolon. + shift src screen-left by m, zero bits n-32; + zero leftmost n pixels of *(pdst+1) and OR in the + stuff from before the semicolon. + +putbitsrop(src, x, w, pdst, planemask, ROP) + like putbits but calls DoRop with the rasterop ROP (see cfb.h for + DoRop) + +getleftbits(psrc, w, dst) + get the leftmost w (w<=PPW) bits from *psrc and put them + in dst. this is used by the cfbGlyphBlt code for glyphs + <=PPW bits wide. +*/ + +#if (BITMAP_BIT_ORDER == MSBFirst) +#define BitRight(lw,n) ((lw) >> (n)) +#define BitLeft(lw,n) ((lw) << (n)) +#else /* (BITMAP_BIT_ORDER == LSBFirst) */ +#define BitRight(lw,n) ((lw) << (n)) +#define BitLeft(lw,n) ((lw) >> (n)) +#endif /* (BITMAP_BIT_ORDER == MSBFirst) */ + +#define SCRLEFT(lw, n) BitLeft (lw, (n) * PSZ) +#define SCRRIGHT(lw, n) BitRight(lw, (n) * PSZ) + +/* + * Note that the shift direction is independent of the byte ordering of the + * machine. The following is portable code. + */ +#if PPW == 16 +#define PFILL(p) ( ((p)&PMSK) | \ + ((p)&PMSK) << PSZ | \ + ((p)&PMSK) << 2*PSZ | \ + ((p)&PMSK) << 3*PSZ | \ + ((p)&PMSK) << 4*PSZ | \ + ((p)&PMSK) << 5*PSZ | \ + ((p)&PMSK) << 6*PSZ | \ + ((p)&PMSK) << 7*PSZ | \ + ((p)&PMSK) << 8*PSZ | \ + ((p)&PMSK) << 9*PSZ | \ + ((p)&PMSK) << 10*PSZ | \ + ((p)&PMSK) << 11*PSZ | \ + ((p)&PMSK) << 12*PSZ | \ + ((p)&PMSK) << 13*PSZ | \ + ((p)&PMSK) << 14*PSZ | \ + ((p)&PMSK) << 15*PSZ ) +#define PFILL2(p, pf) { \ + pf = (p) & PMSK; \ + pf |= (pf << PSZ); \ + pf |= (pf << 2*PSZ); \ + pf |= (pf << 4*PSZ); \ + pf |= (pf << 8*PSZ); \ +} +#endif /* PPW == 16 */ +#if PPW == 8 +#define PFILL(p) ( ((p)&PMSK) | \ + ((p)&PMSK) << PSZ | \ + ((p)&PMSK) << 2*PSZ | \ + ((p)&PMSK) << 3*PSZ | \ + ((p)&PMSK) << 4*PSZ | \ + ((p)&PMSK) << 5*PSZ | \ + ((p)&PMSK) << 6*PSZ | \ + ((p)&PMSK) << 7*PSZ ) +#define PFILL2(p, pf) { \ + pf = (p) & PMSK; \ + pf |= (pf << PSZ); \ + pf |= (pf << 2*PSZ); \ + pf |= (pf << 4*PSZ); \ +} +#endif +#if PPW == 4 +#define PFILL(p) ( ((p)&PMSK) | \ + ((p)&PMSK) << PSZ | \ + ((p)&PMSK) << 2*PSZ | \ + ((p)&PMSK) << 3*PSZ ) +#define PFILL2(p, pf) { \ + pf = (p) & PMSK; \ + pf |= (pf << PSZ); \ + pf |= (pf << 2*PSZ); \ +} +#endif +#if PPW == 2 +#define PFILL(p) ( ((p)&PMSK) | \ + ((p)&PMSK) << PSZ ) +#define PFILL2(p, pf) { \ + pf = (p) & PMSK; \ + pf |= (pf << PSZ); \ +} +#endif +#if PPW == 1 +#define PFILL(p) (p) +#define PFILL2(p,pf) (pf = (p)) +#endif + +/* + * Reduced raster op - using precomputed values, perform the above + * in three instructions + */ + +#define DoRRop(dst, and, xor) (((dst) & (and)) ^ (xor)) + +#define DoMaskRRop(dst, and, xor, mask) \ + (((dst) & ((and) | ~(mask))) ^ (xor & mask)) + +#if PSZ != 32 || PPW != 1 + +#define maskbits(x, w, startmask, endmask, nlw) \ + startmask = cfbstarttab[(x)&PIM]; \ + endmask = cfbendtab[((x)+(w)) & PIM]; \ + if (startmask) \ + nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \ + else \ + nlw = (w) >> PWSH; + +#define maskpartialbits(x, w, mask) \ + mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM]; + +#define mask32bits(x, w, startmask, endmask) \ + startmask = cfbstarttab[(x)&PIM]; \ + endmask = cfbendtab[((x)+(w)) & PIM]; + + +#define getbits(psrc, x, w, dst) \ +if ( ((x) + (w)) <= PPW) \ +{ \ + dst = SCRLEFT(*(psrc), (x)); \ +} \ +else \ +{ \ + int m; \ + m = PPW-(x); \ + dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \ + (SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \ +} + + +#define putbits(src, x, w, pdst, planemask) \ +if ( ((x)+(w)) <= PPW) \ +{ \ + PixelGroup tmpmask; \ + maskpartialbits((x), (w), tmpmask); \ + tmpmask &= PFILL(planemask); \ + *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \ +} \ +else \ +{ \ + unsigned long m; \ + unsigned long n; \ + PixelGroup pm = PFILL(planemask); \ + m = PPW-(x); \ + n = (w) - m; \ + *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \ + (SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \ + *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \ + (SCRLEFT(src, m) & (cfbendtab[n] & pm)); \ +} +#if defined(__GNUC__) && defined(mc68020) +#undef getbits +#define FASTGETBITS(psrc, x, w, dst) \ + asm ("bfextu %3{%1:%2},%0" \ + : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc))) + +#define getbits(psrc,x,w,dst) \ +{ \ + FASTGETBITS(psrc, (x) * PSZ, (w) * PSZ, dst); \ + dst = SCRLEFT(dst,PPW-(w)); \ +} + +#define FASTPUTBITS(src, x, w, pdst) \ + asm ("bfins %3,%0{%1:%2}" \ + : "=o" (*(char *)(pdst)) \ + : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst))) + +#undef putbits +#define putbits(src, x, w, pdst, planemask) \ +{ \ + if (planemask != PMSK) { \ + PixelGroup _m, _pm; \ + FASTGETBITS(pdst, (x) * PSZ , (w) * PSZ, _m); \ + PFILL2(planemask, _pm); \ + _m &= (~_pm); \ + _m |= (SCRRIGHT(src, PPW-(w)) & _pm); \ + FASTPUTBITS(_m, (x) * PSZ, (w) * PSZ, pdst); \ + } else { \ + FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \ + } \ +} + + +#endif /* mc68020 */ + +#define putbitsrop(src, x, w, pdst, planemask, rop) \ +if ( ((x)+(w)) <= PPW) \ +{ \ + PixelGroup tmpmask; \ + PixelGroup t1, t2; \ + maskpartialbits((x), (w), tmpmask); \ + PFILL2(planemask, t1); \ + tmpmask &= t1; \ + t1 = SCRRIGHT((src), (x)); \ + DoRop(t2, rop, t1, *(pdst)); \ + *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \ +} \ +else \ +{ \ + unsigned long m; \ + unsigned long n; \ + PixelGroup t1, t2; \ + PixelGroup pm; \ + PFILL2(planemask, pm); \ + m = PPW-(x); \ + n = (w) - m; \ + t1 = SCRRIGHT((src), (x)); \ + DoRop(t2, rop, t1, *(pdst)); \ + *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\ + t1 = SCRLEFT((src), m); \ + DoRop(t2, rop, t1, *((pdst) + 1)); \ + *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \ + (t2 & (cfbendtab[n] & pm)); \ +} + +#else /* PSZ == 32 && PPW == 1*/ + +/* + * These macros can be optimized for 32-bit pixels since there is no + * need to worry about left/right edge masking. These macros were + * derived from the above using the following reductions: + * + * - x & PIW = 0 [since PIW = 0] + * - all masking tables are only indexed by 0 [ due to above ] + * - cfbstartab[0] and cfbendtab[0] = 0 [ no left/right edge masks] + * - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask] + * + * Macro reduction based upon constants cannot be performed automatically + * by the compiler since it does not know the contents of the masking + * arrays in cfbmskbits.c. + */ +#define maskbits(x, w, startmask, endmask, nlw) \ + startmask = endmask = 0; \ + nlw = (w); + +#define maskpartialbits(x, w, mask) \ + mask = 0xFFFFFFFF; + +#define mask32bits(x, w, startmask, endmask) \ + startmask = endmask = 0; + +/* + * For 32-bit operations, getbits(), putbits(), and putbitsrop() + * will only be invoked with x = 0 and w = PPW (1). The getbits() + * macro is only called within left/right edge logic, which doesn't + * happen for 32-bit pixels. + */ +#define getbits(psrc, x, w, dst) (dst) = *(psrc) + +#define putbits(src, x, w, pdst, planemask) \ + *(pdst) = (*(pdst) & ~planemask) | (src & planemask); + +#define putbitsrop(src, x, w, pdst, planemask, rop) \ +{ \ + PixelGroup t1; \ + DoRop(t1, rop, (src), *(pdst)); \ + *(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \ +} + +#endif /* PSZ != 32 */ + +/* + * Use these macros only when you're using the MergeRop stuff + * in ../mfb/mergerop.h + */ + +/* useful only when not spanning destination longwords */ +#define putbitsmropshort(src,x,w,pdst) {\ + PixelGroup _tmpmask; \ + PixelGroup _t1; \ + maskpartialbits ((x), (w), _tmpmask); \ + _t1 = SCRRIGHT((src), (x)); \ + *pdst = DoMaskMergeRop(_t1, *pdst, _tmpmask); \ +} + +/* useful only when spanning destination longwords */ +#define putbitsmroplong(src,x,w,pdst) { \ + PixelGroup _startmask, _endmask; \ + int _m; \ + PixelGroup _t1; \ + _m = PPW - (x); \ + _startmask = cfbstarttab[x]; \ + _endmask = cfbendtab[(w) - _m]; \ + _t1 = SCRRIGHT((src), (x)); \ + pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \ + _t1 = SCRLEFT ((src),_m); \ + pdst[1] = DoMaskMergeRop(_t1,pdst[1],_endmask); \ +} + +#define putbitsmrop(src,x,w,pdst) \ +if ((x) + (w) <= PPW) {\ + putbitsmropshort(src,x,w,pdst); \ +} else { \ + putbitsmroplong(src,x,w,pdst); \ +} + +#if GETLEFTBITS_ALIGNMENT == 1 +#define getleftbits(psrc, w, dst) dst = *((unsigned int *) psrc) +#endif /* GETLEFTBITS_ALIGNMENT == 1 */ + +#define getglyphbits(psrc, x, w, dst) \ +{ \ + dst = BitLeft((unsigned) *(psrc), (x)); \ + if ( ((x) + (w)) > 32) \ + dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \ +} +#if GETLEFTBITS_ALIGNMENT == 2 +#define getleftbits(psrc, w, dst) \ + { \ + if ( ((int)(psrc)) & 0x01 ) \ + getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \ + else \ + dst = *((unsigned int *) psrc); \ + } +#endif /* GETLEFTBITS_ALIGNMENT == 2 */ + +#if GETLEFTBITS_ALIGNMENT == 4 +#define getleftbits(psrc, w, dst) \ + { \ + int off, off_b; \ + off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \ + getglyphbits( \ + (unsigned int *)( ((char *)(psrc)) - off), \ + (off_b), (w), (dst) \ + ); \ + } +#endif /* GETLEFTBITS_ALIGNMENT == 4 */ + +/* + * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) + * + * Converts bits to pixels in a reasonable way. Takes w (1 <= w <= PPW) + * bits from *psrcstip, starting at bit x; call this a quartet of bits. + * Then, takes the pixels from *psrcpix corresponding to the one-bits (if + * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet + * and puts these pixels into destpix. + * + * Example: + * + * getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest ) + * + * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011 + * + * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101. + * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this + * quartet, so dest = 0x005D007F. + * + * XXX Works with both byte order. + * XXX This works for all values of x and w within a doubleword. + */ +#if (BITMAP_BIT_ORDER == MSBFirst) +#define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \ +{ \ + PixelGroup q; \ + int m; \ + if ((m = ((x) - ((PPW*PSZ)-PPW))) > 0) { \ + q = (*(psrcstip)) << m; \ + if ( (x)+(w) > (PPW*PSZ) ) \ + q |= *((psrcstip)+1) >> ((PPW*PSZ)-m); \ + } \ + else \ + q = (*(psrcstip)) >> -m; \ + q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \ + *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \ +} +#else /* BITMAP_BIT_ORDER == LSB */ +#define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \ +{ \ + PixelGroup q; \ + q = *(psrcstip) >> (xt); \ + if ( ((xt)+(w)) > (PPW*PSZ) ) \ + q |= (*((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \ + q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \ + *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \ +} +#endif + +extern PixelGroup cfbstarttab[]; +extern PixelGroup cfbendtab[]; +extern PixelGroup cfbstartpartial[]; +extern PixelGroup cfbendpartial[]; +extern PixelGroup cfbrmask[]; +extern PixelGroup cfbmask[]; +extern PixelGroup QuartetBitsTable[]; +extern PixelGroup QuartetPixelMaskTable[]; diff --git a/cfb/cfbpixmap.c b/cfb/cfbpixmap.c new file mode 100644 index 000000000..37cec5c7d --- /dev/null +++ b/cfb/cfbpixmap.c @@ -0,0 +1,370 @@ +/* $Xorg: cfbpixmap.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. + +******************************************************************/ +/* pixmap management + written by drewry, september 1986 + + on a monchrome device, a pixmap is a bitmap. +*/ + +#include "Xmd.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "mi.h" +#include "cfb.h" +#include "cfbmskbits.h" + +extern unsigned long endtab[]; + +PixmapPtr +cfbCreatePixmap (pScreen, width, height, depth) + ScreenPtr pScreen; + int width; + int height; + int depth; +{ + PixmapPtr pPixmap; + int datasize; + int paddedWidth; + + paddedWidth = PixmapBytePad(width, depth); + datasize = height * paddedWidth; + pPixmap = AllocatePixmap(pScreen, datasize); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth); + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = paddedWidth; + pPixmap->refcnt = 1; +#ifdef PIXPRIV + pPixmap->devPrivate.ptr = datasize ? + (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL; +#else + pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1); +#endif + return pPixmap; +} + +Bool +cfbDestroyPixmap(pPixmap) + PixmapPtr pPixmap; +{ + if(--pPixmap->refcnt) + return TRUE; + xfree(pPixmap); + return TRUE; +} + +PixmapPtr +cfbCopyPixmap(pSrc) + register PixmapPtr pSrc; +{ + register PixmapPtr pDst; + int size; + ScreenPtr pScreen; + + size = pSrc->drawable.height * pSrc->devKind; + pScreen = pSrc->drawable.pScreen; + pDst = (*pScreen->CreatePixmap) (pScreen, pSrc->drawable.width, + pSrc->drawable.height, pSrc->drawable.depth); + if (!pDst) + return NullPixmap; + memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size); + return pDst; +} + + +/* replicates a pattern to be a full 32 bits wide. + relies on the fact that each scnaline is longword padded. + doesn't do anything if pixmap is not a factor of 32 wide. + changes width field of pixmap if successful, so that the fast + cfbXRotatePixmap code gets used if we rotate the pixmap later. + cfbYRotatePixmap code gets used if we rotate the pixmap later. + + calculate number of times to repeat + for each scanline of pattern + zero out area to be filled with replicate + left shift and or in original as many times as needed +*/ +void +cfbPadPixmap(pPixmap) + PixmapPtr pPixmap; +{ + register int width = (pPixmap->drawable.width) * (pPixmap->drawable.bitsPerPixel); + register int h; + register unsigned long mask; + register unsigned long *p; + register unsigned long bits; /* real pattern bits */ + register int i; + int rep; /* repeat count for pattern */ + + if (width >= PGSZ) + return; + + rep = PGSZ/width; + if (rep*width != PGSZ) + return; + + mask = endtab[width]; + + p = (unsigned long *)(pPixmap->devPrivate.ptr); + for (h=0; h < pPixmap->drawable.height; h++) + { + *p &= mask; + bits = *p; + for(i=1; i<rep; i++) + { +#if (BITMAP_BIT_ORDER == MSBFirst) + bits >>= width; +#else + bits <<= width; +#endif + *p |= bits; + } + p++; + } + pPixmap->drawable.width = PGSZ/(pPixmap->drawable.bitsPerPixel); +} + + +#ifdef notdef +/* + * cfb debugging routine -- assumes pixmap is 1 byte deep + */ +static cfbdumppixmap(pPix) + PixmapPtr pPix; +{ + unsigned int *pw; + char *psrc, *pdst; + int i, j; + char line[66]; + + ErrorF( "pPixmap: 0x%x\n", pPix); + ErrorF( "%d wide %d high\n", pPix->drawable.width, pPix->drawable.height); + if (pPix->drawable.width > 64) + { + ErrorF( "too wide to see\n"); + return; + } + + pw = (unsigned int *) pPix->devPrivate.ptr; + psrc = (char *) pw; + +/* + for ( i=0; i<pPix->drawable.height; ++i ) + ErrorF( "0x%x\n", pw[i] ); +*/ + + for ( i = 0; i < pPix->drawable.height; ++i ) { + pdst = line; + for(j = 0; j < pPix->drawable.width; j++) { + *pdst++ = *psrc++ ? 'X' : ' ' ; + } + *pdst++ = '\n'; + *pdst++ = '\0'; + ErrorF( "%s", line); + } +} +#endif /* notdef */ + +/* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that + * words are PGSZ bits wide, and that the least significant bit appears on the + * left. + */ +void +cfbXRotatePixmap(pPix, rw) + PixmapPtr pPix; + register int rw; +{ + register unsigned long *pw, *pwFinal; + register unsigned long t; + int rot; + + if (pPix == NullPixmap) + return; + + switch (((DrawablePtr) pPix)->bitsPerPixel) { + case PSZ: + break; + case 1: + mfbXRotatePixmap(pPix, rw); + return; + default: + ErrorF("cfbXRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel); + return; + } + pw = (unsigned long *)pPix->devPrivate.ptr; + modulus (rw, (int) pPix->drawable.width, rot); + if(pPix->drawable.width == PPW) + { + pwFinal = pw + pPix->drawable.height; + while(pw < pwFinal) + { + t = *pw; + *pw++ = SCRRIGHT(t, rot) | + (SCRLEFT(t, (PPW-rot)) & cfbendtab[rot]); + } + } + else + { + ErrorF("cfb internal error: trying to rotate odd-sized pixmap.\n"); +#ifdef notdef + register unsigned long *pwTmp; + int size, tsize; + + tsize = PixmapBytePad(pPix->drawable.width - rot, pPix->drawable.depth); + pwTmp = (unsigned long *) ALLOCATE_LOCAL(pPix->drawable.height * tsize); + if (!pwTmp) + return; + /* divide pw (the pixmap) in two vertically at (w - rot) and swap */ + tsize >>= 2; + size = pPix->devKind >> SIZE0F(PixelGroup); + cfbQuickBlt((long *)pw, (long *)pwTmp, + 0, 0, 0, 0, + (int)pPix->drawable.width - rot, (int)pPix->drawable.height, + size, tsize); + cfbQuickBlt((long *)pw, (long *)pw, + (int)pPix->drawable.width - rot, 0, 0, 0, + rot, (int)pPix->drawable.height, + size, size); + cfbQuickBlt((long *)pwTmp, (long *)pw, + 0, 0, rot, 0, + (int)pPix->drawable.width - rot, (int)pPix->drawable.height, + tsize, size); + DEALLOCATE_LOCAL(pwTmp); +#endif + } +} + +/* Rotates pixmap pPix by h lines. Assumes that h is always less than + pPix->drawable.height + works on any width. + */ +void +cfbYRotatePixmap(pPix, rh) + register PixmapPtr pPix; + int rh; +{ + int nbyDown; /* bytes to move down to row 0; also offset of + row rh */ + int nbyUp; /* bytes to move up to line rh; also + offset of first line moved down to 0 */ + char *pbase; + char *ptmp; + int rot; + + if (pPix == NullPixmap) + return; + switch (((DrawablePtr) pPix)->bitsPerPixel) { + case PSZ: + break; + case 1: + mfbYRotatePixmap(pPix, rh); + return; + default: + ErrorF("cfbYRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel); + return; + } + + modulus (rh, (int) pPix->drawable.height, rot); + pbase = (char *)pPix->devPrivate.ptr; + + nbyDown = rot * pPix->devKind; + nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown; + if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp))) + return; + + memmove(ptmp, pbase, nbyUp); /* save the low rows */ + memmove(pbase, pbase+nbyUp, nbyDown); /* slide the top rows down */ + memmove(pbase+nbyDown, ptmp, nbyUp); /* move lower rows up to row rot */ + DEALLOCATE_LOCAL(ptmp); +} + +void +cfbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot) + register PixmapPtr psrcPix, *ppdstPix; + int xrot, yrot; +{ + register PixmapPtr pdstPix; + + if ((pdstPix = *ppdstPix) && + (pdstPix->devKind == psrcPix->devKind) && + (pdstPix->drawable.height == psrcPix->drawable.height)) + { + memmove((char *)pdstPix->devPrivate.ptr, + (char *)psrcPix->devPrivate.ptr, + psrcPix->drawable.height * psrcPix->devKind); + pdstPix->drawable.width = psrcPix->drawable.width; + pdstPix->drawable.depth = psrcPix->drawable.depth; + pdstPix->drawable.bitsPerPixel = psrcPix->drawable.bitsPerPixel; + pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } + else + { + if (pdstPix) + /* FIX XBUG 6168 */ + (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix); + *ppdstPix = pdstPix = cfbCopyPixmap(psrcPix); + if (!pdstPix) + return; + } + cfbPadPixmap(pdstPix); + if (xrot) + cfbXRotatePixmap(pdstPix, xrot); + if (yrot) + cfbYRotatePixmap(pdstPix, yrot); +} diff --git a/cfb/cfbply1rct.c b/cfb/cfbply1rct.c new file mode 100644 index 000000000..b1e5c8ff1 --- /dev/null +++ b/cfb/cfbply1rct.c @@ -0,0 +1,318 @@ +/* + * $Xorg: cfbply1rct.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +#include "X.h" + +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "mistruct.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfbrrop.h" + +void +RROP_NAME(cfbFillPoly1Rect) (pDrawable, pGC, shape, mode, count, ptsIn) + DrawablePtr pDrawable; + GCPtr pGC; + int shape; + int mode; + int count; + DDXPointPtr ptsIn; +{ + cfbPrivGCPtr devPriv; + int nwidth; + unsigned long *addrl, *addr; + int maxy; + int origin; + register int vertex1, vertex2; + int c; + BoxPtr extents; + int clip; + int y; + int *vertex1p, *vertex2p; + int *endp; + int x1, x2; + int dx1, dx2; + int dy1, dy2; + int e1, e2; + int step1, step2; + int sign1, sign2; + int h; + int l, r; + unsigned long mask, bits = ~((unsigned long)0); + int nmiddle; + RROP_DECLARE + + if (mode == CoordModePrevious) + { + miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn); + return; + } + + devPriv = cfbGetGCPrivate(pGC); +#ifdef NO_ONE_RECT + if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1) + { + miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn); + return; + } +#endif + origin = *((int *) &pDrawable->x); + vertex2 = origin - ((origin & 0x8000) << 1); + extents = &devPriv->pCompositeClip->extents; + RROP_FETCH_GCPRIV(devPriv); + vertex1 = *((int *) &extents->x1) - vertex2; + vertex2 = *((int *) &extents->x2) - vertex2 - 0x00010001; + clip = 0; + y = 32767; + maxy = 0; + vertex2p = (int *) ptsIn; + endp = vertex2p + count; + if (shape == Convex) + { + while (count--) + { + c = *vertex2p; + clip |= (c - vertex1) | (vertex2 - c); + c = intToY(c); + if (c < y) + { + y = c; + vertex1p = vertex2p; + } + vertex2p++; + if (c > maxy) + maxy = c; + } + } + else + { + int yFlip = 0; + dx1 = 1; + x2 = -1; + x1 = -1; + while (count--) + { + c = *vertex2p; + clip |= (c - vertex1) | (vertex2 - c); + c = intToY(c); + if (c < y) + { + y = c; + vertex1p = vertex2p; + } + vertex2p++; + if (c > maxy) + maxy = c; + if (c == x1) + continue; + if (dx1 > 0) + { + if (x2 < 0) + x2 = c; + else + dx2 = dx1 = (c - x1) >> 31; + } + else + if ((c - x1) >> 31 != dx1) + { + dx1 = ~dx1; + yFlip++; + } + x1 = c; + } + x1 = (x2 - c) >> 31; + if (x1 != dx1) + yFlip++; + if (x1 != dx2) + yFlip++; + if (yFlip != 2) + clip = 0x8000; + } + if (y == maxy) + return; + + if (clip & 0x80008000) + { + miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn); + return; + } + +#define AddrYPlus(a,y) (unsigned long *) (((unsigned char *) (a)) + (y) * nwidth) + + cfbGetTypedWidthAndPointer(pDrawable, nwidth, addrl, unsigned char, unsigned long); + addrl = AddrYPlus(addrl,y + pDrawable->y); + origin = intToX(origin); + vertex2p = vertex1p; + vertex2 = vertex1 = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; +#define Setup(c,x,vertex,dx,dy,e,sign,step) {\ + x = intToX(vertex); \ + if (dy = intToY(c) - y) { \ + dx = intToX(c) - x; \ + step = 0; \ + if (dx >= 0) \ + { \ + e = 0; \ + sign = 1; \ + if (dx >= dy) {\ + step = dx / dy; \ + dx = dx % dy; \ + } \ + } \ + else \ + { \ + e = 1 - dy; \ + sign = -1; \ + dx = -dx; \ + if (dx >= dy) { \ + step = - (dx / dy); \ + dx = dx % dy; \ + } \ + } \ + } \ + x += origin; \ + vertex = c; \ +} + +#define Step(x,dx,dy,e,sign,step) {\ + x += step; \ + if ((e += dx) > 0) \ + { \ + x += sign; \ + e -= dy; \ + } \ +} + for (;;) + { + if (y == intToY(vertex1)) + { + do + { + if (vertex1p == (int *) ptsIn) + vertex1p = endp; + c = *--vertex1p; + Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1) + } while (y >= intToY(vertex1)); + h = dy1; + } + else + { + Step(x1,dx1,dy1,e1,sign1,step1) + h = intToY(vertex1) - y; + } + if (y == intToY(vertex2)) + { + do + { + c = *vertex2p++; + if (vertex2p == endp) + vertex2p = (int *) ptsIn; + Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2) + } while (y >= intToY(vertex2)); + if (dy2 < h) + h = dy2; + } + else + { + Step(x2,dx2,dy2,e2,sign2,step2) + if ((c = (intToY(vertex2) - y)) < h) + h = c; + } + /* fill spans for this segment */ + y += h; + for (;;) + { + l = x1; + r = x2; + nmiddle = x2 - x1; + if (nmiddle < 0) + { + nmiddle = -nmiddle; + l = x2; + r = x1; + } +#if PPW > 1 + c = l & PIM; + l -= c; +#endif + +#if PGSZ == 32 +#define LWRD_SHIFT 2 +#else /* PGSZ == 64 */ +#define LWRD_SHIFT 3 +#endif /* PGSZ */ + +#if PWSH > LWRD_SHIFT + l = l >> (PWSH - LWRD_SHIFT); +#endif +#if PWSH < LWRD_SHIFT + l = l << (LWRD_SHIFT - PWSH); +#endif + addr = (unsigned long *) (((char *) addrl) + l); +#if PPW > 1 + if (c + nmiddle < PPW) + { + mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle); + RROP_SOLID_MASK(addr,mask); + } + else + { + if (c) + { + mask = SCRRIGHT(bits, c); + RROP_SOLID_MASK(addr,mask); + nmiddle += c - PPW; + addr++; + } +#endif + nmiddle >>= PWSH; + while (--nmiddle >= 0) { + RROP_SOLID(addr); addr++; + } +#if PPW > 1 + if (mask = ~SCRRIGHT(bits, r & PIM)) + RROP_SOLID_MASK(addr,mask); + } +#endif + if (!--h) + break; + addrl = AddrYPlus (addrl, 1); + Step(x1,dx1,dy1,e1,sign1,step1) + Step(x2,dx2,dy2,e2,sign2,step2) + } + if (y == maxy) + break; + addrl = AddrYPlus (addrl, 1); + } +} diff --git a/cfb/cfbpntwin.c b/cfb/cfbpntwin.c new file mode 100644 index 000000000..bf53cb3f9 --- /dev/null +++ b/cfb/cfbpntwin.c @@ -0,0 +1,370 @@ +/* $Xorg: cfbpntwin.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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 "windowstr.h" +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "mi.h" + +void +cfbPaintWindow(pWin, pRegion, what) + WindowPtr pWin; + RegionPtr pRegion; + int what; +{ + register cfbPrivWin *pPrivWin; + WindowPtr pBgWin; + + pPrivWin = cfbGetWindowPrivate(pWin); + + switch (what) { + case PW_BACKGROUND: + switch (pWin->backgroundState) { + case None: + break; + case ParentRelative: + do { + pWin = pWin->parent; + } while (pWin->backgroundState == ParentRelative); + (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, + what); + break; + case BackgroundPixmap: + if (pPrivWin->fastBackground) + { + cfbFillBoxTile32 ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pPrivWin->pRotatedBackground); + } + else + { + cfbFillBoxTileOdd ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pWin->background.pixmap, + (int) pWin->drawable.x, (int) pWin->drawable.y); + } + break; + case BackgroundPixel: + cfbFillBoxSolid ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pWin->background.pixel); + break; + } + break; + case PW_BORDER: + if (pWin->borderIsPixel) + { + cfbFillBoxSolid ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pWin->border.pixel); + } + else if (pPrivWin->fastBorder) + { + cfbFillBoxTile32 ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pPrivWin->pRotatedBorder); + } + else + { + for (pBgWin = pWin; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + + cfbFillBoxTileOdd ((DrawablePtr)pWin, + (int)REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion), + pWin->border.pixmap, + (int) pBgWin->drawable.x, + (int) pBgWin->drawable.y); + } + break; + } +} + +/* + * Use the RROP macros in copy mode + */ + +#define RROP GXcopy +#include "cfbrrop.h" + +#ifdef RROP_UNROLL +# define Expand(left,right,leftAdjust) {\ + int part = nmiddle & RROP_UNROLL_MASK; \ + int widthStep; \ + widthStep = widthDst - nmiddle - leftAdjust; \ + nmiddle >>= RROP_UNROLL_SHIFT; \ + while (h--) { \ + left \ + pdst += part; \ + switch (part) { \ + RROP_UNROLL_CASE(pdst) \ + } \ + m = nmiddle; \ + while (m) { \ + pdst += RROP_UNROLL; \ + RROP_UNROLL_LOOP(pdst) \ + m--; \ + } \ + right \ + pdst += widthStep; \ + } \ +} + +#else +# define Expand(left, right, leftAdjust) { \ + int widthStep; \ + widthStep = widthDst - nmiddle - leftAdjust; \ + while (h--) { \ + left \ + m = nmiddle; \ + while (m--) {\ + RROP_SOLID(pdst); \ + pdst++; \ + } \ + right \ + pdst += widthStep; \ + } \ +} +#endif + +void +cfbFillBoxSolid (pDrawable, nBox, pBox, pixel) + DrawablePtr pDrawable; + int nBox; + BoxPtr pBox; + unsigned long pixel; +{ + unsigned long *pdstBase; + int widthDst; + register int h; + register unsigned long rrop_xor; + register unsigned long *pdst; + register unsigned long leftMask, rightMask; + int nmiddle; + register int m; + int w; + + cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase); + + rrop_xor = PFILL(pixel); + for (; nBox; nBox--, pBox++) + { + pdst = pdstBase + pBox->y1 * widthDst; + h = pBox->y2 - pBox->y1; + w = pBox->x2 - pBox->x1; +#if PSZ == 8 + if (w == 1) + { + register char *pdstb = ((char *) pdst) + pBox->x1; + int incr = widthDst * PGSZB; + + while (h--) + { + *pdstb = rrop_xor; + pdstb += incr; + } + } + else + { +#endif + pdst += (pBox->x1 >> PWSH); + if ((pBox->x1 & PIM) + w <= PPW) + { + maskpartialbits(pBox->x1, w, leftMask); + while (h--) { + *pdst = (*pdst & ~leftMask) | (rrop_xor & leftMask); + pdst += widthDst; + } + } + else + { + maskbits (pBox->x1, w, leftMask, rightMask, nmiddle); + if (leftMask) + { + if (rightMask) + { + Expand (RROP_SOLID_MASK (pdst, leftMask); pdst++; , + RROP_SOLID_MASK (pdst, rightMask); , + 1) + } + else + { + Expand (RROP_SOLID_MASK (pdst, leftMask); pdst++;, + ;, + 1) + } + } + else + { + if (rightMask) + { + Expand (;, + RROP_SOLID_MASK (pdst, rightMask);, + 0) + } + else + { + Expand (;, + ;, + 0) + } + } + } +#if PSZ == 8 + } +#endif + } +} + +void +cfbFillBoxTile32 (pDrawable, nBox, pBox, tile) + DrawablePtr pDrawable; + int nBox; /* number of boxes to fill */ + BoxPtr pBox; /* pointer to list of boxes to fill */ + PixmapPtr tile; /* rotated, expanded tile */ +{ + register unsigned long rrop_xor; + register unsigned long *pdst; + register int m; + unsigned long *psrc; + int tileHeight; + + int widthDst; + int w; + int h; + register unsigned long leftMask; + register unsigned long rightMask; + int nmiddle; + int y; + int srcy; + + unsigned long *pdstBase; + + tileHeight = tile->drawable.height; + psrc = (unsigned long *)tile->devPrivate.ptr; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase); + + while (nBox--) + { + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + y = pBox->y1; + pdst = pdstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH); + srcy = y % tileHeight; + +#define StepTile rrop_xor = psrc[srcy]; \ + ++srcy; \ + if (srcy == tileHeight) \ + srcy = 0; + + if ( ((pBox->x1 & PIM) + w) < PPW) + { + maskpartialbits(pBox->x1, w, leftMask); + rightMask = ~leftMask; + while (h--) + { + StepTile + *pdst = (*pdst & rightMask) | (rrop_xor & leftMask); + pdst += widthDst; + } + } + else + { + maskbits(pBox->x1, w, leftMask, rightMask, nmiddle); + + if (leftMask) + { + if (rightMask) + { + Expand (StepTile + RROP_SOLID_MASK(pdst, leftMask); pdst++;, + RROP_SOLID_MASK(pdst, rightMask);, + 1) + } + else + { + Expand (StepTile + RROP_SOLID_MASK(pdst, leftMask); pdst++;, + ;, + 1) + } + } + else + { + if (rightMask) + { + Expand (StepTile + , + RROP_SOLID_MASK(pdst, rightMask);, + 0) + } + else + { + Expand (StepTile + , + ;, + 0) + } + } + } + pBox++; + } +} diff --git a/cfb/cfbpolypnt.c b/cfb/cfbpolypnt.c new file mode 100644 index 000000000..bf2217fb1 --- /dev/null +++ b/cfb/cfbpolypnt.c @@ -0,0 +1,150 @@ +/************************************************************ + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +/* $Xorg: cfbpolypnt.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ + +#include "X.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "cfb.h" +#include "cfbmskbits.h" + +#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask) + +/* WARNING: pbox contains two shorts. This code assumes they are packed + * and can be referenced together as an INT32. + */ + +#define PointLoop(fill) { \ + for (nbox = REGION_NUM_RECTS(cclip), pbox = REGION_RECTS(cclip); \ + --nbox >= 0; \ + pbox++) \ + { \ + c1 = *((INT32 *) &pbox->x1) - off; \ + c2 = *((INT32 *) &pbox->x2) - off - 0x00010001; \ + for (ppt = (INT32 *) pptInit, i = npt; --i >= 0;) \ + { \ + pt = *ppt++; \ + if (!isClipped(pt,c1,c2)) { \ + fill \ + } \ + } \ + } \ +} + +void +cfbPolyPoint(pDrawable, pGC, mode, npt, pptInit) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; + int npt; + xPoint *pptInit; +{ + register INT32 pt; + register INT32 c1, c2; + register unsigned long ClipMask = 0x80008000; + register unsigned long xor; +#ifdef PIXEL_ADDR + register PixelType *addrp; + register int npwidth; + PixelType *addrpt; +#else + register unsigned long *addrl; + register int nlwidth; + register int xoffset; + unsigned long *addrlt; +#endif + register INT32 *ppt; + RegionPtr cclip; + int nbox; + register int i; + register BoxPtr pbox; + unsigned long and; + int rop = pGC->alu; + int off; + cfbPrivGCPtr devPriv; + xPoint *pptPrev; + + devPriv =cfbGetGCPrivate(pGC); + rop = devPriv->rop; + if (rop == GXnoop) + return; + cclip = devPriv->pCompositeClip; + xor = devPriv->xor; + if ((mode == CoordModePrevious) && (npt > 1)) + { + for (pptPrev = pptInit + 1, i = npt - 1; --i >= 0; pptPrev++) + { + pptPrev->x += (pptPrev-1)->x; + pptPrev->y += (pptPrev-1)->y; + } + } + off = *((int *) &pDrawable->x); + off -= (off & 0x8000) << 1; +#ifdef PIXEL_ADDR + cfbGetPixelWidthAndPointer(pDrawable, npwidth, addrp); + addrp = addrp + pDrawable->y * npwidth + pDrawable->x; + if (rop == GXcopy) + { + if (!(npwidth & (npwidth - 1))) + { + npwidth = ffs(npwidth) - 1; + PointLoop(*(addrp + (intToY(pt) << npwidth) + intToX(pt)) = xor;) + } +#ifdef sun + else if (npwidth == 1152) + { + register int y; + PointLoop(y = intToY(pt); *(addrp + (y << 10) + (y << 7) + intToX(pt)) = xor;) + } +#endif + else + { + PointLoop(*(addrp + intToY(pt) * npwidth + intToX(pt)) = xor;) + } + } + else + { + and = devPriv->and; + PointLoop( addrpt = addrp + intToY(pt) * npwidth + intToX(pt); + *addrpt = DoRRop (*addrpt, and, xor);) + } +#else /* !PIXEL_ADDR */ + cfbGetLongWidthAndPointer(pDrawable, nlwidth, addrl); + addrl = addrl + pDrawable->y * nlwidth + (pDrawable->x >> PWSH); + xoffset = pDrawable->x & PIM; + and = devPriv->and; + PointLoop( addrlt = addrl + intToY(pt) * nlwidth + + ((intToX(pt) + xoffset) >> PWSH); + *addrlt = DoRRop (*addrlt, + and | ~cfbmask[(intToX(pt) + xoffset) & PIM], + xor & cfbmask[(intToX(pt) + xoffset) & PIM]); + ) +#endif /* PIXEL_ADDR */ +} diff --git a/cfb/cfbpush8.c b/cfb/cfbpush8.c new file mode 100644 index 000000000..850de518d --- /dev/null +++ b/cfb/cfbpush8.c @@ -0,0 +1,184 @@ +/* + * Push Pixels for 8 bit displays. + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ +/* $Xorg: cfbpush8.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ + +#if PSZ == 8 + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" +#define MFB_CONSTS_ONLY +#include "maskbits.h" + +void +cfbPushPixels8 (pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg) + GCPtr pGC; + PixmapPtr pBitmap; + DrawablePtr pDrawable; + int dx, dy, xOrg, yOrg; +{ + register unsigned long *src, *dst; + register unsigned long pixel; + register unsigned long c, bits; + unsigned long *pdstLine, *psrcLine; + unsigned long *pdstBase; + int srcWidth; + int dstWidth; + int xoff; + int nBitmapLongs, nPixmapLongs; + int nBitmapTmp, nPixmapTmp; + unsigned long rightMask; + BoxRec bbox; + cfbPrivGCPtr devPriv; + + bbox.x1 = xOrg; + bbox.y1 = yOrg; + bbox.x2 = bbox.x1 + dx; + bbox.y2 = bbox.y1 + dy; + devPriv = cfbGetGCPrivate(pGC); + + switch (RECT_IN_REGION(pGC->pScreen, devPriv->pCompositeClip, &bbox)) + { + case rgnPART: +#ifndef LOWMEMFTPT + mfbPushPixels(pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg); +#else + miPushPixels(pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg); +#endif /* ifndef LOWMEMFTPT */ + case rgnOUT: + return; + } + + cfbGetLongWidthAndPointer (pDrawable, dstWidth, pdstBase) + + psrcLine = (unsigned long *) pBitmap->devPrivate.ptr; + srcWidth = (int) pBitmap->devKind >> PWSH; + + pixel = devPriv->xor; + xoff = xOrg & PIM; + nBitmapLongs = (dx + xoff) >> MFB_PWSH; + nPixmapLongs = (dx + PGSZB + xoff) >> PWSH; + + rightMask = ~cfb8BitLenMasks[((dx + xoff) & MFB_PIM)]; + + pdstLine = pdstBase + (yOrg * dstWidth) + (xOrg >> PWSH); + + while (dy--) + { + c = 0; + nPixmapTmp = nPixmapLongs; + nBitmapTmp = nBitmapLongs; + src = psrcLine; + dst = pdstLine; + while (nBitmapTmp--) + { + bits = *src++; + c |= BitRight (bits, xoff); + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + nPixmapTmp -= 8; + c = 0; + if (xoff) + c = BitLeft (bits, PGSZ - xoff); + } + if (BitLeft (rightMask, xoff)) + c |= BitRight (*src, xoff); + c &= rightMask; + switch (nPixmapTmp) { + case 8: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 7: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 6: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 5: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 4: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 3: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 2: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 1: + WriteBitGroup(dst, pixel, GetBitGroup(c)); + NextBitGroup(c); + dst++; + case 0: + break; + } + pdstLine += dstWidth; + psrcLine += srcWidth; + } +} + +#endif diff --git a/cfb/cfbrctstp8.c b/cfb/cfbrctstp8.c new file mode 100644 index 000000000..9b9db7462 --- /dev/null +++ b/cfb/cfbrctstp8.c @@ -0,0 +1,588 @@ +/* + * Fill 32 bit stippled rectangles for 8 bit frame buffers + */ +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Keith Packard, MIT X Consortium + +*/ + +/* $Xorg: cfbrctstp8.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ + +#if PSZ == 8 + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +#define MFB_CONSTS_ONLY +#include "maskbits.h" + +void +cfb8FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; /* number of boxes to fill */ + register BoxPtr pBox; /* pointer to list of boxes to fill */ +{ + unsigned long *src; + int stippleHeight; + + int nlwDst; /* width in longwords of the dest pixmap */ + int w; /* width of current box */ + register int h; /* height of current box */ + unsigned long startmask; + unsigned long endmask; /* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + register int nlw; /* loop version of nlwMiddle */ + unsigned long *dstLine; + register unsigned long *dst; /* pointer to bits we're writing */ + unsigned long *dstTmp; + int y; /* current scan line */ + + unsigned long *pbits;/* pointer to start of pixmap */ + register unsigned long bits; /* bits from stipple */ + int rot, lastStop, i; + register unsigned long xor, and; + cfbPrivGCPtr devPriv; + PixmapPtr stipple; + int wEnd; + + devPriv = cfbGetGCPrivate(pGC); + stipple = devPriv->pRotatedPixmap; + + cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); + + stippleHeight = stipple->drawable.height; + src = (unsigned long *)stipple->devPrivate.ptr; + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + + while (nBox--) + { + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + y = pBox->y1; + dstLine = pbits + (pBox->y1 * nlwDst) + ((pBox->x1 & ~PIM) >> PWSH); + if (((pBox->x1 & PIM) + w) <= PPW) + { + maskpartialbits(pBox->x1, w, startmask); + nlwMiddle = 0; + endmask = 0; + } + else + { + maskbits (pBox->x1, w, startmask, endmask, nlwMiddle); + } + rot = (pBox->x1 & ((PGSZ-1) & ~PIM)); + pBox++; + y = y % stippleHeight; + if (cfb8StippleRRop == GXcopy) + { + if (w < PGSZ*2) + { + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot) + RotBitsLeft(bits,rot); + dst = dstLine; + dstLine += nlwDst; + if (startmask) + { + *dst = *dst & ~startmask | + GetPixelGroup (bits) & startmask; + dst++; + RotBitsLeft (bits, PGSZB); + } + nlw = nlwMiddle; + while (nlw--) + { + *dst++ = GetPixelGroup(bits); + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + *dst = *dst & ~endmask | + GetPixelGroup (bits) & endmask; + } + } + } + else + { + wEnd = 7 - (nlwMiddle & 7); + nlwMiddle = (nlwMiddle >> 3) + 1; + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot != 0) + RotBitsLeft (bits, rot); + dstTmp = dstLine; + dstLine += nlwDst; + if (startmask) + { + *dstTmp = *dstTmp & ~startmask | + GetPixelGroup (bits) & startmask; + dstTmp++; + RotBitsLeft (bits, PGSZB); + } + w = 7 - wEnd; + while (w--) + { + nlw = nlwMiddle; + dst = dstTmp; + dstTmp++; + xor = GetPixelGroup (bits); + while (nlw--) + { + *dst = xor; + dst += 8; + } + NextBitGroup (bits); + } + nlwMiddle--; + w = wEnd + 1; + if (endmask) + { + dst = dstTmp + (nlwMiddle << 3); + *dst = (*dst & ~endmask) | + GetPixelGroup (bits) & endmask; + } + while (w--) + { + nlw = nlwMiddle; + dst = dstTmp; + dstTmp++; + xor = GetPixelGroup (bits); + while (nlw--) + { + *dst = xor; + dst += 8; + } + NextBitGroup (bits); + } + nlwMiddle++; + } + } + } + else + { + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot) + RotBitsLeft(bits,rot); + dst = dstLine; + dstLine += nlwDst; + if (startmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, startmask); + dst++; + RotBitsLeft (bits, PGSZB); + } + nlw = nlwMiddle; + while (nlw--) + { + RRopBitGroup(dst, GetBitGroup(bits)); + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, endmask); + } + } + } + } +} + +void +cfb8FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; /* number of boxes to fill */ + BoxPtr pBox; /* pointer to list of boxes to fill */ +{ + int x, y, w, h; + int nlwMiddle, nlwDst, nlwTmp; + unsigned long startmask, endmask; + register unsigned long *dst; + unsigned long *dstLine, *pbits, *dstTmp; + unsigned long *src; + register unsigned long xor; + register unsigned long bits, mask; + int rot; + int wEnd; + cfbPrivGCPtr devPriv; + PixmapPtr stipple; + int stippleHeight; + register int nlw; + + devPriv = cfbGetGCPrivate(pGC); + stipple = devPriv->pRotatedPixmap; + src = (unsigned long *)stipple->devPrivate.ptr; + stippleHeight = stipple->drawable.height; + + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + + while (nBox--) + { + x = pBox->x1; + w = pBox->x2 - x; + if (((x & PIM) + w) <= PPW) + { + maskpartialbits(x, w, startmask); + endmask = 0; + nlwMiddle = 0; + } + else + { + maskbits (x, w, startmask, endmask, nlwMiddle); + } + rot = (x & ((PGSZ-1) & ~PIM)); + y = pBox->y1; + dstLine = pbits + (y * nlwDst) + (x >> PWSH); + h = pBox->y2 - y; + pBox++; + y %= stippleHeight; + if (cfb8StippleRRop == GXcopy) + { + xor = devPriv->xor; + if (w < PGSZ*2) + { + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot != 0) + RotBitsLeft (bits, rot); + dst = dstLine; + dstLine += nlwDst; + if (startmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dst = (*dst & ~(mask & startmask)) | + (xor & (mask & startmask)); + dst++; + RotBitsLeft (bits, PGSZB); + } + nlw = nlwMiddle; + while (nlw--) + { + WriteBitGroup (dst,xor,GetBitGroup(bits)) + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dst = (*dst & ~(mask & endmask)) | + (xor & (mask & endmask)); + } + } + } + else + { + wEnd = 7 - (nlwMiddle & 7); + nlwMiddle = (nlwMiddle >> 3) + 1; + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot != 0) + RotBitsLeft (bits, rot); + dstTmp = dstLine; + dstLine += nlwDst; + if (startmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + *dstTmp = (*dstTmp & ~(mask & startmask)) | + (xor & (mask & startmask)); + dstTmp++; + RotBitsLeft (bits, PGSZB); + } + w = 7 - wEnd; + while (w--) + { + nlw = nlwMiddle; + dst = dstTmp; + dstTmp++; +#if defined(__GNUC__) && defined(mc68020) + mask = cfb8PixelMasks[GetBitGroup(bits)]; + xor = xor & mask; + mask = ~mask; + while (nlw--) + { + *dst = (*dst & mask) | xor; + dst += 8; + } + xor = devPriv->xor; +#else +#define SwitchBitsLoop(body) \ + while (nlw--) \ + { \ + body \ + dst += 8; \ + } + SwitchBitGroup(dst, xor, GetBitGroup(bits)); +#undef SwitchBitsLoop +#endif + NextBitGroup (bits); + } + nlwMiddle--; + w = wEnd + 1; + if (endmask) + { + mask = cfb8PixelMasks[GetBitGroup(bits)]; + dst = dstTmp + (nlwMiddle << 3); + *dst = (*dst & ~(mask & endmask)) | + (xor & (mask & endmask)); + } + while (w--) + { + nlw = nlwMiddle; + dst = dstTmp; + dstTmp++; +#if defined(__GNUC__) && defined(mc68020) + mask = cfb8PixelMasks[GetBitGroup(bits)]; + xor = xor & mask; + mask = ~mask; + while (nlw--) + { + *dst = (*dst & mask) | xor; + dst += 8; + } + xor = devPriv->xor; +#else +#define SwitchBitsLoop(body) \ + while (nlw--) \ + { \ + body \ + dst += 8; \ + } + SwitchBitGroup(dst, xor, GetBitGroup(bits)); +#undef SwitchBitsLoop +#endif + NextBitGroup (bits); + } + nlwMiddle++; + } + } + } + else + { + while (h--) + { + bits = src[y]; + y++; + if (y == stippleHeight) + y = 0; + if (rot != 0) + RotBitsLeft (bits, rot); + dst = dstLine; + dstLine += nlwDst; + if (startmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, startmask); + dst++; + RotBitsLeft (bits, PGSZB); + } + nlw = nlwMiddle; + while (nlw--) + { + RRopBitGroup(dst, GetBitGroup(bits)); + dst++; + RotBitsLeft (bits, PGSZB); + } + if (endmask) + { + xor = GetBitGroup(bits); + *dst = MaskRRopPixels(*dst, xor, endmask); + } + } + } + } +} + + +void +cfb8FillRectStippledUnnatural (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; + register BoxPtr pBox; +{ + unsigned long *pdstBase; /* pointer to start of bitmap */ + unsigned long *pdstLine; /* current destination line */ + int nlwDst; /* width in longwords of bitmap */ + PixmapPtr pStipple; /* pointer to stipple we want to fill with */ + int nlwMiddle; + register int nlw; + int x, y, w, h, xrem, xSrc, ySrc; + int stwidth, stippleWidth; + int stippleHeight; + register unsigned long bits, inputBits; + register int partBitsLeft; + int nextPartBits; + int bitsLeft, bitsWhole; + register unsigned long *pdst; /* pointer to current word in bitmap */ + unsigned long *srcTemp, *srcStart; + unsigned long *psrcBase; + unsigned long startmask, endmask; + + if (pGC->fillStyle == FillStippled) + cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask); + else + cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); + + if (cfb8StippleRRop == GXnoop) + return; + + /* + * OK, so what's going on here? We have two Drawables: + * + * The Stipple: + * Depth = 1 + * Width = stippleWidth + * Words per scanline = stwidth + * Pointer to pixels = pStipple->devPrivate.ptr + */ + + pStipple = pGC->stipple; + + stwidth = pStipple->devKind >> PWSH; + stippleWidth = pStipple->drawable.width; + stippleHeight = pStipple->drawable.height; + psrcBase = (unsigned long *) pStipple->devPrivate.ptr; + + /* + * The Target: + * Depth = PSZ + * Width = determined from *pwidth + * Words per scanline = nlwDst + * Pointer to pixels = addrlBase + */ + + xSrc = pDrawable->x; + ySrc = pDrawable->y; + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase) + + /* 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 % stippleWidth) - stippleWidth; + ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight; + + bitsWhole = stippleWidth; + + while (nBox--) + { + x = pBox->x1; + y = pBox->y1; + w = pBox->x2 - x; + h = pBox->y2 - y; + pBox++; + pdstLine = pdstBase + y * nlwDst + (x >> PWSH); + y = (y - ySrc) % stippleHeight; + srcStart = psrcBase + y * stwidth; + xrem = ((x & ~PIM) - xSrc) % stippleWidth; + if (((x & PIM) + w) < PPW) + { + maskpartialbits (x, w, startmask); + nlwMiddle = 0; + endmask = 0; + } + else + { + maskbits (x, w, startmask, endmask, nlwMiddle); + } + while (h--) + { + srcTemp = srcStart + (xrem >> MFB_PWSH); + bitsLeft = stippleWidth - (xrem & ~MFB_PIM); + NextUnnaturalStippleWord + NextSomeBits (inputBits, (xrem & MFB_PIM)); + partBitsLeft -= (xrem & MFB_PIM); + NextUnnaturalStippleBits + nlw = nlwMiddle; + pdst = pdstLine; + if (startmask) + { + *pdst = MaskRRopPixels(*pdst,bits,startmask); + pdst++; + NextUnnaturalStippleBits + } + while (nlw--) + { + *pdst = RRopPixels(*pdst,bits); + pdst++; + NextUnnaturalStippleBits + } + if (endmask) + *pdst = MaskRRopPixels(*pdst,bits,endmask); + pdstLine += nlwDst; + y++; + srcStart += stwidth; + if (y == stippleHeight) + { + y = 0; + srcStart = psrcBase; + } + } + } +} + +#endif /* PSZ == 8 */ diff --git a/cfb/cfbrrop.c b/cfb/cfbrrop.c new file mode 100644 index 000000000..69ec0278d --- /dev/null +++ b/cfb/cfbrrop.c @@ -0,0 +1,221 @@ +/* + * $Xorg: cfbrrop.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* cfb reduced rasterop computations */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "cfbmskbits.h" + +/* A description: + * + * There are four possible operations on each bit in the destination word, + * + * 1 2 3 4 + * + * 0 0 0 1 1 + * 1 0 1 0 1 + * + * On examination of the reduced rop equation (dst = (dst & and) ^ xor), + * these four fall to reduced rops as follows: + * + * and 0 1 1 0 + * xor 0 0 1 1 + * + * or, (if 'and' is expensive) (dst = (dst | or) ^ xor) + * + * or 1 0 0 1 + * xor 1 0 1 0 + * + * The trouble with using this later equation is that trivial + * rasterop reduction is more difficult; some common rasterops + * use complicated expressions of xor/and instead of the simple + * ones while other common rasterops are not made any simpler: + * + * GXcopy: *dst = ~xor instead of *dst = xor + * GXand: *dst = *dst & ~or instead of *dst = *dst & and + * GXor: *dst = *dst | or instead of *dst = *dst | xor + * GXxor: *dst = *dst ^ xor instead of *dst = *dst ^ xor + * + * If you're really set on using this second mechanism, the changes + * are pretty simple. + * + * All that remains is to provide a mechanism for computing and/xor values + * based on the raster op and foreground value. + * + * The 16 rops fall as follows, with the associated reduced + * rop and/xor and or/xor values. The values in parenthesis following the + * reduced values gives an equation using the source value for + * the reduced value, and is one of {0, src, ~src, 1} as appropriate. + * + * clear and andReverse copy + * src 0 1 0 1 0 1 0 1 + * dst 0 0 0 0 0 0 0 0 1 0 0 1 + * 1 0 0 1 0 1 1 0 0 1 0 1 + * + * and 0 0 (0) 0 1 (src) 0 1 (src) 0 0 (0) + * xor 0 0 (0) 0 0 (0) 0 1 (src) 0 1 (src) + * + * or 1 1 (1) 1 0 (~src) 1 0 (~src) 1 1 (1) + * xor 1 1 (1) 1 0 (~src) 1 1 (1) 1 0 (~src) + * + * andInverted noop xor or + * src 0 1 0 1 0 1 0 1 + * dst 0 0 0 0 0 0 0 0 1 0 0 1 + * 1 1 0 1 1 1 1 1 0 1 1 1 + * + * and 1 0 (~src) 1 1 (1) 1 1 (1) 1 0 (~src) + * xor 0 0 (0) 0 0 (0) 0 1 (src) 0 1 (src) + * + * or 0 1 (src) 0 0 (0) 0 0 (0) 0 1 (src) + * xor 0 1 (src) 0 0 (0) 0 1 (src) 0 0 (0) + * + * nor equiv invert orReverse + * src 0 1 0 1 0 1 0 1 + * dst 0 1 0 0 1 0 0 1 1 0 1 1 + * 1 0 0 1 0 1 1 0 0 1 0 1 + * + * and 1 0 (~src) 1 1 (1) 1 1 (1) 1 0 (~src) + * xor 1 0 (~src) 1 0 (~src) 1 1 (1) 1 1 (1) + * + * or 0 1 (src) 0 0 (0) 0 0 (0) 0 1 (src) + * xor 1 1 (1) 1 0 (~src) 1 1 (1) 1 0 (~src) + * + * copyInverted orInverted nand set + * src 0 1 0 1 0 1 0 1 + * dst 0 1 0 0 1 0 0 1 1 0 1 1 + * 1 1 0 1 1 1 1 1 0 1 1 1 + * + * and 0 0 (0) 0 1 (src) 0 1 (src) 0 0 (0) + * xor 1 0 (~src) 1 0 (~src) 1 1 (1) 1 1 (1) + * + * or 1 1 (1) 1 0 (~src) 1 0 (~src) 1 1 (1) + * xor 0 1 (src) 0 0 (0) 0 1 (src) 0 0 (0) + */ + +int +cfbReduceRasterOp (rop, fg, pm, andp, xorp) + int rop; + unsigned long fg, pm; + unsigned long *andp, *xorp; +{ + unsigned long and, xor; + int rrop; + + fg = PFILL (fg); + pm = PFILL (pm); + switch (rop) + { + case GXclear: + and = 0; + xor = 0; + break; + case GXand: + and = fg; + xor = 0; + break; + case GXandReverse: + and = fg; + xor = fg; + break; + case GXcopy: + and = 0; + xor = fg; + break; + case GXandInverted: + and = ~fg; + xor = 0; + break; + case GXnoop: + and = ~0; + xor = 0; + break; + case GXxor: + and = ~0; + xor = fg; + break; + case GXor: + and = ~fg; + xor = fg; + break; + case GXnor: + and = ~fg; + xor = ~fg; + break; + case GXequiv: + and = ~0; + xor = ~fg; + break; + case GXinvert: + and = ~0; + xor = ~0; + break; + case GXorReverse: + and = ~fg; + xor = ~0; + break; + case GXcopyInverted: + and = 0; + xor = ~fg; + break; + case GXorInverted: + and = fg; + xor = ~fg; + break; + case GXnand: + and = fg; + xor = ~0; + break; + case GXset: + and = 0; + xor = ~0; + break; + } + and |= ~pm; + xor &= pm; + *andp = and; + *xorp = xor; + /* check for some special cases to reduce computation */ + if (and == 0) + rrop = GXcopy; + /* nothing checks for GXnoop + else if (and == ~0 && xor == 0) + rrop = GXnoop; + */ + else if (and == ~0) + rrop = GXxor; + else if (xor == 0) + rrop = GXand; + else if ( (and ^ xor) == ~0) /* fix XBUG 6541 */ + rrop = GXor; + else + rrop = GXset; /* rop not reduced */ + return rrop; +} diff --git a/cfb/cfbrrop.h b/cfb/cfbrrop.h new file mode 100644 index 000000000..4423e040d --- /dev/null +++ b/cfb/cfbrrop.h @@ -0,0 +1,150 @@ +/* + * $Xorg: cfbrrop.h,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef GXcopy +#include "X.h" +#endif + +#define RROP_FETCH_GC(gc) \ + RROP_FETCH_GCPRIV(((cfbPrivGCPtr)(gc)->devPrivates[cfbGCPrivateIndex].ptr)) + +#ifndef RROP +#define RROP GXset +#endif + +#if RROP == GXcopy +#define RROP_DECLARE register unsigned long rrop_xor; +#define RROP_FETCH_GCPRIV(devPriv) rrop_xor = (devPriv)->xor; +#define RROP_SOLID(dst) (*(dst) = (rrop_xor)) +#define RROP_SOLID_MASK(dst,mask) (*(dst) = (*(dst) & ~(mask)) | ((rrop_xor) & (mask))) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,Copy) +#endif /* GXcopy */ + +#if RROP == GXxor +#define RROP_DECLARE register unsigned long rrop_xor; +#define RROP_FETCH_GCPRIV(devPriv) rrop_xor = (devPriv)->xor; +#define RROP_SOLID(dst) (*(dst) ^= (rrop_xor)) +#define RROP_SOLID_MASK(dst,mask) (*(dst) ^= ((rrop_xor) & (mask))) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,Xor) +#endif /* GXxor */ + +#if RROP == GXand +#define RROP_DECLARE register unsigned long rrop_and; +#define RROP_FETCH_GCPRIV(devPriv) rrop_and = (devPriv)->and; +#define RROP_SOLID(dst) (*(dst) &= (rrop_and)) +#define RROP_SOLID_MASK(dst,mask) (*(dst) &= ((rrop_and) | ~(mask))) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,And) +#endif /* GXand */ + +#if RROP == GXor +#define RROP_DECLARE register unsigned long rrop_or; +#define RROP_FETCH_GCPRIV(devPriv) rrop_or = (devPriv)->xor; +#define RROP_SOLID(dst) (*(dst) |= (rrop_or)) +#define RROP_SOLID_MASK(dst,mask) (*(dst) |= ((rrop_or) & (mask))) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,Or) +#endif /* GXor */ + +#if RROP == GXnoop +#define RROP_DECLARE +#define RROP_FETCH_GCPRIV(devPriv) +#define RROP_SOLID(dst) +#define RROP_SOLID_MASK(dst,mask) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,Noop) +#endif /* GXnoop */ + +#if RROP == GXset +#define RROP_DECLARE register unsigned long rrop_and, rrop_xor; +#define RROP_FETCH_GCPRIV(devPriv) rrop_and = (devPriv)->and; \ + rrop_xor = (devPriv)->xor; +#define RROP_SOLID(dst) (*(dst) = DoRRop (*(dst), rrop_and, rrop_xor)) +#define RROP_SOLID_MASK(dst,mask) (*(dst) = DoMaskRRop (*(dst), rrop_and, rrop_xor, (mask))) +#define RROP_NAME(prefix) RROP_NAME_CAT(prefix,General) +#endif /* GXset */ + +#define RROP_UNROLL_CASE1(p,i) case (i): RROP_SOLID((p) - (i)); +#define RROP_UNROLL_CASE2(p,i) RROP_UNROLL_CASE1(p,(i)+1) RROP_UNROLL_CASE1(p,i) +#define RROP_UNROLL_CASE4(p,i) RROP_UNROLL_CASE2(p,(i)+2) RROP_UNROLL_CASE2(p,i) +#define RROP_UNROLL_CASE8(p,i) RROP_UNROLL_CASE4(p,(i)+4) RROP_UNROLL_CASE4(p,i) +#define RROP_UNROLL_CASE16(p,i) RROP_UNROLL_CASE8(p,(i)+8) RROP_UNROLL_CASE8(p,i) +#define RROP_UNROLL_CASE3(p) RROP_UNROLL_CASE2(p,2) RROP_UNROLL_CASE1(p,1) +#define RROP_UNROLL_CASE7(p) RROP_UNROLL_CASE4(p,4) RROP_UNROLL_CASE3(p) +#define RROP_UNROLL_CASE15(p) RROP_UNROLL_CASE8(p,8) RROP_UNROLL_CASE7(p) +#define RROP_UNROLL_CASE31(p) RROP_UNROLL_CASE16(p,16) RROP_UNROLL_CASE15(p) +#ifdef LONG64 +#define RROP_UNROLL_CASE63(p) RROP_UNROLL_CASE32(p,32) RROP_UNROLL_CASE31(p) +#endif /* LONG64 */ + +#define RROP_UNROLL_LOOP1(p,i) RROP_SOLID((p) + (i)); +#define RROP_UNROLL_LOOP2(p,i) RROP_UNROLL_LOOP1(p,(i)) RROP_UNROLL_LOOP1(p,(i)+1) +#define RROP_UNROLL_LOOP4(p,i) RROP_UNROLL_LOOP2(p,(i)) RROP_UNROLL_LOOP2(p,(i)+2) +#define RROP_UNROLL_LOOP8(p,i) RROP_UNROLL_LOOP4(p,(i)) RROP_UNROLL_LOOP4(p,(i)+4) +#define RROP_UNROLL_LOOP16(p,i) RROP_UNROLL_LOOP8(p,(i)) RROP_UNROLL_LOOP8(p,(i)+8) +#define RROP_UNROLL_LOOP32(p,i) RROP_UNROLL_LOOP16(p,(i)) RROP_UNROLL_LOOP16(p,(i)+16) +#ifdef LONG64 +#define RROP_UNROLL_LOOP64(p,i) RROP_UNROLL_LOOP32(p,(i)) RROP_UNROLL_LOOP32(p,(i)+32) +#endif /* LONG64 */ + +#if defined (FAST_CONSTANT_OFFSET_MODE) && defined (SHARED_IDCACHE) && (RROP == GXcopy) + +#ifdef LONG64 +#define RROP_UNROLL_SHIFT 6 +#define RROP_UNROLL_CASE(p) RROP_UNROLL_CASE63(p) +#define RROP_UNROLL_LOOP(p) RROP_UNROLL_LOOP64(p,-64) +#else /* not LONG64 */ +#define RROP_UNROLL_SHIFT 5 +#define RROP_UNROLL_CASE(p) RROP_UNROLL_CASE31(p) +#define RROP_UNROLL_LOOP(p) RROP_UNROLL_LOOP32(p,-32) +#endif /* LONG64 */ +#define RROP_UNROLL (1<<RROP_UNROLL_SHIFT) +#define RROP_UNROLL_MASK (RROP_UNROLL-1) + +#define RROP_SPAN(pdst,nmiddle) {\ + int part = (nmiddle) & RROP_UNROLL_MASK; \ + (nmiddle) >>= RROP_UNROLL_SHIFT; \ + (pdst) += part * (sizeof (unsigned long) / sizeof (*pdst)); \ + switch (part) {\ + RROP_UNROLL_CASE((unsigned long *) (pdst)) \ + } \ + while (--(nmiddle) >= 0) { \ + (pdst) += RROP_UNROLL * (sizeof (unsigned long) / sizeof (*pdst)); \ + RROP_UNROLL_LOOP((unsigned long *) (pdst)) \ + } \ +} +#else +#define RROP_SPAN(pdst,nmiddle) \ + while (--(nmiddle) >= 0) { \ + RROP_SOLID((unsigned long *) (pdst)); \ + (pdst) += sizeof (unsigned long) / sizeof (*pdst); \ + } +#endif + +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define RROP_NAME_CAT(prefix,suffix) prefix##suffix +#else +#define RROP_NAME_CAT(prefix,suffix) prefix/**/suffix +#endif diff --git a/cfb/cfbscrinit.c b/cfb/cfbscrinit.c new file mode 100644 index 000000000..ad8bee4f5 --- /dev/null +++ b/cfb/cfbscrinit.c @@ -0,0 +1,195 @@ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + 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 no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or The Open Group +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and The Open Group make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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. + +********************************************************/ +/* $Xorg: cfbscrinit.c,v 1.3 2000/08/17 19:48:15 cpqbld Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "resource.h" +#include "colormap.h" +#include "colormapst.h" +#include "cfb.h" +#include "mi.h" +#include "mistruct.h" +#include "dix.h" +#include "cfbmskbits.h" +#include "mibstore.h" + + +miBSFuncRec cfbBSFuncRec = { + cfbSaveAreas, + cfbRestoreAreas, + (void (*)()) 0, + (PixmapPtr (*)()) 0, + (PixmapPtr (*)()) 0, +}; + +Bool +cfbCloseScreen (index, pScreen) + int index; + ScreenPtr pScreen; +{ + int d; + DepthPtr depths = pScreen->allowedDepths; + + for (d = 0; d < pScreen->numDepths; d++) + xfree (depths[d].vids); + xfree (depths); + xfree (pScreen->visuals); +#ifdef CFB_NEED_SCREEN_PRIVATE + xfree (pScreen->devPrivates[cfbScreenPrivateIndex].ptr); +#else + xfree (pScreen->devPrivate); +#endif + return TRUE; +} + +Bool +cfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width) + register ScreenPtr pScreen; + pointer pbits; /* pointer to screen bitmap */ + int xsize, ysize; /* in pixels */ + int dpix, dpiy; /* dots per inch */ + int width; /* pixel width of frame buffer */ +{ + int i; + extern RegionPtr (*cfbPuntCopyPlane)(); + + if (!cfbAllocatePrivates(pScreen, (int *) 0, (int *) 0)) + return FALSE; + pScreen->defColormap = FakeClientID(0); + /* let CreateDefColormap do whatever it wants for pixels */ + pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0; + pScreen->QueryBestSize = mfbQueryBestSize; + /* SaveScreen */ + pScreen->GetImage = cfbGetImage; + pScreen->GetSpans = cfbGetSpans; + pScreen->CreateWindow = cfbCreateWindow; + pScreen->DestroyWindow = cfbDestroyWindow; + pScreen->PositionWindow = cfbPositionWindow; + pScreen->ChangeWindowAttributes = cfbChangeWindowAttributes; + pScreen->RealizeWindow = cfbMapWindow; + pScreen->UnrealizeWindow = cfbUnmapWindow; + pScreen->PaintWindowBackground = cfbPaintWindow; + pScreen->PaintWindowBorder = cfbPaintWindow; + pScreen->CopyWindow = cfbCopyWindow; + pScreen->CreatePixmap = cfbCreatePixmap; + pScreen->DestroyPixmap = cfbDestroyPixmap; + pScreen->RealizeFont = mfbRealizeFont; + pScreen->UnrealizeFont = mfbUnrealizeFont; + pScreen->CreateGC = cfbCreateGC; + pScreen->CreateColormap = cfbInitializeColormap; + pScreen->DestroyColormap = (void (*)())NoopDDA; +#ifdef STATIC_COLOR + pScreen->InstallColormap = cfbInstallColormap; + pScreen->UninstallColormap = cfbUninstallColormap; + pScreen->ListInstalledColormaps = cfbListInstalledColormaps; + pScreen->StoreColors = (void (*)())NoopDDA; +#endif + pScreen->ResolveColor = cfbResolveColor; + pScreen->BitmapToRegion = mfbPixmapToRegion; + + mfbRegisterCopyPlaneProc (pScreen, cfbCopyPlane); + return TRUE; +} + +#ifdef CFB_NEED_SCREEN_PRIVATE +Bool +cfbCreateScreenResources(pScreen) + ScreenPtr pScreen; +{ + Bool retval; + + pointer oldDevPrivate = pScreen->devPrivate; + pScreen->devPrivate = pScreen->devPrivates[cfbScreenPrivateIndex].ptr; + retval = miCreateScreenResources(pScreen); + pScreen->devPrivates[cfbScreenPrivateIndex].ptr = pScreen->devPrivate; + pScreen->devPrivate = oldDevPrivate; + return retval; +} +#endif + +cfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width) + register ScreenPtr pScreen; + pointer pbits; /* pointer to screen bitmap */ + int xsize, ysize; /* in pixels */ + int dpix, dpiy; /* dots per inch */ + int width; /* pixel width of frame buffer */ +{ + int i, j; +#ifdef CFB_NEED_SCREEN_PRIVATE + pointer oldDevPrivate; +#endif + VisualPtr visuals; + DepthPtr depths; + int nvisuals; + int ndepths; + int rootdepth; + VisualID defaultVisual; + + rootdepth = 0; + if (!cfbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth, + &defaultVisual,((unsigned long)1<<(PSZ-1)), 8)) + return FALSE; +#ifdef CFB_NEED_SCREEN_PRIVATE + oldDevPrivate = pScreen->devPrivate; +#endif + if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, + rootdepth, ndepths, depths, + defaultVisual, nvisuals, visuals, + (miBSFuncPtr) 0)) + return FALSE; + /* overwrite miCloseScreen with our own */ + pScreen->CloseScreen = cfbCloseScreen; + /* init backing store here so we can overwrite CloseScreen without stepping + * on the backing store wrapped version */ + miInitializeBackingStore (pScreen, &cfbBSFuncRec); +#ifdef CFB_NEED_SCREEN_PRIVATE + pScreen->CreateScreenResources = cfbCreateScreenResources; + pScreen->devPrivates[cfbScreenPrivateIndex].ptr = pScreen->devPrivate; + pScreen->devPrivate = oldDevPrivate; +#endif + return TRUE; +} + +/* dts * (inch/dot) * (25.4 mm / inch) = mm */ +Bool +cfbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width) + register ScreenPtr pScreen; + pointer pbits; /* pointer to screen bitmap */ + int xsize, ysize; /* in pixels */ + int dpix, dpiy; /* dots per inch */ + int width; /* pixel width of frame buffer */ +{ + if (!cfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width)) + return FALSE; + return cfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width); +} diff --git a/cfb/cfbsetsp.c b/cfb/cfbsetsp.c new file mode 100644 index 000000000..4a3d2fbfe --- /dev/null +++ b/cfb/cfbsetsp.c @@ -0,0 +1,280 @@ +/* $Xorg: cfbsetsp.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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 "Xmd.h" +#include "servermd.h" + +#include "misc.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include <mergerop.h> + +/* cfbSetScanline -- copies the bits from psrc to the drawable starting at + * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc + * starts on the scanline. (I.e., if this scanline passes through multiple + * boxes, we may not want to start grabbing bits at psrc but at some offset + * further on.) + */ +cfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, planemask) + int y; + int xOrigin; /* where this scanline starts */ + int xStart; /* first bit to use from scanline */ + int xEnd; /* last bit to use from scanline + 1 */ + register unsigned int *psrc; + register int alu; /* raster op */ + int *pdstBase; /* start of the drawable */ + int widthDst; /* width of drawable in words */ + unsigned long planemask; +{ + int w; /* width of scanline in bits */ + register int *pdst; /* where to put the bits */ + register int tmpSrc; /* scratch buffer to collect bits in */ + int dstBit; /* offset in bits from beginning of + * word */ + register int nstart; /* number of bits from first partial */ + register int nend; /* " " last partial word */ + int offSrc; + int startmask, endmask, nlMiddle, nl; + DeclareMergeRop() + + InitializeMergeRop(alu,planemask); + pdst = pdstBase + (y * widthDst) + (xStart >> PWSH); + psrc += (xStart - xOrigin) >> PWSH; + offSrc = (xStart - xOrigin) & PIM; + w = xEnd - xStart; + dstBit = xStart & PIM; + + if (dstBit + w <= PPW) + { + maskpartialbits(dstBit, w, startmask); + endmask = 0; + nlMiddle = 0; + } + else + { + maskbits(xStart, w, startmask, endmask, nlMiddle); + } + if (startmask) + nstart = PPW - dstBit; + else + nstart = 0; + if (endmask) + nend = xEnd & PIM; + else + nend = 0; + if (startmask) + { + getbits(psrc, offSrc, nstart, tmpSrc); + putbitsmropshort(tmpSrc, dstBit, nstart, pdst); + pdst++; + offSrc += nstart; + if (offSrc > PLST) + { + psrc++; + offSrc -= PPW; + } + } + nl = nlMiddle; + while (nl--) + { + getbits(psrc, offSrc, PPW, tmpSrc); + *pdst = DoMergeRop(tmpSrc, *pdst); + pdst++; + psrc++; + } + if (endmask) + { + getbits(psrc, offSrc, nend, tmpSrc); + putbitsmropshort(tmpSrc, 0, nend, pdst); + } +} + + + +/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at + * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines + * are in increasing Y order. + * Source bit lines are server scanline padded so that they always begin + * on a word boundary. + */ +void +cfbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + char *pcharsrc; + register DDXPointPtr ppt; + int *pwidth; + int nspans; + int fSorted; +{ + unsigned int *psrc = (unsigned int *)pcharsrc; + unsigned long *pdstBase; /* start of dst bitmap */ + int widthDst; /* width of bitmap in words */ + register BoxPtr pbox, pboxLast, pboxTest; + register DDXPointPtr pptLast; + int alu; + RegionPtr prgnDst; + int xStart, xEnd; + int yMax; + + alu = pGC->alu; + prgnDst = cfbGetCompositeClip(pGC); + pptLast = ppt + nspans; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + yMax = (int) pDrawable->y + (int) pDrawable->height; + + pbox = REGION_RECTS(prgnDst); + pboxLast = pbox + REGION_NUM_RECTS(prgnDst); + + if(fSorted) + { + /* scan lines sorted in ascending order. Because they are sorted, we + * don't have to check each scanline against each clip box. We can be + * sure that this scanline only has to be clipped to boxes at or after the + * beginning of this y-band + */ + pboxTest = pbox; + while(ppt < pptLast) + { + pbox = pboxTest; + if(ppt->y >= yMax) + break; + while(pbox < pboxLast) + { + if(pbox->y1 > ppt->y) + { + /* scanline is before clip box */ + break; + } + else if(pbox->y2 <= ppt->y) + { + /* clip box is before scanline */ + pboxTest = ++pbox; + continue; + } + else if(pbox->x1 > ppt->x + *pwidth) + { + /* clip box is to right of scanline */ + break; + } + else if(pbox->x2 <= ppt->x) + { + /* scanline is to right of clip box */ + pbox++; + continue; + } + + /* at least some of the scanline is in the current clip box */ + xStart = max(pbox->x1, ppt->x); + xEnd = min(ppt->x + *pwidth, pbox->x2); + cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, + (int *)pdstBase, widthDst, pGC->planemask); + if(ppt->x + *pwidth <= pbox->x2) + { + /* End of the line, as it were */ + break; + } + else + pbox++; + } + /* We've tried this line against every box; it must be outside them + * all. move on to the next point */ + ppt++; + psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth); + pwidth++; + } + } + else + { + /* scan lines not sorted. We must clip each line against all the boxes */ + while(ppt < pptLast) + { + if(ppt->y >= 0 && ppt->y < yMax) + { + + for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++) + { + if(pbox->y1 > ppt->y) + { + /* rest of clip region is above this scanline, + * skip it */ + break; + } + if(pbox->y2 <= ppt->y) + { + /* clip box is below scanline */ + pbox++; + break; + } + if(pbox->x1 <= ppt->x + *pwidth && + pbox->x2 > ppt->x) + { + xStart = max(pbox->x1, ppt->x); + xEnd = min(pbox->x2, ppt->x + *pwidth); + cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, + (int *)pdstBase, widthDst, pGC->planemask); + } + + } + } + psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + } +} + diff --git a/cfb/cfbsolid.c b/cfb/cfbsolid.c new file mode 100644 index 000000000..ead63a757 --- /dev/null +++ b/cfb/cfbsolid.c @@ -0,0 +1,296 @@ +/* + * $Xorg: cfbsolid.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfbrrop.h" + +#include "mi.h" +#include "mispans.h" + +#if defined(FAST_CONSTANT_OFFSET_MODE) && (RROP != GXcopy) +# define Expand(left,right,leftAdjust) {\ + int part = nmiddle & 3; \ + int widthStep; \ + widthStep = widthDst - nmiddle - leftAdjust; \ + nmiddle >>= 2; \ + pdst = pdstRect; \ + while (h--) { \ + left \ + pdst += part; \ + switch (part) { \ + RROP_UNROLL_CASE3(pdst) \ + } \ + m = nmiddle; \ + while (m) { \ + pdst += 4; \ + RROP_UNROLL_LOOP4(pdst,-4) \ + m--; \ + } \ + right \ + pdst += widthStep; \ + } \ +} +#else +# ifdef RROP_UNROLL +# define Expand(left,right,leftAdjust) {\ + int part = nmiddle & RROP_UNROLL_MASK; \ + int widthStep; \ + widthStep = widthDst - nmiddle - leftAdjust; \ + nmiddle >>= RROP_UNROLL_SHIFT; \ + pdst = pdstRect; \ + while (h--) { \ + left \ + pdst += part; \ + switch (part) { \ + RROP_UNROLL_CASE(pdst) \ + } \ + m = nmiddle; \ + while (m) { \ + pdst += RROP_UNROLL; \ + RROP_UNROLL_LOOP(pdst) \ + m--; \ + } \ + right \ + pdst += widthStep; \ + } \ +} + +# else +# define Expand(left, right, leftAdjust) { \ + while (h--) { \ + pdst = pdstRect; \ + left \ + m = nmiddle; \ + while (m--) {\ + RROP_SOLID(pdst); \ + pdst++; \ + } \ + right \ + pdstRect += widthDst; \ + } \ +} +# endif +#endif + + +void +RROP_NAME(cfbFillRectSolid) (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; + BoxPtr pBox; +{ + register int m; + register unsigned long *pdst; + RROP_DECLARE + register unsigned long leftMask, rightMask; + unsigned long *pdstBase, *pdstRect; + int nmiddle; + int h; + int w; + int widthDst; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + RROP_FETCH_GC(pGC) + + for (; nBox; nBox--, pBox++) + { + pdstRect = pdstBase + pBox->y1 * widthDst; + h = pBox->y2 - pBox->y1; + w = pBox->x2 - pBox->x1; +#if PSZ == 8 + if (w == 1) + { + register char *pdstb = ((char *) pdstRect) + pBox->x1; + int incr = widthDst * PGSZB; + + while (h--) + { + RROP_SOLID (pdstb); + pdstb += incr; + } + } + else + { +#endif + pdstRect += (pBox->x1 >> PWSH); + if ((pBox->x1 & PIM) + w <= PPW) + { + maskpartialbits(pBox->x1, w, leftMask); + pdst = pdstRect; + while (h--) { + RROP_SOLID_MASK (pdst, leftMask); + pdst += widthDst; + } + } + else + { + maskbits (pBox->x1, w, leftMask, rightMask, nmiddle); + if (leftMask) + { + if (rightMask) /* left mask and right mask */ + { + Expand(RROP_SOLID_MASK (pdst, leftMask); pdst++;, + RROP_SOLID_MASK (pdst, rightMask);, 1) + } + else /* left mask and no right mask */ + { + Expand(RROP_SOLID_MASK (pdst, leftMask); pdst++;, + ;, 1) + } + } + else + { + if (rightMask) /* no left mask and right mask */ + { + Expand(;, + RROP_SOLID_MASK (pdst, rightMask);, 0) + } + else /* no left mask and no right mask */ + { + Expand(;, + ;, 0) + } + } + } +#if PSZ == 8 + } +#endif + } +} + +void +RROP_NAME(cfbSolidSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + unsigned long *pdstBase; + int widthDst; + + RROP_DECLARE + + register unsigned long *pdst; + register int nlmiddle; + register unsigned long startmask, endmask; + register int w; + int x; + + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + DDXPointPtr ppt; /* pointer to list of start points */ + int *pwidthFree;/* copies of the pointers to free */ + DDXPointPtr pptFree; + int *pwidth; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); + RROP_FETCH_GCPRIV(devPriv) + n = nInit * miFindMaxBand(devPriv->pCompositeClip); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans(devPriv->pCompositeClip, + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + while (n--) + { + x = ppt->x; + pdst = pdstBase + (ppt->y * widthDst); + ++ppt; + w = *pwidth++; + if (!w) + continue; +#if PSZ == 8 + if (w <= PGSZB) + { + register char *addrb; + + addrb = ((char *) pdst) + x; + while (w--) + { + RROP_SOLID (addrb); + addrb++; + } + } +#else + if ((x & PIM) + w <= PPW) + { + pdst += x >> PWSH; + maskpartialbits (x, w, startmask); + RROP_SOLID_MASK (pdst, startmask); + } +#endif + else + { + pdst += x >> PWSH; + maskbits (x, w, startmask, endmask, nlmiddle); + if (startmask) + { + RROP_SOLID_MASK (pdst, startmask); + ++pdst; + } + + RROP_SPAN(pdst,nlmiddle) + if (endmask) + { + RROP_SOLID_MASK (pdst, endmask); + } + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} diff --git a/cfb/cfbteblt8.c b/cfb/cfbteblt8.c new file mode 100644 index 000000000..7653e770b --- /dev/null +++ b/cfb/cfbteblt8.c @@ -0,0 +1,583 @@ +/* + * TEGblt - ImageText expanded glyph fonts only. For + * 8 bit displays, in Copy mode with no clipping. + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* $Xorg: cfbteblt8.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $ */ + +#if PSZ == 8 + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +/* + * this code supports up to 5 characters at a time. The performance + * differences between 4 and 5 is usually small (~7% on PMAX) and + * frequently negative (SPARC and Sun3), so this file is compiled + * only once for now. If you want to use the other options, you'll + * need to hack cfbgc.c as well. + */ + +#ifndef NGLYPHS +#define NGLYPHS 4 +#define DO_COMMON +#endif + +#ifdef DO_COMMON +#define CFBTEGBLT8 cfbTEGlyphBlt8 +#endif + +/* + * On little-endian machines (or where fonts are padded to 32-bit + * boundaries) we can use some magic to avoid the expense of getleftbits + */ + +#if ((BITMAP_BIT_ORDER == LSBFirst && NGLYPHS >= 4) || GLYPHPADBYTES == 4) + +#if GLYPHPADBYTES == 1 +typedef unsigned char *glyphPointer; +#define USE_LEFTBITS +#endif + +#if GLYPHPADBYTES == 2 +typedef unsigned short *glyphPointer; +#define USE_LEFTBITS +#endif + +#if GLYPHPADBYTES == 4 +typedef unsigned int *glyphPointer; +#endif + +#define GetBitsL c = BitLeft (*leftChar++, lshift) +#define NGetBits1S(r) c = BitRight(*char1++ r, xoff1) +#define NGetBits1L(r) GetBitsL | BitRight(*char1++ r, xoff1) +#define NGetBits1U(r) c = *char1++ r +#define NGetBits2S(r) NGetBits1S(| BitRight(*char2++ r, widthGlyph)) +#define NGetBits2L(r) NGetBits1L(| BitRight(*char2++ r, widthGlyph)) +#define NGetBits2U(r) NGetBits1U(| BitRight(*char2++ r, widthGlyph)) +#define NGetBits3S(r) NGetBits2S(| BitRight(*char3++ r, widthGlyph)) +#define NGetBits3L(r) NGetBits2L(| BitRight(*char3++ r, widthGlyph)) +#define NGetBits3U(r) NGetBits2U(| BitRight(*char3++ r, widthGlyph)) +#define NGetBits4S(r) NGetBits3S(| BitRight(*char4++ r, widthGlyph)) +#define NGetBits4L(r) NGetBits3L(| BitRight(*char4++ r, widthGlyph)) +#define NGetBits4U(r) NGetBits3U(| BitRight(*char4++ r, widthGlyph)) +#define NGetBits5S(r) NGetBits4S(| BitRight(*char5++ r, widthGlyph)) +#define NGetBits5L(r) NGetBits4L(| BitRight(*char5++ r, widthGlyph)) +#define NGetBits5U(r) NGetBits4U(| BitRight(*char5++ r, widthGlyph)) +#define GetBits1S c = BitRight(*char1++, xoff1) +#define GetBits1L GetBitsL | BitRight(*char1++, xoff1) +#define GetBits1U c = *char1++ +#define GetBits2S NGetBits1S(| BitRight(*char2++, widthGlyph)) +#define GetBits2L NGetBits1L(| BitRight(*char2++, widthGlyph)) +#define GetBits2U NGetBits1U(| BitRight(*char2++, widthGlyph)) +#define GetBits3S NGetBits2S(| BitRight(*char3++, widthGlyph)) +#define GetBits3L NGetBits2L(| BitRight(*char3++, widthGlyph)) +#define GetBits3U NGetBits2U(| BitRight(*char3++, widthGlyph)) +#define GetBits4S NGetBits3S(| BitRight(*char4++, widthGlyph)) +#define GetBits4L NGetBits3L(| BitRight(*char4++, widthGlyph)) +#define GetBits4U NGetBits3U(| BitRight(*char4++, widthGlyph)) +#define GetBits5S NGetBits4S(| BitRight(*char5++, widthGlyph)) +#define GetBits5L NGetBits4L(| BitRight(*char5++, widthGlyph)) +#define GetBits5U NGetBits4U(| BitRight(*char5++, widthGlyph)) + +#else + +typedef unsigned int *glyphPointer; + +#define USE_LEFTBITS +#define ALL_LEFTBITS + +#define GetBitsL WGetBitsL +#define GetBits1S WGetBits1S +#define GetBits1L WGetBits1L +#define GetBits1U WGetBits1U + +#define GetBits2S GetBits1S Get1Bits (char2, tmpSrc) \ + c |= BitRight(tmpSrc, xoff2); +#define GetBits2L GetBits1L Get1Bits (char2, tmpSrc) \ + c |= BitRight(tmpSrc, xoff2); +#define GetBits2U GetBits1U Get1Bits (char2, tmpSrc) \ + c |= BitRight(tmpSrc, xoff2); + +#define GetBits3S GetBits2S Get1Bits (char3, tmpSrc) \ + c |= BitRight(tmpSrc, xoff3); +#define GetBits3L GetBits2L Get1Bits (char3, tmpSrc) \ + c |= BitRight(tmpSrc, xoff3); +#define GetBits3U GetBits2U Get1Bits (char3, tmpSrc) \ + c |= BitRight(tmpSrc, xoff3); + +#define GetBits4S GetBits3S Get1Bits (char4, tmpSrc) \ + c |= BitRight(tmpSrc, xoff4); +#define GetBits4L GetBits3L Get1Bits (char4, tmpSrc) \ + c |= BitRight(tmpSrc, xoff4); +#define GetBits4U GetBits3U Get1Bits (char4, tmpSrc) \ + c |= BitRight(tmpSrc, xoff4); + +#define GetBits5S GetBits4S Get1Bits (char5, tmpSrc) \ + c |= BitRight(tmpSrc, xoff5); +#define GetBits5L GetBits4L Get1Bits (char5, tmpSrc) \ + c |= BitRight(tmpSrc, xoff5); +#define GetBits5U GetBits4U Get1Bits (char5, tmpSrc) \ + c |= BitRight(tmpSrc, xoff5); + +#endif + +#ifdef USE_LEFTBITS +extern unsigned long endtab[]; + +#define IncChar(c) (c = (glyphPointer) (((char *) c) + glyphBytes)) + +#define Get1Bits(ch,dst) glyphbits (ch, widthGlyph, glyphMask, dst); \ + IncChar (ch); + +#define glyphbits(bits,width,mask,dst) getleftbits(bits,width,dst); \ + dst &= mask; + +#define WGetBitsL Get1Bits(leftChar,c); \ + c = BitLeft (c, lshift); +#define WGetBits1S Get1Bits (char1, c) \ + c = BitRight (c, xoff1); +#define WGetBits1L WGetBitsL Get1Bits (char1, tmpSrc) \ + c |= BitRight (tmpSrc, xoff1); +#define WGetBits1U Get1Bits (char1, c) + +#else +#define WGetBitsL GetBitsL +#define WGetBits1S GetBits1S +#define WGetBits1L GetBits1L +#define WGetBits1U GetBits1U +#endif + +#if NGLYPHS == 2 +# define GetBitsNS GetBits2S +# define GetBitsNL GetBits2L +# define GetBitsNU GetBits2U +# define LastChar char2 +#ifndef CFBTEGBLT8 +# define CFBTEGBLT8 cfbTEGlyphBlt8x2 +#endif +#endif +#if NGLYPHS == 3 +# define GetBitsNS GetBits3S +# define GetBitsNL GetBits3L +# define GetBitsNU GetBits3U +# define LastChar char3 +#ifndef CFBTEGBLT8 +# define CFBTEGBLT8 cfbTEGlyphBlt8x3 +#endif +#endif +#if NGLYPHS == 4 +# define GetBitsNS GetBits4S +# define GetBitsNL GetBits4L +# define GetBitsNU GetBits4U +# define LastChar char4 +#ifndef CFBTEGBLT8 +# define CFBTEGBLT8 cfbTEGlyphBlt8x4 +#endif +#endif +#if NGLYPHS == 5 +# define GetBitsNS GetBits5S +# define GetBitsNL GetBits5L +# define GetBitsNU GetBits5U +# define LastChar char5 +#ifndef CFBTEGBLT8 +# define CFBTEGBLT8 cfbTEGlyphBlt8x5 +#endif +#endif + +/* another ugly giant macro */ +#define SwitchEm switch (ew) \ + { \ + case 0: \ + break; \ + case 1: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 \ + Loop \ + } \ + break; \ + case 2: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) \ + Loop \ + } \ + break; \ + case 3: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step StoreBits(2) \ + Loop \ + } \ + break; \ + case 4: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step \ + StoreBits(2) Step StoreBits(3) \ + Loop \ + } \ + break; \ + case 5: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step \ + StoreBits(2) Step StoreBits(3) Step \ + StoreBits(4) \ + Loop \ + } \ + break; \ + case 6: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step \ + StoreBits(2) Step StoreBits(3) Step \ + StoreBits(4) Step StoreBits(5) \ + Loop \ + } \ + break; \ + case 7: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step \ + StoreBits(2) Step StoreBits(3) Step \ + StoreBits(4) Step StoreBits(5) Step \ + StoreBits(6) \ + Loop \ + } \ + break; \ + case 8: \ + while (hTmp--) { \ + GetBits; \ + StoreBits0 FirstStep StoreBits(1) Step \ + StoreBits(2) Step StoreBits(3) Step \ + StoreBits(4) Step StoreBits(5) Step \ + StoreBits(6) Step StoreBits(7) \ + Loop \ + } \ + break; \ + } + +#ifdef FAST_CONSTANT_OFFSET_MODE +#define StorePixels(o,p) dst[o] = p +#define Loop dst += widthDst; +#else +#define StorePixels(o,p) *dst++ = (p) +#define Loop dst += widthLeft; +#endif + +#define Step NextBitGroup(c); + +#if (BITMAP_BIT_ORDER == MSBFirst) +#define StoreBits(o) StorePixels(o,GetPixelGroup(c)); +#define FirstStep Step +#else +#if PGSZ == 64 +#define StoreBits(o) StorePixels(o,cfb8Pixels[(c) & PGSZBMSK]); +#define FirstStep Step +#else /* PGSZ == 32 */ +#define StoreBits(o) StorePixels(o,*((unsigned long *) (((char *) cfb8Pixels) + (c & 0x3c)))); +#define FirstStep c = BitLeft (c, 2); +#endif /* PGSZ */ +#endif /* BITMAP_BIT_ORDER */ + + +void +CFBTEGBLT8 (pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GC *pGC; + int xInit, yInit; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + register unsigned long c; + register unsigned long *dst; + register unsigned long leftMask, rightMask; + register int hTmp; + register int xoff1; + register glyphPointer char1; + register glyphPointer char2; +#if NGLYPHS >= 3 + register glyphPointer char3; +#endif +#if NGLYPHS >= 4 + register glyphPointer char4; +#endif +#if NGLYPHS >= 5 + register glyphPointer char5; +#endif +#ifdef ALL_LEFTBITS + int xoff2, xoff3, xoff4, xoff5; +#endif + + FontPtr pfont = pGC->font; + unsigned long *dstLine; + glyphPointer oldRightChar; + unsigned long *pdstBase; + glyphPointer leftChar; + int widthDst, widthLeft; + int widthGlyph; + int h; + int ew; + int x, y; + BoxRec bbox; /* for clipping */ + int lshift; + int widthGlyphs; +#ifdef USE_LEFTBITS + register unsigned long glyphMask; + register unsigned long tmpSrc; + register int glyphBytes; +#endif + + widthGlyph = FONTMAXBOUNDS(pfont,characterWidth); + h = FONTASCENT(pfont) + FONTDESCENT(pfont); + if (!h) + return; + x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x; + y = yInit - FONTASCENT(pfont) + pDrawable->y; + bbox.x1 = x; + bbox.x2 = x + (widthGlyph * nglyph); + bbox.y1 = y; + bbox.y2 = y + h; + + switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &bbox)) + { + case rgnPART: + cfbImageGlyphBlt8(pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase); + case rgnOUT: + return; + } + + if (!cfb8CheckPixels (pGC->fgPixel, pGC->bgPixel)) + cfb8SetPixels (pGC->fgPixel, pGC->bgPixel); + + leftChar = 0; + + cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase) + +#if NGLYPHS == 2 + widthGlyphs = widthGlyph << 1; +#else +#if NGLYPHS == 4 + widthGlyphs = widthGlyph << 2; +#else + widthGlyphs = widthGlyph * NGLYPHS; +#endif +#endif + +#ifdef USE_LEFTBITS + glyphMask = endtab[widthGlyph]; + glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci); +#endif + + pdstBase += y * widthDst; +#ifdef DO_COMMON + if (widthGlyphs <= 32) +#endif + while (nglyph >= NGLYPHS) + { + nglyph -= NGLYPHS; + hTmp = h; + dstLine = pdstBase + (x >> PWSH); + xoff1 = x & PIM; + char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); + char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); +#ifdef ALL_LEFTBITS + xoff2 = xoff1 + widthGlyph; +#endif +#if NGLYPHS >= 3 + char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); +#ifdef ALL_LEFTBITS + xoff3 = xoff2 + widthGlyph; +#endif +#endif +#if NGLYPHS >= 4 + char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); +#ifdef ALL_LEFTBITS + xoff4 = xoff3 + widthGlyph; +#endif +#endif +#if NGLYPHS >= 5 + char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); +#ifdef ALL_LEFTBITS + xoff5 = xoff4 + widthGlyph; +#endif +#endif + oldRightChar = LastChar; + dst = dstLine; + if (xoff1) + { + ew = ((widthGlyphs - (PGSZB - xoff1)) >> PWSH) + 1; +#ifndef FAST_CONSTANT_OFFSET_MODE + widthLeft = widthDst - ew; +#endif + if (!leftChar) + { + leftMask = cfbendtab[xoff1]; + rightMask = cfbstarttab[xoff1]; + +#define StoreBits0 StorePixels (0,dst[0] & leftMask | \ + GetPixelGroup(c) & rightMask); +#define GetBits GetBitsNS + + SwitchEm + +#undef GetBits +#undef StoreBits0 + + } + else + { + lshift = widthGlyph - xoff1; + +#define StoreBits0 StorePixels (0,GetPixelGroup(c)); +#define GetBits GetBitsNL + + SwitchEm + +#undef GetBits +#undef StoreBits0 + + } + } + else + { +#if NGLYPHS == 4 && PGSZ == 32 + ew = widthGlyph; /* widthGlyphs >> 2 */ +#else + ew = widthGlyphs >> PWSH; +#endif +#ifndef FAST_CONSTANT_OFFSET_MODE + widthLeft = widthDst - ew; +#endif + +#define StoreBits0 StorePixels (0,GetPixelGroup(c)); +#define GetBits GetBitsNU + + SwitchEm + +#undef GetBits +#undef StoreBits0 + + } + x += widthGlyphs; + leftChar = oldRightChar; + } + while (nglyph--) + { + xoff1 = x & PIM; + char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++); + hTmp = h; + dstLine = pdstBase + (x >> PWSH); + oldRightChar = char1; + dst = dstLine; + if (xoff1) + { + ew = ((widthGlyph - (PGSZB - xoff1)) >> PWSH) + 1; +#ifndef FAST_CONSTANT_OFFSET_MODE + widthLeft = widthDst - ew; +#endif + if (!leftChar) + { + leftMask = cfbendtab[xoff1]; + rightMask = cfbstarttab[xoff1]; + +#define StoreBits0 StorePixels (0,dst[0] & leftMask | GetPixelGroup(c) & rightMask); +#define GetBits WGetBits1S + + SwitchEm +#undef GetBits +#undef StoreBits0 + + } + else + { + lshift = widthGlyph - xoff1; + +#define StoreBits0 StorePixels (0,GetPixelGroup(c)); +#define GetBits WGetBits1L + + SwitchEm +#undef GetBits +#undef StoreBits0 + + } + } + else + { + ew = widthGlyph >> PWSH; + +#ifndef FAST_CONSTANT_OFFSET_MODE + widthLeft = widthDst - ew; +#endif + +#define StoreBits0 StorePixels (0,GetPixelGroup(c)); +#define GetBits WGetBits1U + + SwitchEm + +#undef GetBits +#undef StoreBits0 + + } + x += widthGlyph; + leftChar = oldRightChar; + } + /* + * draw the tail of the last character + */ + xoff1 = x & PIM; + if (xoff1) + { + rightMask = cfbstarttab[xoff1]; + leftMask = cfbendtab[xoff1]; + lshift = widthGlyph - xoff1; + dst = pdstBase + (x >> PWSH); + hTmp = h; + while (hTmp--) + { + GetBitsL; + *dst = (*dst & rightMask) | (GetPixelGroup(c) & leftMask); + dst += widthDst; + } + } +} +#endif /* PSZ == 8 */ diff --git a/cfb/cfbtegblt.c b/cfb/cfbtegblt.c new file mode 100644 index 000000000..383926619 --- /dev/null +++ b/cfb/cfbtegblt.c @@ -0,0 +1,201 @@ +/* $Xorg: cfbtegblt.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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 "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cfbmskbits.h" +#include "mi.h" +#define MFB_CONSTS_ONLY +#include "maskbits.h" + +/* + this works for fonts with glyphs <= 32 bits wide, on an + arbitrarily deep display. Use cfbTEGlyphBlt8 for 8 bit displays. + + This should be called only with a terminal-emulator font; +this means that the FIXED_METRICS flag is set, and that +glyphbounds == charbounds. + + in theory, this goes faster; even if it doesn't, it reduces the +flicker caused by writing a string over itself with image text (since +the background gets repainted per character instead of per string.) +this seems to be important for some converted X10 applications. + + Image text looks at the bits in the glyph and the fg and bg in the +GC. it paints a rectangle, as defined in the protocol dcoument, +and the paints the characters. + +*/ + +void +cfbTEGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) + DrawablePtr pDrawable; + GC *pGC; + int x, y; + unsigned int nglyph; + CharInfoPtr *ppci; /* array of character info */ + pointer pglyphBase; /* start of array of glyphs */ +{ + FontPtr pfont = pGC->font; + int widthDst; + unsigned long *pdstBase; /* pointer to longword with top row + of current glyph */ + + int w; /* width of glyph and char */ + int h; /* height of glyph and char */ + register int xpos=x; /* current x%32 */ + int ypos=y; /* current y%32 */ + register unsigned char *pglyph; + int widthGlyph; + + register unsigned long *pdst;/* pointer to current longword in dst */ + int hTmp; /* counter for height */ + BoxRec bbox; /* for clipping */ + + register int wtmp,xtemp,width; + unsigned long bgfill,fgfill,*ptemp,tmpDst1,tmpDst2,*pdtmp; + int tmpx; + + xpos += pDrawable->x; + ypos += pDrawable->y; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + wtmp = FONTMAXBOUNDS(pfont,characterWidth); + h = FONTASCENT(pfont) + FONTDESCENT(pfont); + widthGlyph = GLYPHWIDTHBYTESPADDED(*ppci); + + xpos += FONTMAXBOUNDS(pfont,leftSideBearing); + ypos -= FONTASCENT(pfont); + + bbox.x1 = xpos; + bbox.x2 = xpos + (wtmp * nglyph); + bbox.y1 = ypos; + bbox.y2 = ypos + h; + + fgfill = PFILL(pGC->fgPixel); + bgfill = PFILL(pGC->bgPixel); + + switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &bbox)) + { + case rgnOUT: + break; + case rgnPART: + /* this is the WRONG thing to do, but it works. + calling the non-terminal text is easy, but slow, given + what we know about the font. + + the right thing to do is something like: + for each clip rectangle + compute at which row the glyph starts to be in it, + and at which row the glyph ceases to be in it + compute which is the first glyph inside the left + edge, and the last one inside the right edge + draw a fractional first glyph, using only + the rows we know are in + draw all the whole glyphs, using the appropriate rows + draw any pieces of the last glyph, using the right rows + + this way, the code would take advantage of knowing that + all glyphs are the same height and don't overlap. + + one day... + */ + miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + break; + case rgnIN: + + pdtmp = pdstBase + (widthDst * ypos); + while(nglyph--) + { + + pglyph = FONTGLYPHBITS(pglyphBase, *ppci++); + pdst = pdtmp; + hTmp = h; + + while (hTmp--) + { + x = xpos; + width = wtmp; + xtemp = 0; + + while (width > 0) + { + tmpx = x & PIM; + w = min(width, PPW - tmpx); + w = min(w, (PGSZ - xtemp)); + + ptemp = (unsigned long *)(pglyph + (xtemp >> MFB_PWSH)); + getstipplepixels(ptemp,xtemp,w,0,&bgfill,&tmpDst1); + getstipplepixels(ptemp,xtemp,w,1,&fgfill,&tmpDst2); + + { + unsigned long tmpDst = tmpDst1 | tmpDst2; + unsigned long *pdsttmp = pdst + (x >> PWSH); + putbits(tmpDst,tmpx,w,pdsttmp,pGC->planemask); + } + x += w; + xtemp += w; + width -= w; + } + pglyph += widthGlyph; + pdst += widthDst; + } + xpos += wtmp; + } + break; + } +} diff --git a/cfb/cfbtile32.c b/cfb/cfbtile32.c new file mode 100644 index 000000000..544857a25 --- /dev/null +++ b/cfb/cfbtile32.c @@ -0,0 +1,352 @@ +/* + * Fill 32 bit tiled rectangles. Used by both PolyFillRect and PaintWindow. + * no depth dependencies. + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* $Xorg: cfbtile32.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +#include "mergerop.h" + +#include "mi.h" +#include "mispans.h" + +#ifdef sparc +#define SHARED_IDCACHE +#endif + +#define STORE(p) (*(p) = MROP_PREBUILT_SOLID(srcpix,*(p))) + +#if (MROP == Mcopy) && defined(FAST_CONSTANT_OFFSET_MODE) && defined(SHARED_IDCACHE) +# define Expand(left,right) {\ + int part = nlwMiddle & ((PGSZB*2)-1); \ + nlwMiddle >>= PWSH + 1; \ + while (h--) { \ + srcpix = psrc[srcy]; \ + MROP_PREBUILD(srcpix); \ + ++srcy; \ + if (srcy == tileHeight) \ + srcy = 0; \ + left \ + p += part; \ + switch (part) { \ + case 7: \ + STORE(p - 7); \ + case 6: \ + STORE(p - 6); \ + case 5: \ + STORE(p - 5); \ + case 4: \ + STORE(p - 4); \ + case 3: \ + STORE(p - 3); \ + case 2: \ + STORE(p - 2); \ + case 1: \ + STORE(p - 1); \ + } \ + nlw = nlwMiddle; \ + while (nlw) { \ + STORE (p + 0); \ + STORE (p + 1); \ + STORE (p + 2); \ + STORE (p + 3); \ + STORE (p + 4); \ + STORE (p + 5); \ + STORE (p + 6); \ + STORE (p + 7); \ + p += 8; \ + nlw--; \ + } \ + right \ + p += nlwExtra; \ + } \ +} +#else +#define Expand(left,right) {\ + while (h--) { \ + srcpix = psrc[srcy]; \ + MROP_PREBUILD(srcpix); \ + ++srcy; \ + if (srcy == tileHeight) \ + srcy = 0; \ + left \ + nlw = nlwMiddle; \ + while (nlw--) \ + { \ + STORE(p); \ + p++; \ + } \ + right \ + p += nlwExtra; \ + } \ +} +#endif + +void +MROP_NAME(cfbFillRectTile32) (pDrawable, pGC, nBox, pBox) + DrawablePtr pDrawable; + GCPtr pGC; + int nBox; /* number of boxes to fill */ + BoxPtr pBox; /* pointer to list of boxes to fill */ +{ + register unsigned long srcpix; + unsigned long *psrc; /* pointer to bits in tile, if needed */ + int tileHeight; /* height of the tile */ + + int nlwDst; /* width in longwords of the dest pixmap */ + int w; /* width of current box */ + register int h; /* height of current box */ + register unsigned long startmask; + register unsigned long endmask; /* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + int nlwExtra; /* to get from right of box to left of next span */ + register int nlw; /* loop version of nlwMiddle */ + register unsigned long *p; /* pointer to bits we're writing */ + int y; /* current scan line */ + int srcy; /* current tile position */ + + unsigned long *pbits;/* pointer to start of pixmap */ + PixmapPtr tile; /* rotated, expanded tile */ + MROP_DECLARE_REG() + MROP_PREBUILT_DECLARE() + + tile = cfbGetGCPrivate(pGC)->pRotatedPixmap; + tileHeight = tile->drawable.height; + psrc = (unsigned long *)tile->devPrivate.ptr; + + MROP_INITIALIZE(pGC->alu, pGC->planemask); + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + + while (nBox--) + { + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + y = pBox->y1; + p = pbits + (y * nlwDst) + (pBox->x1 >> PWSH); + srcy = y % tileHeight; + + if ( ((pBox->x1 & PIM) + w) <= PPW) + { + maskpartialbits(pBox->x1, w, startmask); + nlwExtra = nlwDst; + while (h--) + { + srcpix = psrc[srcy]; + MROP_PREBUILD(srcpix); + ++srcy; + if (srcy == tileHeight) + srcy = 0; + *p = MROP_PREBUILT_MASK (srcpix, *p, startmask); + p += nlwExtra; + } + } + else + { + maskbits(pBox->x1, w, startmask, endmask, nlwMiddle); + nlwExtra = nlwDst - nlwMiddle; + + if (startmask) + { + nlwExtra -= 1; + if (endmask) + { + Expand(*p = MROP_PREBUILT_MASK(srcpix, *p, startmask); p++;, + *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);) + } + else + { + Expand(*p = MROP_PREBUILT_MASK(srcpix, *p, startmask); p++;, + ;) + } + } + else + { + if (endmask) + { + Expand(;, + *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);) + } + else + { + Expand(;, + ;) + } + } + } + pBox++; + } +} + +void +MROP_NAME(cfbTile32FS)(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) + DrawablePtr pDrawable; + GCPtr pGC; + int nInit; /* number of spans to fill */ + DDXPointPtr pptInit; /* pointer to list of start points */ + int *pwidthInit; /* pointer to list of n widths */ + int fSorted; +{ + /* next three parameters are post-clip */ + int n; /* number of spans to fill */ + DDXPointPtr ppt; /* pointer to list of start points */ + int *pwidth;/* pointer to list of n widths */ + unsigned long *pbits; /* pointer to start of bitmap */ + int nlwDst; /* width in longwords of bitmap */ + register unsigned long *p; /* pointer to current longword in bitmap */ + register int w; /* current span width */ + register int nlw; + register int x; + register unsigned long startmask; + register unsigned long endmask; + register unsigned long srcpix; + int y; + int *pwidthFree;/* copies of the pointers to free */ + DDXPointPtr pptFree; + PixmapPtr tile; + unsigned long *psrc; /* pointer to bits in tile */ + int tileHeight;/* height of the tile */ + MROP_DECLARE_REG () + MROP_PREBUILT_DECLARE() + + n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) ); + pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) + { + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + pwidth = pwidthFree; + ppt = pptFree; + n = miClipSpans( cfbGetCompositeClip(pGC), + pptInit, pwidthInit, nInit, + ppt, pwidth, fSorted); + + tile = cfbGetGCPrivate(pGC)->pRotatedPixmap; + tileHeight = tile->drawable.height; + psrc = (unsigned long *)tile->devPrivate.ptr; + + MROP_INITIALIZE(pGC->alu, pGC->planemask); + + cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits) + +#if MROP == Mcopy + if (!(tileHeight & (tileHeight-1))) + { + tileHeight--; + while (n--) + { + x = ppt->x; + y = ppt->y; + ++ppt; + w = *pwidth++; + p = pbits + (y * nlwDst) + (x >> PWSH); + srcpix = psrc[y & tileHeight]; + MROP_PREBUILD(srcpix); + + if ((x & PIM) + w < PPW) + { + maskpartialbits(x, w, startmask); + *p = MROP_PREBUILT_MASK (srcpix, *p, startmask); + } + else + { + maskbits(x, w, startmask, endmask, nlw); + if (startmask) + { + *p = MROP_PREBUILT_MASK(srcpix, *p, startmask); + p++; + } + while (nlw--) + { + STORE(p); + ++p; + } + if (endmask) + { + *p = MROP_PREBUILT_MASK(srcpix, *p, endmask); + } + } + } + } + else +#endif + { + while (n--) + { + x = ppt->x; + y = ppt->y; + ++ppt; + w = *pwidth++; + p = pbits + (y * nlwDst) + (x >> PWSH); + srcpix = psrc[y % tileHeight]; + MROP_PREBUILD(srcpix); + + if ((x & PIM) + w < PPW) + { + maskpartialbits(x, w, startmask); + *p = MROP_PREBUILT_MASK (srcpix, *p, startmask); + } + else + { + maskbits(x, w, startmask, endmask, nlw); + if (startmask) + { + *p = MROP_PREBUILT_MASK(srcpix, *p, startmask); + p++; + } + while (nlw--) + { + STORE(p); + ++p; + } + if (endmask) + { + *p = MROP_PREBUILT_MASK(srcpix, *p, endmask); + } + } + } + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); +} diff --git a/cfb/cfbtileodd.c b/cfb/cfbtileodd.c new file mode 100644 index 000000000..2307f6b55 --- /dev/null +++ b/cfb/cfbtileodd.c @@ -0,0 +1,1080 @@ +/* + * Fill odd tiled rectangles and spans. + * no depth dependencies. + */ + +/* + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* $Xorg: cfbtileodd.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + +#include "mergerop.h" + +#if PGSZ == 32 +#define LEFTSHIFT_AMT (5 - PWSH) +#else /* PGSZ == 64 */ +#define LEFTSHIFT_AMT (6 - PWSH) +#endif /* PGSZ */ + +#define LastTileBits {\ + tmp = bits; \ + if (tileEndPart) \ + bits = (*pSrc & tileEndMask) | BitRight (*pSrcLine, tileEndLeftShift); \ + else \ + bits = *pSrc; \ +} + +#define ResetTileBits {\ + pSrc = pSrcLine; \ + nlwSrc = widthSrc;\ + if (tileEndPart) { \ + if (PPW - xoff + tileEndPart <= PPW) {\ + bits = *pSrc++; \ + nlwSrc--; \ + } else \ + bits = BitLeft(tmp, tileEndLeftShift) | \ + BitRight(bits, tileEndRightShift); \ + xoff = (xoff + xoffStep) & PIM; \ + leftShift = xoff << LEFTSHIFT_AMT; \ + rightShift = PGSZ - leftShift; \ + }\ +} + +#define NextTileBits {\ + if (nlwSrc == 1) {\ + LastTileBits\ + } else { \ + if (nlwSrc == 0) {\ + ResetTileBits\ + } \ + if (nlwSrc == 1) {\ + LastTileBits\ + } else {\ + tmp = bits; \ + bits = *pSrc++; \ + }\ + }\ + nlwSrc--; \ +} + +void +MROP_NAME(cfbFillBoxTileOdd) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask) + DrawablePtr pDrawable; + int nBox; /* number of boxes to fill */ + register BoxPtr pBox; /* pointer to list of boxes to fill */ + PixmapPtr tile; /* tile */ + int xrot, yrot; + int alu; + unsigned long planemask; +{ + int tileWidth; /* width of tile in pixels */ + int tileHeight; /* height of the tile */ + int widthSrc; + + int widthDst; /* width in longwords of the dest pixmap */ + int w; /* width of current box */ + int h; /* height of current box */ + unsigned long startmask; + unsigned long endmask;/* masks for reggedy bits at either end of line */ + int nlwMiddle; /* number of longwords between sides of boxes */ + int nlwSrc; /* number of whole longwords in source */ + + register int nlw; /* loop version of nlwMiddle */ + int srcy; /* current tile y position */ + int srcx; /* current tile x position */ + int xoffDst, xoffSrc; + int leftShift, rightShift; + + MROP_DECLARE_REG() + + unsigned long *pDstBase; /* pointer to start of dest */ + unsigned long *pDstLine; /* poitner to start of dest box */ + unsigned long *pSrcBase; /* pointer to start of source */ + unsigned long *pSrcLine; /* pointer to start of source line */ + register unsigned long *pDst; + register unsigned long *pSrc; + register unsigned long bits, tmp; + register int nlwPart; + int xoffStart, xoff; + int leftShiftStart, rightShiftStart, nlwSrcStart; + unsigned long tileEndMask; + int tileEndLeftShift, tileEndRightShift; + int xoffStep; + int tileEndPart; + int needFirst; + unsigned long narrow[2]; + unsigned long narrowMask; + int narrowShift; + Bool narrowTile; + + MROP_INITIALIZE (alu, planemask) + + tileHeight = tile->drawable.height; + tileWidth = tile->drawable.width; + widthSrc = tile->devKind / PGSZB; + narrowTile = FALSE; + if (widthSrc == 1) + { + narrowShift = tileWidth; + narrowMask = cfbendpartial [tileWidth]; + tileWidth *= 2; + widthSrc = 2; + narrowTile = TRUE; + } + pSrcBase = (unsigned long *)tile->devPrivate.ptr; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase) + + tileEndPart = tileWidth & PIM; + tileEndMask = cfbendpartial[tileEndPart]; + tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT; + tileEndRightShift = PGSZ - tileEndLeftShift; + xoffStep = PPW - tileEndPart; + /* + * current assumptions: tile > 32 bits wide. + */ + while (nBox--) + { + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + modulus (pBox->x1 - xrot, tileWidth, srcx); + modulus (pBox->y1 - yrot, tileHeight, srcy); + xoffDst = pBox->x1 & PIM; + if (xoffDst + w < PPW) + { + maskpartialbits(pBox->x1, w, startmask); + endmask = 0; + nlwMiddle = 0; + } + else + { + maskbits (pBox->x1, w, startmask, endmask, nlwMiddle) + } + pDstLine = pDstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH); + pSrcLine = pSrcBase + (srcy * widthSrc); + xoffSrc = srcx & PIM; + if (xoffSrc >= xoffDst) + { + xoffStart = xoffSrc - xoffDst; + needFirst = 1; + } + else + { + xoffStart = PPW - (xoffDst - xoffSrc); + needFirst = 0; + } + leftShiftStart = (xoffStart) << LEFTSHIFT_AMT; + rightShiftStart = PGSZ - leftShiftStart; + nlwSrcStart = widthSrc - (srcx >> PWSH); + while (h--) + { + /* XXX only works when narrowShift >= PPW/2 */ + if (narrowTile) + { + tmp = pSrcBase[srcy] & narrowMask; /* source width == 1 */ + narrow[0] = tmp | SCRRIGHT (tmp, narrowShift); + narrow[1] = SCRLEFT (tmp, PPW - narrowShift) | + SCRRIGHT(tmp, 2 * narrowShift - PPW); + pSrcLine = narrow; + } + xoff = xoffStart; + leftShift = leftShiftStart; + rightShift = rightShiftStart; + nlwSrc = nlwSrcStart; + pSrc = pSrcLine + (srcx >> PWSH); + pDst = pDstLine; + bits = 0; + if (needFirst) + { + NextTileBits + } + if (startmask) + { + NextTileBits + tmp = BitLeft(tmp, leftShift); + if (rightShift != PGSZ) + tmp |= BitRight(bits,rightShift); + *pDst = MROP_MASK (tmp, *pDst, startmask); + ++pDst; + } + nlw = nlwMiddle; + while (nlw) + { +#if MROP == Mcopy + if (nlwSrc > 1) + { + nlwPart = nlw; + if (nlwPart >= nlwSrc) + nlwPart = nlwSrc - 1; + nlw -= nlwPart; + nlwSrc -= nlwPart; + if (rightShift != PGSZ) + { + while (nlwPart--) + { + tmp = bits; + bits = *pSrc++; + *pDst = MROP_SOLID(BitLeft(tmp, leftShift) | + BitRight (bits, rightShift), + *pDst); + ++pDst; + } + } + else + { + if (nlwPart) + { + *pDst = MROP_SOLID (bits, *pDst); + ++pDst; + nlwPart--; + while (nlwPart--) + { + *pDst = MROP_SOLID(*pSrc, *pDst); + ++pDst; ++pSrc; + } + bits = *pSrc++; + } + } + } + else +#endif + { + NextTileBits + if (rightShift != PGSZ) + { + *pDst = MROP_SOLID(BitLeft(tmp, leftShift) | + BitRight(bits, rightShift), + *pDst); + } + else + { + *pDst = MROP_SOLID (tmp, *pDst); + } + ++pDst; + nlw--; + } + } + if (endmask) + { + NextTileBits + if (rightShift == PGSZ) + bits = 0; + *pDst = MROP_MASK (BitLeft(tmp, leftShift) | + BitRight(bits,rightShift), + *pDst, endmask); + } + pDstLine += widthDst; + pSrcLine += widthSrc; + if (++srcy == tileHeight) + { + srcy = 0; + pSrcLine = pSrcBase; + } + } + pBox++; + } +} + +void +MROP_NAME(cfbFillSpanTileOdd) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask) + DrawablePtr pDrawable; + int n; + DDXPointPtr ppt; + int *pwidth; + PixmapPtr tile; + int xrot, yrot; + int alu; + unsigned long planemask; +{ + int tileWidth; /* width of tile in pixels */ + int tileHeight; /* height of the tile */ + int widthSrc; + + int widthDst; /* width in longwords of the dest pixmap */ + int w; /* width of current span */ + unsigned long startmask; + unsigned long endmask; /* masks for reggedy bits at either end of line */ + int nlwSrc; /* number of whole longwords in source */ + + register int nlw; /* loop version of nlwMiddle */ + int srcy; /* current tile y position */ + int srcx; /* current tile x position */ + int xoffDst, xoffSrc; + int leftShift, rightShift; + + MROP_DECLARE_REG() + + unsigned long *pDstBase; /* pointer to start of dest */ + unsigned long *pDstLine; /* poitner to start of dest box */ + unsigned long *pSrcBase; /* pointer to start of source */ + unsigned long *pSrcLine; /* pointer to start of source line */ + register unsigned long *pDst; + register unsigned long *pSrc; + register unsigned long bits, tmp; + register int nlwPart; + int xoffStart, xoff; + int leftShiftStart, rightShiftStart, nlwSrcStart; + unsigned long tileEndMask; + int tileEndLeftShift, tileEndRightShift; + int xoffStep; + int tileEndPart; + int needFirst; + unsigned long narrow[2]; + unsigned long narrowMask; + int narrowShift; + Bool narrowTile; + + MROP_INITIALIZE (alu, planemask) + + tileHeight = tile->drawable.height; + tileWidth = tile->drawable.width; + widthSrc = tile->devKind / PGSZB; + narrowTile = FALSE; + if (widthSrc == 1) + { + narrowShift = tileWidth; + narrowMask = cfbendpartial [tileWidth]; + tileWidth *= 2; + widthSrc = 2; + narrowTile = TRUE; + } + pSrcBase = (unsigned long *)tile->devPrivate.ptr; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase) + + tileEndPart = tileWidth & PIM; + tileEndMask = cfbendpartial[tileEndPart]; + tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT; + tileEndRightShift = PGSZ - tileEndLeftShift; + xoffStep = PPW - tileEndPart; + while (n--) + { + w = *pwidth++; + modulus (ppt->x - xrot, tileWidth, srcx); + modulus (ppt->y - yrot, tileHeight, srcy); + xoffDst = ppt->x & PIM; + if (xoffDst + w < PPW) + { + maskpartialbits(ppt->x, w, startmask); + endmask = 0; + nlw = 0; + } + else + { + maskbits (ppt->x, w, startmask, endmask, nlw) + } + pDstLine = pDstBase + (ppt->y * widthDst) + (ppt->x >> PWSH); + pSrcLine = pSrcBase + (srcy * widthSrc); + xoffSrc = srcx & PIM; + if (xoffSrc >= xoffDst) + { + xoffStart = xoffSrc - xoffDst; + needFirst = 1; + } + else + { + xoffStart = PPW - (xoffDst - xoffSrc); + needFirst = 0; + } + leftShiftStart = (xoffStart) << LEFTSHIFT_AMT; + rightShiftStart = PGSZ - leftShiftStart; + nlwSrcStart = widthSrc - (srcx >> PWSH); + /* XXX only works when narrowShift >= PPW/2 */ + if (narrowTile) + { + tmp = pSrcBase[srcy] & narrowMask; /* source width == 1 */ + narrow[0] = tmp | SCRRIGHT (tmp, narrowShift); + narrow[1] = SCRLEFT (tmp, PPW - narrowShift) | + SCRRIGHT(tmp, 2 * narrowShift - PPW); + pSrcLine = narrow; + } + xoff = xoffStart; + leftShift = leftShiftStart; + rightShift = rightShiftStart; + nlwSrc = nlwSrcStart; + pSrc = pSrcLine + (srcx >> PWSH); + pDst = pDstLine; + bits = 0; + if (needFirst) + { + NextTileBits + } + if (startmask) + { + NextTileBits + tmp = BitLeft(tmp, leftShift); + if (rightShift != PGSZ) + tmp |= BitRight(bits,rightShift); + *pDst = MROP_MASK (tmp, *pDst, startmask); + ++pDst; + } + while (nlw) + { +#if MROP == Mcopy + if (nlwSrc > 1) + { + nlwPart = nlw; + if (nlwPart >= nlwSrc) + nlwPart = nlwSrc - 1; + nlw -= nlwPart; + nlwSrc -= nlwPart; + if (rightShift != PGSZ) + { + while (nlwPart--) + { + tmp = bits; + bits = *pSrc++; + *pDst = MROP_SOLID(BitLeft(tmp, leftShift) | + BitRight (bits, rightShift), + *pDst); + ++pDst; + } + } + else + { + if (nlwPart) + { + *pDst = MROP_SOLID (bits, *pDst); + ++pDst; + nlwPart--; + while (nlwPart--) + { + *pDst = MROP_SOLID(*pSrc, *pDst); + ++pDst; ++pSrc; + } + bits = *pSrc++; + } + } + } + else +#endif + { + NextTileBits + if (rightShift != PGSZ) + { + *pDst = MROP_SOLID(BitLeft(tmp, leftShift) | + BitRight(bits, rightShift), + *pDst); + ++pDst; + } + else + { + *pDst = MROP_SOLID (tmp, *pDst); + ++pDst; + } + nlw--; + } + } + if (endmask) + { + NextTileBits + if (rightShift == PGSZ) + bits = 0; + *pDst = MROP_MASK (BitLeft(tmp, leftShift) | + BitRight(bits,rightShift), + *pDst, endmask); + } + ppt++; + } +} + +# include "fastblt.h" + +#define IncSrcPtr psrc++; if (!--srcRemaining) { srcRemaining = widthSrc; psrc = psrcStart; } + +void +MROP_NAME(cfbFillBoxTile32s) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask) + DrawablePtr pDrawable; + int nBox; /* number of boxes to fill */ + register BoxPtr pBox; /* pointer to list of boxes to fill */ + PixmapPtr tile; /* tile */ + int xrot, yrot; + int alu; + unsigned long planemask; +{ + int tileWidth; /* width of tile */ + int tileHeight; /* height of the tile */ + int widthSrc; /* width in longwords of the source tile */ + + int widthDst; /* width in longwords of the dest pixmap */ + int w; /* width of current box */ + int h; /* height of current box */ + unsigned long startmask; + unsigned long endmask;/* masks for reggedy bits at either end of line */ + int nlMiddle; /* number of longwords between sides of boxes */ + + register int nl; /* loop version of nlMiddle */ + int srcy; /* current tile y position */ + int srcx; /* current tile x position */ + int srcRemaining; /* number of longwords remaining in source */ + int xoffDst, xoffSrc; + int srcStart; /* number of longwords source offset at left of box */ + int leftShift, rightShift; + + MROP_DECLARE_REG() + + unsigned long *pdstBase; /* pointer to start of dest */ + unsigned long *pdstLine; /* poitner to start of dest box */ + unsigned long *psrcBase; /* pointer to start of source */ + unsigned long *psrcLine; /* pointer to fetch point of source */ + unsigned long *psrcStart; /* pointer to start of source line */ + register unsigned long *pdst; + register unsigned long *psrc; + register unsigned long bits, bits1; + register int nlTemp; + + MROP_INITIALIZE (alu, planemask) + + psrcBase = (unsigned long *)tile->devPrivate.ptr; + tileHeight = tile->drawable.height; + tileWidth = tile->drawable.width; + widthSrc = tileWidth >> PWSH; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + while (nBox--) + { + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + + /* set up source */ + modulus (pBox->x1 - xrot, tileWidth, srcx); + modulus (pBox->y1 - yrot, tileHeight, srcy); + xoffSrc = srcx & PIM; + srcStart = (srcx >> PWSH); + psrcStart = psrcBase + (srcy * widthSrc); + psrcLine = psrcStart + srcStart; + + /* set up dest */ + xoffDst = pBox->x1 & PIM; + pdstLine = pdstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH); + /* set up masks */ + if (xoffDst + w < PPW) + { + maskpartialbits(pBox->x1, w, startmask); + endmask = 0; + nlMiddle = 0; + } + else + { + maskbits (pBox->x1, w, startmask, endmask, nlMiddle) + } + if (xoffSrc == xoffDst) + { + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + srcRemaining = widthSrc - srcStart; + if (startmask) + { + *pdst = MROP_MASK (*psrc, *pdst, startmask); + pdst++; + IncSrcPtr + } + nlTemp = nlMiddle; + while (nlTemp) + { + nl = nlTemp; + if (nl > srcRemaining) + nl = srcRemaining; + + nlTemp -= nl; + srcRemaining -= nl; + +#if MROP == Mcopy +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); +#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++; +#define BodyEven(n) BodyOdd(n) + +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl, label1, + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++;) +#endif +#else + while (nl--) { + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++; + } +#endif + if (!srcRemaining) + { + srcRemaining = widthSrc; + psrc = psrcStart; + } + } + if (endmask) + { + *pdst = MROP_MASK (*psrc, *pdst, endmask); + } + pdstLine += widthDst; + psrcLine += widthSrc; + psrcStart += widthSrc; + if (++srcy == tileHeight) + { + psrcStart = psrcBase; + psrcLine = psrcStart + srcStart; + srcy = 0; + } + } + } + else + { + if (xoffSrc > xoffDst) + { + leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT; + rightShift = PGSZ - leftShift; + } + else + { + rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT; + leftShift = PGSZ - rightShift; + } + while (h--) + { + psrc = psrcLine; + pdst = pdstLine; + bits = 0; + srcRemaining = widthSrc - srcStart; + if (xoffSrc > xoffDst) + { + bits = *psrc; + IncSrcPtr + } + if (startmask) + { + bits1 = BitLeft(bits,leftShift); + bits = *psrc; + IncSrcPtr + bits1 |= BitRight(bits,rightShift); + *pdst = MROP_MASK(bits1, *pdst, startmask); + pdst++; + } + nlTemp = nlMiddle; + while (nlTemp) + { + nl = nlTemp; + if (nl > srcRemaining) + nl = srcRemaining; + + nlTemp -= nl; + srcRemaining -= nl; + +#if MROP == Mcopy +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; + +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) \ + bits = psrc[-n]; \ + pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]); + +#define BodyEven(n) \ + bits1 = psrc[-n]; \ + pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]); + +#define LoopReset \ + pdst += UNROLL; \ + psrc += UNROLL; + +#else + +#define BodyOdd(n) \ + bits = *psrc++; \ + *pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \ + pdst++; + +#define BodyEven(n) \ + bits1 = *psrc++; \ + *pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \ + pdst++; + +#define LoopReset ; + +#endif /* !FAST_CONSTANT_OFFSET_MODE */ + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL (nl,label2, + bits1 = BitLeft(bits, leftShift); + bits = *psrc++; + *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst); + pdst++; + ) +#endif +#else + while (nl--) { + bits1 = BitLeft(bits, leftShift); + bits = *psrc++; + *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst); + pdst++; + } +#endif + if (!srcRemaining) + { + srcRemaining = widthSrc; + psrc = psrcStart; + } + } + + if (endmask) + { + bits1 = BitLeft(bits, leftShift); + if (BitLeft(endmask, rightShift)) + { + bits = *psrc; + bits1 |= BitRight(bits, rightShift); + } + *pdst = MROP_MASK (bits1, *pdst, endmask); + } + pdstLine += widthDst; + psrcLine += widthSrc; + psrcStart += widthSrc; + if (++srcy == tileHeight) + { + psrcStart = psrcBase; + psrcLine = psrcStart + srcStart; + srcy = 0; + } + } + } + pBox++; + } +} + +void +MROP_NAME(cfbFillSpanTile32s) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask) + DrawablePtr pDrawable; + int n; + DDXPointPtr ppt; + int *pwidth; + PixmapPtr tile; + int xrot, yrot; + int alu; + unsigned long planemask; +{ + int tileWidth; /* width of tile */ + int tileHeight; /* height of the tile */ + int widthSrc; /* width in longwords of the source tile */ + + int widthDst; /* width in longwords of the dest pixmap */ + int w; /* width of current box */ + unsigned long startmask; + unsigned long endmask;/* masks for reggedy bits at either end of line */ + int nlMiddle; /* number of longwords between sides of boxes */ + + register int nl; /* loop version of nlMiddle */ + int srcy; /* current tile y position */ + int srcx; /* current tile x position */ + int srcRemaining; /* number of longwords remaining in source */ + int xoffDst, xoffSrc; + int srcStart; /* number of longwords source offset at left of box */ + int leftShift, rightShift; + + MROP_DECLARE_REG() + + unsigned long *pdstBase; /* pointer to start of dest */ + unsigned long *pdstLine; /* poitner to start of dest box */ + unsigned long *psrcBase; /* pointer to start of source */ + unsigned long *psrcLine; /* pointer to fetch point of source */ + unsigned long *psrcStart; /* pointer to start of source line */ + register unsigned long *pdst; + register unsigned long *psrc; + register unsigned long bits, bits1; + register int nlTemp; + + MROP_INITIALIZE (alu, planemask) + + psrcBase = (unsigned long *)tile->devPrivate.ptr; + tileHeight = tile->drawable.height; + tileWidth = tile->drawable.width; + widthSrc = tileWidth >> PWSH; + + cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase) + + while (n--) + { + w = *pwidth++; + + /* set up source */ + modulus (ppt->x - xrot, tileWidth, srcx); + modulus (ppt->y - yrot, tileHeight, srcy); + xoffSrc = srcx & PIM; + srcStart = (srcx >> PWSH); + psrcStart = psrcBase + (srcy * widthSrc); + psrcLine = psrcStart + srcStart; + + /* set up dest */ + xoffDst = ppt->x & PIM; + pdstLine = pdstBase + (ppt->y * widthDst) + (ppt->x >> PWSH); + /* set up masks */ + if (xoffDst + w < PPW) + { + maskpartialbits(ppt->x, w, startmask); + endmask = 0; + nlMiddle = 0; + } + else + { + maskbits (ppt->x, w, startmask, endmask, nlMiddle) + } + + if (xoffSrc == xoffDst) + { + psrc = psrcLine; + pdst = pdstLine; + srcRemaining = widthSrc - srcStart; + if (startmask) + { + *pdst = MROP_MASK (*psrc, *pdst, startmask); + pdst++; + IncSrcPtr + } + nlTemp = nlMiddle; + while (nlTemp) + { + nl = nlTemp; + if (nl > srcRemaining) + nl = srcRemaining; + + nlTemp -= nl; + srcRemaining -= nl; + +#if MROP == Mcopy +#ifdef LARGE_INSTRUCTION_CACHE +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); +#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++; +#define BodyEven(n) BodyOdd(n) + +#define LoopReset ; + +#endif + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL(nl, label1, + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++;) +#endif +#else + while (nl--) { + *pdst = MROP_SOLID (*psrc, *pdst); + pdst++; psrc++; + } +#endif + if (!srcRemaining) + { + srcRemaining = widthSrc; + psrc = psrcStart; + } + } + if (endmask) + { + *pdst = MROP_MASK (*psrc, *pdst, endmask); + } + } + else + { + if (xoffSrc > xoffDst) + { + leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT; + rightShift = PGSZ - leftShift; + } + else + { + rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT; + leftShift = PGSZ - rightShift; + } + psrc = psrcLine; + pdst = pdstLine; + bits = 0; + srcRemaining = widthSrc - srcStart; + if (xoffSrc > xoffDst) + { + bits = *psrc; + IncSrcPtr + } + if (startmask) + { + bits1 = BitLeft(bits,leftShift); + bits = *psrc; + IncSrcPtr + bits1 |= BitRight(bits,rightShift); + *pdst = MROP_MASK(bits1, *pdst, startmask); + pdst++; + } + nlTemp = nlMiddle; + while (nlTemp) + { + nl = nlTemp; + if (nl > srcRemaining) + nl = srcRemaining; + + nlTemp -= nl; + srcRemaining -= nl; + +#if MROP == Mcopy +#ifdef LARGE_INSTRUCTION_CACHE + bits1 = bits; + +#ifdef FAST_CONSTANT_OFFSET_MODE + + psrc += nl & (UNROLL-1); + pdst += nl & (UNROLL-1); + +#define BodyOdd(n) \ +bits = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]); + +#define BodyEven(n) \ +bits1 = psrc[-n]; \ +pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]); + +#define LoopReset \ +pdst += UNROLL; \ +psrc += UNROLL; + +#else + +#define BodyOdd(n) \ +bits = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \ +pdst++; + +#define BodyEven(n) \ +bits1 = *psrc++; \ +*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \ +pdst++; + +#define LoopReset ; + +#endif /* !FAST_CONSTANT_OFFSET_MODE */ + + PackedLoop + +#undef BodyOdd +#undef BodyEven +#undef LoopReset + +#else + DuffL (nl,label2, + bits1 = BitLeft(bits, leftShift); + bits = *psrc++; + *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst); + pdst++; + ) +#endif +#else + while (nl--) { + bits1 = BitLeft(bits,leftShift); + bits = *psrc++; + *pdst = MROP_SOLID(bits1|BitRight(bits,rightShift), *pdst); + pdst++; + } +#endif + if (!srcRemaining) + { + srcRemaining = widthSrc; + psrc = psrcStart; + } + } + + if (endmask) + { + bits1 = BitLeft(bits, leftShift); + if (BitLeft(endmask, rightShift)) + { + bits = *psrc; + bits1 |= BitRight(bits, rightShift); + } + *pdst = MROP_MASK (bits1, *pdst, endmask); + } + } + ppt++; + } +} diff --git a/cfb/cfbwindow.c b/cfb/cfbwindow.c new file mode 100644 index 000000000..244aa412b --- /dev/null +++ b/cfb/cfbwindow.c @@ -0,0 +1,334 @@ +/* $Xorg: cfbwindow.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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 "scrnintstr.h" +#include "windowstr.h" +#include "cfb.h" +#include "mistruct.h" +#include "regionstr.h" +#include "cfbmskbits.h" + +extern WindowPtr *WindowTable; + +Bool +cfbCreateWindow(pWin) + WindowPtr pWin; +{ + cfbPrivWin *pPrivWin; + + pPrivWin = cfbGetWindowPrivate(pWin); + pPrivWin->pRotatedBorder = NullPixmap; + pPrivWin->pRotatedBackground = NullPixmap; + pPrivWin->fastBackground = FALSE; + pPrivWin->fastBorder = FALSE; + pPrivWin->oldRotate.x = 0; + pPrivWin->oldRotate.y = 0; + +#ifdef PIXMAP_PER_WINDOW + /* Setup pointer to Screen pixmap */ + pWin->devPrivates[frameWindowPrivateIndex].ptr = + (pointer) cfbGetScreenPixmap(pWin->drawable.pScreen); +#endif + + return TRUE; +} + +Bool +cfbDestroyWindow(pWin) + WindowPtr pWin; +{ + cfbPrivWin *pPrivWin; + + pPrivWin = cfbGetWindowPrivate(pWin); + + if (pPrivWin->pRotatedBorder) + (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder); + if (pPrivWin->pRotatedBackground) + (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground); + return(TRUE); +} + +/*ARGSUSED*/ +Bool +cfbMapWindow(pWindow) + WindowPtr pWindow; +{ + return(TRUE); +} + +/* (x, y) is the upper left corner of the window on the screen + do we really need to pass this? (is it a;ready in pWin->absCorner?) + we only do the rotation for pixmaps that are 32 bits wide (padded +or otherwise.) + cfbChangeWindowAttributes() has already put a copy of the pixmap +in pPrivWin->pRotated* +*/ +/*ARGSUSED*/ +Bool +cfbPositionWindow(pWin, x, y) + WindowPtr pWin; + int x, y; +{ + cfbPrivWin *pPrivWin; + int setxy = 0; + + pPrivWin = cfbGetWindowPrivate(pWin); + if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground) + { + cfbXRotatePixmap(pPrivWin->pRotatedBackground, + pWin->drawable.x - pPrivWin->oldRotate.x); + cfbYRotatePixmap(pPrivWin->pRotatedBackground, + pWin->drawable.y - pPrivWin->oldRotate.y); + setxy = 1; + } + + if (!pWin->borderIsPixel && pPrivWin->fastBorder) + { + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + cfbXRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.x - pPrivWin->oldRotate.x); + cfbYRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.y - pPrivWin->oldRotate.y); + setxy = 1; + } + if (setxy) + { + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } + return (TRUE); +} + +/*ARGSUSED*/ +Bool +cfbUnmapWindow(pWindow) + WindowPtr pWindow; +{ + return (TRUE); +} + +/* UNCLEAN! + this code calls the bitblt helper code directly. + + cfbCopyWindow copies only the parts of the destination that are +visible in the source. +*/ + + +void +cfbCopyWindow(pWin, ptOldOrg, prgnSrc) + WindowPtr pWin; + DDXPointRec ptOldOrg; + RegionPtr prgnSrc; +{ + DDXPointPtr pptSrc; + register DDXPointPtr ppt; + RegionRec rgnDst; + register BoxPtr pbox; + register int dx, dy; + register int i, nbox; + WindowPtr pwinRoot; + + pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; + + REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); + REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + + pbox = REGION_RECTS(&rgnDst); + nbox = REGION_NUM_RECTS(&rgnDst); + if(!nbox || !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) + { + REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); + return; + } + ppt = pptSrc; + + for (i = nbox; --i >= 0; ppt++, pbox++) + { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + cfbDoBitbltCopy((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, + GXcopy, &rgnDst, pptSrc, ~0L); + DEALLOCATE_LOCAL(pptSrc); + REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); +} + + + +/* swap in correct PaintWindow* routine. If we can use a fast output +routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy +of it in devPrivates[cfbWindowPrivateIndex].ptr. +*/ +Bool +cfbChangeWindowAttributes(pWin, mask) + WindowPtr pWin; + unsigned long mask; +{ + register unsigned long index; + register cfbPrivWin *pPrivWin; + int width; + WindowPtr pBgWin; + + pPrivWin = cfbGetWindowPrivate(pWin); + + /* + * When background state changes from ParentRelative and + * we had previously rotated the fast border pixmap to match + * the parent relative origin, rerotate to match window + */ + if (mask & (CWBackPixmap | CWBackPixel) && + pWin->backgroundState != ParentRelative && + pPrivWin->fastBorder && + (pPrivWin->oldRotate.x != pWin->drawable.x || + pPrivWin->oldRotate.y != pWin->drawable.y)) + { + cfbXRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.x - pPrivWin->oldRotate.x); + cfbYRotatePixmap(pPrivWin->pRotatedBorder, + pWin->drawable.y - pPrivWin->oldRotate.y); + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } + while(mask) + { + index = lowbit (mask); + mask &= ~index; + switch(index) + { + case CWBackPixmap: + if (pWin->backgroundState == None) + { + pPrivWin->fastBackground = FALSE; + } + else if (pWin->backgroundState == ParentRelative) + { + pPrivWin->fastBackground = FALSE; + /* Rotate border to match parent origin */ + if (pPrivWin->pRotatedBorder) { + for (pBgWin = pWin->parent; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + cfbXRotatePixmap(pPrivWin->pRotatedBorder, + pBgWin->drawable.x - pPrivWin->oldRotate.x); + cfbYRotatePixmap(pPrivWin->pRotatedBorder, + pBgWin->drawable.y - pPrivWin->oldRotate.y); + pPrivWin->oldRotate.x = pBgWin->drawable.x; + pPrivWin->oldRotate.y = pBgWin->drawable.y; + } + } + else if (((width = (pWin->background.pixmap->drawable.width * PSZ)) + <= PGSZ) && !(width & (width - 1))) + { + cfbCopyRotatePixmap(pWin->background.pixmap, + &pPrivWin->pRotatedBackground, + pWin->drawable.x, + pWin->drawable.y); + if (pPrivWin->pRotatedBackground) + { + pPrivWin->fastBackground = TRUE; + pPrivWin->oldRotate.x = pWin->drawable.x; + pPrivWin->oldRotate.y = pWin->drawable.y; + } + else + { + pPrivWin->fastBackground = FALSE; + } + } + else + { + pPrivWin->fastBackground = FALSE; + } + break; + + case CWBackPixel: + pPrivWin->fastBackground = FALSE; + break; + + case CWBorderPixmap: + if (((width = (pWin->border.pixmap->drawable.width * PSZ)) <= PGSZ) && + !(width & (width - 1))) + { + for (pBgWin = pWin; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + cfbCopyRotatePixmap(pWin->border.pixmap, + &pPrivWin->pRotatedBorder, + pBgWin->drawable.x, + pBgWin->drawable.y); + if (pPrivWin->pRotatedBorder) + { + pPrivWin->fastBorder = TRUE; + pPrivWin->oldRotate.x = pBgWin->drawable.x; + pPrivWin->oldRotate.y = pBgWin->drawable.y; + } + else + { + pPrivWin->fastBorder = FALSE; + } + } + else + { + pPrivWin->fastBorder = FALSE; + } + break; + case CWBorderPixel: + pPrivWin->fastBorder = FALSE; + break; + } + } + return (TRUE); +} + diff --git a/cfb/cfbzerarc.c b/cfb/cfbzerarc.c new file mode 100644 index 000000000..37b7023d5 --- /dev/null +++ b/cfb/cfbzerarc.c @@ -0,0 +1,218 @@ +/************************************************************ + +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +/* $Xorg: cfbzerarc.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */ + +/* Derived from: + * "Algorithm for drawing ellipses or hyperbolae with a digital plotter" + * by M. L. V. Pitteway + * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289 + */ + +#include "X.h" +#include "Xprotostr.h" +#include "miscstruct.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "cfb.h" +#include "cfbmskbits.h" +#include "mizerarc.h" +#include "cfbrrop.h" +#include "mi.h" + +#ifdef PIXEL_ADDR + +static void +RROP_NAME(cfbZeroArcSS8) (pDraw, pGC, arc) + DrawablePtr pDraw; + GCPtr pGC; + xArc *arc; +{ + miZeroArcRec info; + Bool do360; + register int x; + PixelType *addrp; + register PixelType *yorgp, *yorgop; + RROP_DECLARE + register int yoffset; + int npwidth, dyoffset; + register int y, a, b, d, mask; + register int k1, k3, dx, dy; + + cfbGetPixelWidthAndPointer(pDraw,npwidth, addrp) + + RROP_FETCH_GC (pGC); + do360 = miZeroArcSetup(arc, &info, TRUE); + yorgp = addrp + ((info.yorg + pDraw->y) * npwidth); + yorgop = addrp + ((info.yorgo + pDraw->y) * npwidth); + info.xorg += pDraw->x; + info.xorgo += pDraw->x; + MIARCSETUP(); + yoffset = y ? npwidth : 0; + dyoffset = 0; + mask = info.initialMask; + if (!(arc->width & 1)) + { + if (mask & 2) + RROP_SOLID((yorgp + info.xorgo)); + if (mask & 8) + RROP_SOLID((yorgop + info.xorgo)); + } + if (!info.end.x || !info.end.y) + { + mask = info.end.mask; + info.end = info.altend; + } + if (do360 && (arc->width == arc->height) && !(arc->width & 1)) + { + register int xoffset = npwidth; + PixelType *yorghb = yorgp + (info.h * npwidth) + info.xorg; + PixelType *yorgohb = yorghb - info.h; + + yorgp += info.xorg; + yorgop += info.xorg; + yorghb += info.h; + while (1) + { + RROP_SOLID(yorgp + yoffset + x); + RROP_SOLID(yorgp + yoffset - x); + RROP_SOLID(yorgop - yoffset - x); + RROP_SOLID(yorgop - yoffset + x); + if (a < 0) + break; + RROP_SOLID(yorghb - xoffset - y); + RROP_SOLID(yorgohb - xoffset + y); + RROP_SOLID(yorgohb + xoffset + y); + RROP_SOLID(yorghb + xoffset - y); + xoffset += npwidth; + MIARCCIRCLESTEP(yoffset += npwidth;); + } + yorgp -= info.xorg; + yorgop -= info.xorg; + x = info.w; + yoffset = info.h * npwidth; + } + else if (do360) + { + while (y < info.h || x < info.w) + { + MIARCOCTANTSHIFT(dyoffset = npwidth;); + RROP_SOLID(yorgp + yoffset + info.xorg + x); + RROP_SOLID(yorgp + yoffset + info.xorgo - x); + RROP_SOLID(yorgop - yoffset + info.xorgo - x); + RROP_SOLID(yorgop - yoffset + info.xorg + x); + MIARCSTEP(yoffset += dyoffset;, yoffset += npwidth;); + } + } + else + { + while (y < info.h || x < info.w) + { + MIARCOCTANTSHIFT(dyoffset = npwidth;); + if ((x == info.start.x) || (y == info.start.y)) + { + mask = info.start.mask; + info.start = info.altstart; + } + if (mask & 1) + RROP_SOLID(yorgp + yoffset + info.xorg + x); + if (mask & 2) + RROP_SOLID(yorgp + yoffset + info.xorgo - x); + if (mask & 4) + RROP_SOLID(yorgop - yoffset + info.xorgo - x); + if (mask & 8) + RROP_SOLID(yorgop - yoffset + info.xorg + x); + if ((x == info.end.x) || (y == info.end.y)) + { + mask = info.end.mask; + info.end = info.altend; + } + MIARCSTEP(yoffset += dyoffset;, yoffset += npwidth;); + } + } + if ((x == info.start.x) || (y == info.start.y)) + mask = info.start.mask; + if (mask & 1) + RROP_SOLID(yorgp + yoffset + info.xorg + x); + if (mask & 4) + RROP_SOLID(yorgop - yoffset + info.xorgo - x); + if (arc->height & 1) + { + if (mask & 2) + RROP_SOLID(yorgp + yoffset + info.xorgo - x); + if (mask & 8) + RROP_SOLID(yorgop - yoffset + info.xorg + x); + } +} + +void +RROP_NAME (cfbZeroPolyArcSS8) (pDraw, pGC, narcs, parcs) + register DrawablePtr pDraw; + GCPtr pGC; + int narcs; + xArc *parcs; +{ + register xArc *arc; + register int i; + BoxRec box; + int x2, y2; + RegionPtr cclip; + + cclip = cfbGetCompositeClip(pGC); + for (arc = parcs, i = narcs; --i >= 0; arc++) + { + if (miCanZeroArc(arc)) + { + box.x1 = arc->x + pDraw->x; + box.y1 = arc->y + pDraw->y; + /* + * Because box.x2 and box.y2 get truncated to 16 bits, and the + * RECT_IN_REGION test treats the resulting number as a signed + * integer, the RECT_IN_REGION test alone can go the wrong way. + * This can result in a server crash because the rendering + * routines in this file deal directly with cpu addresses + * of pixels to be stored, and do not clip or otherwise check + * that all such addresses are within their respective pixmaps. + * So we only allow the RECT_IN_REGION test to be used for + * values that can be expressed correctly in a signed short. + */ + x2 = box.x1 + (int)arc->width + 1; + box.x2 = x2; + y2 = box.y1 + (int)arc->height + 1; + box.y2 = y2; + if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) && + (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) + RROP_NAME (cfbZeroArcSS8) (pDraw, pGC, arc); + else + miZeroPolyArc(pDraw, pGC, 1, arc); + } + else + miPolyArc(pDraw, pGC, 1, arc); + } +} + +#endif diff --git a/cfb/stip68kgnu.h b/cfb/stip68kgnu.h new file mode 100644 index 000000000..9b2c7a1b3 --- /dev/null +++ b/cfb/stip68kgnu.h @@ -0,0 +1,128 @@ +/* + * $Xorg: stip68kgnu.h,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * Stipple stack macro for 68k GCC + * + * Note - this macro can nott describe the full extent of the + * modifications made to the arguments (GCC does not allow enough + * arguments to __asm statements). Therefore, it is possible + * (though unlikely) that future magic versions of GCC may + * miscompile this somehow. In particular, (stipple) is modified + * by the macro, yet not listed as an output value. + */ + +#define STIPPLE(addr,stipple,value,width,count,shift) \ + __asm volatile ( \ + "subqw #1,%1\n\ + lea 0f,a1\n\ + movew #28,d2\n\ + addl %7,d2\n\ + movew #28,d3\n\ + subql #4,%7\n\ + negl %7\n\ +1:\n\ + movel %0,a0\n\ + addl %5,%0\n\ + movel %3@+,d1\n\ + beq 3f\n\ + movel d1,d0\n\ + lsrl d2,d0\n\ + lsll #5,d0\n\ + lsll %7,d1\n\ + jmp a1@(d0:l)\n\ +2:\n\ + addl #4,a0\n\ + movel d1,d0\n\ + lsrl d3,d0\n\ + lsll #5,d0\n\ + lsll #4,d1\n\ + jmp a1@(d0:l)\n\ +0:\n\ + bne 2b ; dbra %1,1b ; bra 4f\n\ + . = 0b + 0x20\n\ + moveb %4,a0@(3)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f\n\ + . = 0b + 0x40\n\ + moveb %4,a0@(2)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f\n\ + . = 0b + 0x60\n\ + movew %4,a0@(2)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f\n\ + . = 0b + 0x80\n\ + moveb %4,a0@(1)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0xa0\n\ + moveb %4,a0@(3) ; moveb %4,a0@(1)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0xc0\n\ + movew %4,a0@(1)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0xe0\n\ + movew %4,a0@(2) ; moveb %4,a0@(1)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x100\n\ + moveb %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x120\n\ + moveb %4,a0@(3) ; moveb %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x140\n\ + moveb %4,a0@(2) ; moveb %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x160\n\ + movew %4,a0@(2) ; moveb %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x180\n\ + movew %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x1a0\n\ + moveb %4,a0@(3) ; movew %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x1c0\n\ + moveb %4,a0@(2) ; movew %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; dbra %1,1b ; bra 4f ;\n\ + . = 0b + 0x1e0\n\ + movel %4,a0@(0)\n\ + andl d1,d1 ; bne 2b ; \n\ +3: dbra %1,1b ; \n\ +4:\n"\ + : "=a" (addr), /* %0 */ \ + "=d" (count) /* %1 */ \ + : "0" (addr), /* %2 */ \ + "a" (stipple), /* %3 */ \ + "d" (value), /* %4 */ \ + "a" (width), /* %5 */ \ + "1" (count), /* %6 */ \ + "d" (shift) /* %7 */ \ + : /* ctemp */ "d0", \ + /* c */ "d1", \ + /* lshift */ "d2", \ + /* rshift */ "d3", \ + /* atemp */ "a0", \ + /* case */ "a1") diff --git a/cfb/stipmips.s b/cfb/stipmips.s new file mode 100644 index 000000000..c42d9b5ae --- /dev/null +++ b/cfb/stipmips.s @@ -0,0 +1,281 @@ +/* + * $Xorg: stipmips.s,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * MIPS assembly code for optimized text rendering. + * + * Other stippling could be done in assembly, but the payoff is + * not nearly as large. Mostly because large areas are heavily + * optimized already. + */ + +#ifdef MIPSEL +# define BitsR sll +# define BitsL srl +# define BO(o) o +# define HO(o) o +# define WO(o) o +# define FourBits(dest,bits) and dest, bits, 0xf +#else +# define BitsR srl +# define BitsL sll +# define BO(o) 3-o +# define HO(o) 2-o +# define WO(o) o +# define FourBits(dest,bits) srl dest, bits, 28 +#endif + +/* reordering instructions would be fatal here */ + .set noreorder + + +/* + * cfbStippleStack(addr, stipple, value, stride, Count, Shift) + * 4 5 6 7 16(sp) 20(sp) + * + * Apply successive 32-bit stipples starting at addr, addr+stride, ... + * + * Used for text rendering, but only when no data could be lost + * when the stipple is shifted left by Shift bits + */ +/* arguments */ +#define addr $4 +#define stipple $5 +#define value $6 +#define stride $7 +#define Count 16($sp) +#define Shift 20($sp) + +/* local variables */ +#define count $14 +#define shift $13 +#define atemp $12 +#define bits $11 +#define lshift $9 +#define sbase $8 +#define stemp $2 + +#define CASE_SIZE 5 /* case blocks are 2^5 bytes each */ +#define CASE_MASK 0x1e0 /* first case mask */ + +#define ForEachLine $200 +#define NextLine $201 +#define NextLine1 $202 +#define CaseBegin $203 +#define ForEachBits $204 +#define ForEachBits1 $205 +#define NextBits $206 + +#ifdef TETEXT +#define cfbStippleStack cfbStippleStackTE +#endif + + .globl cfbStippleStack + .ent cfbStippleStack 2 +cfbStippleStack: + .frame $sp, 0, $31 + lw count, Count /* fetch stack params */ + la sbase,CaseBegin /* load up switch table */ + lw shift, Shift + li lshift, 4 /* compute offset within */ + subu lshift, lshift, shift /* stipple of remaining bits */ +#ifdef MIPSEL + addu shift, shift, CASE_SIZE /* first shift for LSB */ +#else + addu shift, shift, 28-CASE_SIZE /* first shift for MSB */ +#endif + /* do ... while (--count > 0); */ +ForEachLine: + lw bits, 0(stipple) /* get stipple bits */ + move atemp, addr /* set up for this line */ +#ifdef TETEXT + /* Terminal emulator fonts are expanded and have many 0 rows */ + beqz bits, NextLine /* skip out early on 0 */ +#endif + addu addr, addr, stride /* step for the loop */ + BitsR stemp, bits, shift /* get first bits */ + and stemp, stemp, CASE_MASK /* compute first branch */ + addu stemp, stemp, sbase /* ... */ + j stemp /* ... */ + BitsL bits, bits, lshift /* set remaining bits */ + +ForEachBits: + addu atemp, atemp, 4 +ForEachBits1: + FourBits(stemp, bits) /* compute jump for */ + sll stemp, stemp, CASE_SIZE /* next four bits */ + addu stemp, stemp, sbase /* ... */ + j stemp /* ... */ + BitsL bits, bits, 4 /* step for remaining bits */ +CaseBegin: + bnez bits, ForEachBits1 /* 0 */ + addu atemp, atemp, 4 +NextLine: + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* 1 */ + sb value, BO(0)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* 2 */ + sb value, BO(1)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* 3 */ + sh value, HO(0)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* 4 */ + sb value, BO(2)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + sb value, BO(0)(atemp) /* 5 */ + bnez bits, ForEachBits + sb value, BO(2)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + sb value, BO(1)(atemp) /* 6 */ + bnez bits, ForEachBits + sb value, BO(2)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + bnez bits, ForEachBits /* 7 */ + swl value, BO(2)(atemp) /* untested on MSB */ + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* 8 */ + sb value, BO(3)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + sb value, BO(0)(atemp) /* 9 */ + bnez bits, ForEachBits + sb value, BO(3)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + sb value, BO(1)(atemp) /* a */ + bnez bits, ForEachBits + sb value, BO(3)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + sh value, HO(0)(atemp) /* b */ + bnez bits, ForEachBits + sb value, BO(3)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + bnez bits, ForEachBits /* c */ + sh value, HO(2)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + sb value, BO(0)(atemp) /* d */ + bnez bits, ForEachBits + sh value, HO(2)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + + bnez bits, ForEachBits /* e */ + swr value, BO(1)(atemp) /* untested on MSB */ + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + bnez bits, ForEachBits /* f */ + sw value, WO(0)(atemp) + addu count, count, -1 + bnez count, ForEachLine + addu stipple, stipple, 4 + j $31 + nop + nop + + .end cfbStippleStack diff --git a/cfb/stipsparc.s b/cfb/stipsparc.s new file mode 100644 index 000000000..2c417599e --- /dev/null +++ b/cfb/stipsparc.s @@ -0,0 +1,280 @@ +/* + * $Xorg: stipsparc.s,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * SPARC assembly code for optimized text rendering. + * + * Other stippling could be done in assembly, but the payoff is + * not nearly as large. Mostly because large areas are heavily + * optimized already. + */ + +/* not that I expect to ever see an LSB SPARC, but ... */ +#ifdef LITTLE_ENDIAN +# define BitsR sll +# define BitsL srl +# define BO(o) o +# define HO(o) o +# define WO(o) o +# define FourBits(dest,bits) and bits, 0xf, dest +#else +# define BitsR srl +# define BitsL sll +# define BO(o) 3-o +# define HO(o) 2-o +# define WO(o) o +# define FourBits(dest,bits) srl bits, 28, dest +#endif + +/* + * cfbStippleStack(addr, stipple, value, stride, Count, Shift) + * 4 5 6 7 16(sp) 20(sp) + * + * Apply successive 32-bit stipples starting at addr, addr+stride, ... + * + * Used for text rendering, but only when no data could be lost + * when the stipple is shifted left by Shift bits + */ +/* arguments */ +#define addr %i0 +#define stipple %i1 +#define value %i2 +#define stride %i3 +#define count %i4 +#define shift %i5 + +/* local variables */ +#define atemp %l0 +#define bits %l1 +#define lshift %l2 +#define sbase %l3 +#define stemp %l4 + +#define CASE_SIZE 5 /* case blocks are 2^5 bytes each */ +#define CASE_MASK 0x1e0 /* first case mask */ + +#define ForEachLine LY1 +#define NextLine LY2 +#define CaseBegin LY3 +#define ForEachBits LY4 +#define NextBits LY5 + +#ifdef SVR4 +#ifdef TETEXT +#define _cfbStippleStack cfbStippleStackTE +#else +#define _cfbStippleStack cfbStippleStack +#endif +#else +#ifdef TETEXT +#define _cfbStippleStack _cfbStippleStackTE +#endif +#endif + .seg "text" + .proc 16 + .globl _cfbStippleStack +_cfbStippleStack: + save %sp,-64,%sp + sethi %hi(CaseBegin),sbase /* load up switch table */ + or sbase,%lo(CaseBegin),sbase + + mov 4,lshift /* compute offset within */ + sub lshift, shift, lshift /* stipple of remaining bits */ +#ifdef LITTLE_ENDIAN + inc CASE_SIZE, shift /* first shift for LSB */ +#else + inc 28-CASE_SIZE, shift /* first shift for MSB */ +#endif + /* do ... while (--count > 0); */ +ForEachLine: + ld [stipple],bits /* get stipple bits */ + mov addr,atemp /* set up for this line */ +#ifdef TETEXT + /* Terminal emulator fonts are expanded and have many 0 rows */ + tst bits + bz NextLine /* skip out early on 0 */ +#endif + add addr, stride, addr /* step for the loop */ + BitsR bits, shift, stemp /* get first bits */ + and stemp, CASE_MASK, stemp /* compute first jump */ + BitsL bits, lshift, bits /* set remaining bits */ + jmp sbase+stemp /* ... */ + tst bits + +ForEachBits: + inc 4, atemp +ForEachBits1: + FourBits(stemp, bits) /* compute jump for */ + sll stemp, CASE_SIZE, stemp /* these four bits */ + BitsL bits, 4, bits /* step for remaining bits */ + jmp sbase+stemp /* jump */ + tst bits +CaseBegin: + bnz,a ForEachBits1 /* 0 */ + inc 4, atemp +NextLine: + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 1 */ + stb value, [atemp+BO(0)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 2 */ + stb value, [atemp+BO(1)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 3 */ + sth value, [atemp+HO(0)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 4 */ + stb value, [atemp+BO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + stb value, [atemp+BO(0)] /* 5 */ + bnz ForEachBits + stb value, [atemp+BO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + stb value, [atemp+BO(1)] /* 6 */ + bnz ForEachBits + stb value, [atemp+BO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + sth value, [atemp+HO(0)] /* 7 */ + bnz ForEachBits + stb value, [atemp+BO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + bnz ForEachBits /* 8 */ + stb value, [atemp+BO(3)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + stb value, [atemp+BO(0)] /* 9 */ + bnz ForEachBits + stb value, [atemp+BO(3)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + stb value, [atemp+BO(1)] /* a */ + bnz ForEachBits + stb value, [atemp+BO(3)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + sth value, [atemp+HO(0)] /* b */ + bnz ForEachBits + stb value, [atemp+BO(3)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + bnz ForEachBits /* c */ + sth value, [atemp+HO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + stb value, [atemp+BO(0)] /* d */ + bnz ForEachBits + sth value, [atemp+HO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + stb value, [atemp+BO(1)] /* e */ + bnz ForEachBits + sth value, [atemp+HO(2)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + bnz ForEachBits /* f */ + st value, [atemp+WO(0)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore diff --git a/cfb/stipsprc32.s b/cfb/stipsprc32.s new file mode 100644 index 000000000..ce2b949b2 --- /dev/null +++ b/cfb/stipsprc32.s @@ -0,0 +1,281 @@ +/* + * $Xorg: stipsprc32.s,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ + * +Copyright 1990, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * SPARC assembly code for optimized text rendering. + * + * Other stippling could be done in assembly, but the payoff is + * not nearly as large. Mostly because large areas are heavily + * optimized already. + */ + +/* not that I expect to ever see an LSB SPARC, but ... */ +#ifdef LITTLE_ENDIAN +# define BitsR sll +# define BitsL srl +# define WO(o) 3-o +# define FourBits(dest,bits) and bits, 0xf, dest +#else +# define BitsR srl +# define BitsL sll +# define WO(o) o +# define FourBits(dest,bits) srl bits, 28, dest +#endif + +/* + * cfb32StippleStack(addr, stipple, value, stride, Count, Shift) + * 4 5 6 7 16(sp) 20(sp) + * + * Apply successive 32-bit stipples starting at addr, addr+stride, ... + * + * Used for text rendering, but only when no data could be lost + * when the stipple is shifted left by Shift bits + */ +/* arguments */ +#define addr %i0 +#define stipple %i1 +#define value %i2 +#define stride %i3 +#define count %i4 +#define shift %i5 + +/* local variables */ +#define atemp %l0 +#define bits %l1 +#define lshift %l2 +#define sbase %l3 +#define stemp %l4 + +#define CASE_SIZE 5 /* case blocks are 2^5 bytes each */ +#define CASE_MASK 0x1e0 /* first case mask */ + +#define ForEachLine LY1 +#define NextLine LY2 +#define CaseBegin LY3 +#define ForEachBits LY4 +#define NextBits LY5 + +#ifdef SVR4 +#ifdef TETEXT +#define _cfb32StippleStack cfb32StippleStackTE +#else +#define _cfb32StippleStack cfb32StippleStack +#endif +#else +#ifdef TETEXT +#define _cfb32StippleStack _cfb32StippleStackTE +#endif +#endif + + .seg "text" + .proc 16 + .globl _cfb32StippleStack +_cfb32StippleStack: + save %sp,-64,%sp + sethi %hi(CaseBegin),sbase /* load up switch table */ + or sbase,%lo(CaseBegin),sbase + + mov 4,lshift /* compute offset within */ + sub lshift, shift, lshift /* stipple of remaining bits */ +#ifdef LITTLE_ENDIAN + inc CASE_SIZE, shift /* first shift for LSB */ +#else + inc 28-CASE_SIZE, shift /* first shift for MSB */ +#endif + /* do ... while (--count > 0); */ +ForEachLine: + ld [stipple],bits /* get stipple bits */ + mov addr,atemp /* set up for this line */ +#ifdef TETEXT + /* Terminal emulator fonts are expanded and have many 0 rows */ + tst bits + bz NextLine /* skip out early on 0 */ +#endif + add addr, stride, addr /* step for the loop */ + BitsR bits, shift, stemp /* get first bits */ + and stemp, CASE_MASK, stemp /* compute first jump */ + BitsL bits, lshift, bits /* set remaining bits */ + jmp sbase+stemp /* ... */ + tst bits + +ForEachBits: + inc 16, atemp +ForEachBits1: + FourBits(stemp, bits) /* compute jump for */ + sll stemp, CASE_SIZE, stemp /* these four bits */ + BitsL bits, 4, bits /* step for remaining bits */ + jmp sbase+stemp /* jump */ + tst bits +CaseBegin: + bnz,a ForEachBits1 /* 0 */ + inc 16, atemp +NextLine: + deccc 1, count +NextLine1: + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 1 */ + st value, [atemp+WO(12)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + bnz ForEachBits /* 2 */ + st value, [atemp+WO(8)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + st value, [atemp+WO(8)] /* 3 */ + bnz ForEachBits + st value, [atemp+WO(12)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + bnz ForEachBits /* 4 */ + st value, [atemp+WO(4)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + st value, [atemp+WO(4)] /* 5 */ + bnz ForEachBits + st value, [atemp+WO(12)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + st value, [atemp+WO(4)] /* 6 */ + bnz ForEachBits + st value, [atemp+WO(8)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + st value, [atemp+WO(4)] /* 7 */ + st value, [atemp+WO(8)] + bnz ForEachBits + st value, [atemp+WO(12)] + b NextLine1 + deccc 1, count + nop + nop + + bnz ForEachBits /* 8 */ + st value, [atemp+WO(0)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + nop + + st value, [atemp+WO(0)] /* 9 */ + bnz ForEachBits + st value, [atemp+WO(12)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + st value, [atemp+WO(0)] /* a */ + bnz ForEachBits + st value, [atemp+WO(8)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + st value, [atemp+WO(0)] /* b */ + st value, [atemp+WO(8)] + bnz ForEachBits + st value, [atemp+WO(12)] + b NextLine1 + deccc 1, count + nop + nop + + st value, [atemp+WO(0)] /* c */ + bnz ForEachBits + st value, [atemp+WO(4)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore + + st value, [atemp+WO(0)] /* d */ + st value, [atemp+WO(4)] + bnz ForEachBits + st value, [atemp+WO(12)] + b NextLine1 + deccc 1, count + nop + nop + + st value, [atemp+WO(0)] /* e */ + st value, [atemp+WO(4)] + bnz ForEachBits + st value, [atemp+WO(8)] + b NextLine1 + deccc 1, count + nop + nop + + st value, [atemp+WO(0)] /* f */ + st value, [atemp+WO(4)] + st value, [atemp+WO(8)] + bnz ForEachBits + st value, [atemp+WO(12)] + deccc 1, count + bnz,a ForEachLine + inc 4, stipple + ret + restore |