/***********************************************************
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/
/* Monochrome Frame Buffer definitions 
   written by drewry, september 1986
*/
#include "pixmap.h"
#include "region.h"
#include "gc.h"
#include "colormap.h"
#include "miscstruct.h"

extern int InverseAlu[];

extern Bool mfbScreenInit();
extern void mfbQueryBestSize();
extern Bool mfbCreateWindow();
extern Bool mfbPositionWindow();
extern Bool mfbChangeWindowAttributes();
extern Bool mfbMapWindow();
extern Bool mfbUnmapWindow();
extern Bool mfbDestroyWindow();

extern Bool mfbRealizeFont();
extern Bool mfbUnrealizeFont();
extern Bool mfbRealizeCursor();
extern Bool mfbUnrealizeCursor();
extern Bool mfbScreenSaver();
extern Bool mfbCreateGC();

extern PixmapPtr mfbCreatePixmap();
extern Bool mfbDestroyPixmap();

extern void mfbCopyWindow();

/* window painters */
extern void mfbPaintWindowNone();
extern void mfbPaintWindowPR();
extern void mfbPaintWindowSolid();
extern void mfbPaintWindow32();

/* rectangle painters */
extern void mfbSolidWhiteArea();
extern void mfbStippleWhiteArea();
extern void mfbSolidBlackArea();
extern void mfbStippleBlackArea();
extern void mfbSolidInvertArea();
extern void mfbStippleInvertArea();
extern void mfbTileArea32();


extern void mfbPolyFillRect();
extern void miPolyFillRect();
extern void miPolyFillArc();
extern void mfbCopyArea();
extern void mfbPolyPoint();
extern void mfbCopyPlane();

extern void mfbDestroyGC();
extern void mfbValidateGC();
extern void mfbCopyGCDest();

extern void mfbSetSpans();
extern unsigned int *mfbGetSpans();
extern void mfbWhiteSolidFS();
extern void mfbBlackSolidFS();
extern void mfbInvertSolidFS();
extern void mfbWhiteStippleFS();
extern void mfbBlackStippleFS();
extern void mfbInvertStippleFS();
extern void mfbTileFS();
extern void mfbUnnaturalTileFS();
extern void mfbUnnaturalStippleFS();

extern void mfbGetImage();
extern void mfbPutImage();

extern void mfbLineSS();	/* solid single-pixel wide line */
				/* calls mfb{Bres|Horz|Vert}S() */
extern void mfbDashLine();	/* dashed zero-width line */
extern void miNotMiter();
extern void miMiter();
extern void miWideLine();
extern void miWideDash();
extern void miChangeClip();
extern void miDestroyClip();
extern void mfbImageText8();
extern void mfbImageText16();
extern int mfbPolyText16();
extern int mfbPolyText8();
extern void mfbTileBox();
extern void mfbPaintBox();
extern void mfbStippleBox();
extern PixmapPtr mfbCopyPixmap();
extern RegionPtr mfbPixmapToRegion();
extern RegionPtr miRectsToRegion();
extern void  miPolyArc();
extern void  miFillPolyArc();
extern void mfbPushPixels();

/* text for glyphs <= 32 bits wide */
extern void mfbImageGlyphBltWhite();
extern void mfbImageGlyphBltBlack();
extern void mfbPolyGlyphBltWhite();
extern void mfbPolyGlyphBltBlack();
extern void mfbPolyGlyphBltInvert();

/* text for terminal emulator text */
extern void mfbTEGlyphBlt();

extern void mfbChangeClip();
extern void mfbDestroyClip();
extern int mfbListInstalledColormaps();

extern ColormapPtr mfbGetStaticColormap();
extern void mfbResolveColor();

/*
   private filed of pixmap
   pixmap.devPrivate = (unsigned int *)pointer←to←bits
   pixmap.devKind = width←of←pixmap←in←bytes
*/

/* private field of GC */
typedef struct {
    short	rop;		/* reduction of rasterop to 1 of 3 */
    short	ropOpStip;	/* rop for opaque stipple */
    short	fExpose;	/* callexposure handling ? */
    short	freeCompClip;
    PixmapPtr	pRotatedTile;	/* tile/stipple  rotated to align with window */
    PixmapPtr	pRotatedStipple;	/* and using offsets */
    RegionPtr	pAbsClientRegion; /* client region in screen coords */
    RegionPtr	pCompositeClip; /* FREE←CC or REPLACE←CC */
    void 	(* FillArea)();
    PixmapPtr   *ppPixmap;	/* points to the pixmapPtr to
				   use for tiles and stipples */
    } mfbPrivGC;
typedef mfbPrivGC	*mfbPrivGCPtr;

/* freeCompositeClip values */
#define REPLACE←CC	0		/* compsite clip is a copy of a
					pointer, so it doesn't need to 
					be freed; just overwrite it.
					this happens if there is no
					client clip and the gc is
					clipped by children 
					*/
#define FREE←CC		1		/* composite clip is a real
					   region that we need to free
					*/

/* private field of window */
typedef struct {
    int		fastBorder;	/* non-zero if border is 32 bits wide */
    int		fastBackground;
    DDXPointRec	oldRotate;
    PixmapPtr	pRotatedBackground;
    PixmapPtr	pRotatedBorder;
    } mfbPrivWin;

/* precomputed information about each glyph for GlyphBlt code.
   this saves recalculating the per glyph information for each
box.
*/
typedef struct ←pos{
    int xpos;		/* xposition of glyph's origin */
    int xchar;		/* x position mod 32 */
    int leftEdge;
    int rightEdge;
    int topEdge;
    int bottomEdge;
    unsigned int *pdstBase;	/* longword with character origin */
    int widthGlyph;	/* width in bytes of this glyph */
} TEXTPOS;

/* reduced raster ops for mfb */
#define RROP←BLACK	GXclear
#define RROP←WHITE	GXset
#define RROP←NOP	GXnoop
#define RROP←INVERT	GXinvert

/* out of clip region codes */
#define OUT←LEFT 0x08
#define OUT←RIGHT 0x04
#define OUT←ABOVE 0x02
#define OUT←BELOW 0x01

/* major axis for bresenham's line */
#define X←AXIS	0
#define Y←AXIS	1

/* optimization codes for FONT's devPrivate field */
#define FT←VARPITCH	0
#define FT←SMALLPITCH	1
#define FT←FIXPITCH	2

/* macros for mfbbitblt.c, mfbfillsp.c
   these let the code do one switch on the rop per call, rather
than a switch on the rop per item (span or rectangle.)
*/

#define fnCLEAR(src, dst)	(0)
#define fnAND(src, dst) 	(src & dst)
#define fnANDREVERSE(src, dst)	(src & ~dst)
#define fnCOPY(src, dst)	(src)
#define fnANDINVERTED(src, dst)	(~src & dst)
#define fnNOOP(src, dst)	(dst)
#define fnXOR(src, dst)		(src ↑ dst)
#define fnOR(src, dst)		(src | dst)
#define fnNOR(src, dst)		(~(src | dst))
#define fnEQUIV(src, dst)	(~src ↑ dst)
#define fnINVERT(src, dst)	(~dst)
#define fnORREVERSE(src, dst)	(src | ~dst)
#define fnCOPYINVERTED(src, dst)(~src)
#define fnORINVERTED(src, dst)	(~src | dst)
#define fnNAND(src, dst)	(~(src & dst))
#define fnSET(src, dst)		(~0)

/* Binary search to figure out what to do for the raster op.  It may
 * do 5 comparisons, but at least it does no function calls 
 * Special cases copy because it's so frequent 
 */
#define DoRop(alu, src, dst) \
( ((alu) == GXcopy) ? (src) : \
    (((alu) >= GXnor) ? \
     (((alu) >= GXcopyInverted) ? \
       (((alu) >= GXnand) ? \
         (((alu) == GXnand) ? ~((src) & (dst)) : ~0) : \
         (((alu) == GXcopyInverted) ? ~(src) : (~(src) | (dst)))) : \
       (((alu) >= GXinvert) ? \
	 (((alu) == GXinvert) ? ~(dst) : ((src) | ~(dst))) : \
	 (((alu) == GXnor) ? ~((src) | (dst)) : (~(src) ↑ (dst)))) ) : \
     (((alu) >= GXandInverted) ? \
       (((alu) >= GXxor) ? \
	 (((alu) == GXxor) ? ((src) ↑ (dst)) : ((src) | (dst))) : \
	 (((alu) == GXnoop) ? (dst) : (~(src) & (dst)))) : \
       (((alu) >= GXandReverse) ? \
	 (((alu) == GXandReverse) ? ((src) & ~(dst)) : (src)) : \
	 (((alu) == GXand) ? ((src) & (dst)) : 0)))  ) )


#define DoRRop(alu, src, dst) \
(((alu) == RROP←BLACK) ? ((dst) & ~(src)) : \
 ((alu) == RROP←WHITE) ? ((dst) | (src)) : \
 ((alu) == RROP←INVERT) ? ((dst) ↑ (src)) : \
  (dst))