-- multigraphicsdefs.mesa
-- last edited by McCreight, December 16, 1982 5:12 PM

DIRECTORY
BitBltDefs,
InlineDefs;

multiGraphicsDefs: DEFINITIONS IMPORTS BitBltDefs, InlineDefs =
BEGIN
BitmapPtr: TYPE = POINTER TO Bitmap ← NIL;
Bitmap: TYPE = RECORD
[
bank: [0..7], --3 bits for Box (idiotic space optimization)
nWords: [0..1777B],
nBits,nLines: CARDINAL,
nBitsPerPixel: [0..256),
portraitMode: BOOLEAN,
scaleFactor: [0..128),
bits: POINTER TO ARRAY [0..0) OF CARDINAL
];
BoxType: TYPE = {normal,outline,gray};
Box: TYPE = RECORD
[boxBitmap: Bitmap,
savedBits: POINTER TO ARRAY [0..0) OF CARDINAL, --used when moving around
displayBitmap: BitmapPtr,
displayX,displayY: CARDINAL,
displayed: BOOLEAN,--1 bit(i.e.,whether displayX,Y are valid)
savedBank: [0..7], --3 bits
function: BitBltDefs.BBoperation,--2 bits
type: BoxType,--2 bits
gray: [0..256)--8 bits
];

StrikeFontPtr: TYPE = POINTER TO StrikeFont ← NIL;
StrikeFont: TYPE = RECORD
[oneBit,index,fixed: [0..1],
bank: [0..77B],
minCode,maxCode: CARDINAL,
maxWidth: CARDINAL,
strikeBodyWordLength: CARDINAL,
ascent,descent: CARDINAL,
wordsPerScanLine: CARDINAL,
bitmap: POINTER TO ARRAY [0..0) OF CARDINAL,
xInSegment: POINTER TO ARRAY [0..0) OF CARDINAL
];
textMode: TYPE = [0..3];
normal: textMode = 0;
italic: textMode = 1;
bold: textMode=2;
Color: TYPE = CARDINAL;

BitBltGrayPtr: TYPE = POINTER TO ARRAY [0..4) OF CARDINAL;
GrayPatternPtr: TYPE = POINTER TO GrayPattern ← NIL;
GrayPattern: TYPE = ARRAY GrayPatternIndex OF CARDINAL;
GrayPatternIndex: TYPE = CARDINAL[0..6]; -- 0, 1, 2, 3, 0, 1, 2
solid: GrayPattern = ALL[177777B];

BLTBlockPtr: TYPE = POINTER TO BLTBlock ← NIL;
BLTBlock: TYPE = RECORD
[blk: BitBltDefs.BBTable,
next: BLTBlockPtr,
padding: WORD -- to allow for even word boundaries
];
AllocateBLT: PROC RETURNS [bb: BLTBlockPtr];
FreeBLT: PROC [bb: BLTBlockPtr];

MakeLongPointer: PROCEDURE [ptr: POINTER,bank: UNSPECIFIED] RETURNS
[LONG POINTER] = MACHINE CODE {};

SetDefaultBitmap: PROC [width,height: CARDINAL];
KillGraphics: PROC [outputDevice:BitmapPtr←NIL];
SetXMAlloc: PROC [Allocate: PROC [nwords: CARDINAL] RETURNS [LONG POINTER],Free: PROC [LONG POINTER],AllocateFromBank: PROC [nwords: CARDINAL,bank: CARDINAL] RETURNS [LONG POINTER]];
GetXMAlloc: PROC RETURNS [Allocate: PROC [nwords: CARDINAL] RETURNS [LONG POINTER],Free: PROC [LONG POINTER],AllocateFromBank: PROC [nwords: CARDINAL,bank: CARDINAL] RETURNS [LONG POINTER]];

GetDefaultBitmapHandle: PROC RETURNS[BitmapPtr] ;

TurnOnGraphics: PROC [bitsPerPixel: CARDINAL ← 1,portraitMode: BOOLEAN ← TRUE,scalePercent: CARDINAL ← 100] RETURNS [BitmapPtr] ;

InitGrayMaps: PROC;
SetGrayMap: PROC [idx,g0,g1,g2,g3:CARDINAL];

currentGray
: GrayPattern;
SetGrayLevel: PROC [intensity: CARDINAL];
GetGrayBlock: PROC RETURNS [gray0,gray1,gray2,gray3: CARDINAL];

PutPoint
: PROC [x,y: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetPoint[x, y, replace, b]};
ErasePoint: PROC [x,y: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetPoint[x, y, erase, b]};
XorPoint: PROC [x,y: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetPoint[x, y, invert, b]};
SetPoint: PROC [x, y: INTEGER, fn: BitBltDefs.BBoperation, b: BitmapPtr ← NIL];

PutGray
: PROC [x1,y1,x2,y2: INTEGER,b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, paint, @currentGray, b]};
EraseGray: PROC [x1,y1,x2,y2: INTEGER,b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, erase, @currentGray, b]};
XorGray: PROC [x1,y1,x2,y2: INTEGER,b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, invert, @currentGray, b]};
ReplaceGray: PROC [x1,y1,x2,y2: INTEGER,b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, replace, @currentGray, b]};

PutArea
: PROC [x1,y1,x2,y2: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, paint,, b]};
ReplaceArea: PROC [x1,y1,x2,y2: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, replace,, b]};
EraseArea, MaskArea: PROC [x1,y1,x2,y2: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, erase,, b]};
XorArea: PROC [x1,y1,x2,y2: INTEGER, b: BitmapPtr ← NIL] = INLINE
{SetArea[x1, y1, x2, y2, invert,, b]};
SetArea: PROC [x1,y1,x2,y2: INTEGER,fn: BitBltDefs.BBoperation,
gray: GrayPatternPtr ← NIL, b: BitmapPtr ← NIL];

PutText
: PROC [s: STRING,x,y: INTEGER,font: StrikeFontPtr,mode: textMode,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] = INLINE
{nextX ← SetText[s: s, x: x, y: y, fn: paint, font: font, mode: mode, b: b]};
ReplaceText: PROC [s: STRING,x,y: INTEGER,font: StrikeFontPtr,mode: textMode,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] = INLINE
{nextX ← SetText[s: s, x: x, y: y, fn: replace, font: font, mode: mode, b: b]};
EraseText: PROC [s: STRING,x,y: INTEGER,font: StrikeFontPtr,mode: textMode,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] = INLINE
{nextX ← SetText[s: s, x: x, y: y, fn: erase, font: font, mode: mode, b: b]};
XorText: PROC [s: STRING,x,y: INTEGER,font: StrikeFontPtr,mode: textMode,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] = INLINE
{nextX ← SetText[s: s, x: x, y: y, fn: invert, font: font, mode: mode, b: b]};
SetText: PROC [s: STRING, x,y: INTEGER, fn: BitBltDefs.BBoperation,
font: StrikeFontPtr, mode: textMode, strt, end: CARDINAL←0,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] ;

SetStrong
: PROC [so: LONG POINTER, x,y: INTEGER, fn: BitBltDefs.BBoperation,
font: StrikeFontPtr, mode: textMode,strt, end: CARDINAL←0,
b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] ;
MeasureText: PROC [s: STRING,font: StrikeFontPtr,b: BitmapPtr ← NIL] RETURNS [nextX: INTEGER] ;
CharWidth:PROC [c:CHARACTER,font:POINTER TO
multiGraphicsDefs.StrikeFont] RETURNS [INTEGER] ;
GetStrikeHandle: PROC [fontName: STRING] RETURNS [StrikeFontPtr] ;



TurnOnColor
: PROC [bitsPerPixel: CARDINAL ← 1, portraitMode: BOOLEAN ← TRUE,
scalePercent: CARDINAL ← 100, initColor: Color←0] RETURNS [BitmapPtr] ;

SetColorTable: PROC [new: POINTER TO ARRAY [0..0) OF CARDINAL,
outputDevice: BitmapPtr ← NIL] ;

PutColorPoint: PROC [x, y: INTEGER, c: Color ← 0, b: BitmapPtr ← NIL,
cGray: GrayPatternPtr ← NIL] = INLINE
{SetColorPoint[x, y, replace, c, b, cGray]};
XorColorPoint: PROC [x, y: INTEGER, c: Color ← 0, b: BitmapPtr ← NIL,
cGray: GrayPatternPtr ← NIL] = INLINE
{SetColorPoint[x, y, invert, c, b, cGray]};
SetColorPoint: PROC [x, y: INTEGER, fn: BitBltDefs.BBoperation,
c: Color ← 0, b: BitmapPtr ← NIL, cGray: GrayPatternPtr ← NIL] ;

PutColorLine
: PROC [x1,y1,x2,y2: INTEGER, c: Color ← 0, b: BitmapPtr ← NIL,
cGray: GrayPatternPtr ← NIL] = INLINE
{SetColorLine[x1,y1,x2,y2, paint, c, b, cGray]};
ReplaceColorLine: PROC [x1,y1,x2,y2: INTEGER, c: Color ← 0, b: BitmapPtr ← NIL,
cGray: GrayPatternPtr ← NIL] = INLINE
{SetColorLine[x1,y1,x2,y2, replace, c, b, cGray]};
XorColorLine: PROC [x1,y1,x2,y2: INTEGER, c: Color ← 0, b: BitmapPtr ← NIL,
cGray: GrayPatternPtr ← NIL] = INLINE
{SetColorLine[x1,y1,x2,y2, invert, c, b, cGray]};
SetColorLine: PROC [x1,y1,x2,y2: INTEGER, fn: BitBltDefs.BBoperation,
c: Color ← 0, b: BitmapPtr ← NIL, cGray: GrayPatternPtr ← NIL];

PutColorArea
: PROC [x1, y1, x2, y2: INTEGER, c: Color, b: BitmapPtr ← NIL] = INLINE
BEGIN
gray: GrayPattern ← GetColorGray[c];
SetColorArea[x1,y1,x2,y2, paint, @gray,, b];
END;
PutColorTemp: PROC [x1, y1, x2, y2: INTEGER, gray: GrayPattern,
b: BitmapPtr ← NIL] = INLINE
{SetColorArea[x1,y1,x2,y2, paint, @gray,, b]};
EraseColorArea: PROC [x1, y1, x2, y2: INTEGER, c: Color, b: BitmapPtr ← NIL] = INLINE
BEGIN
gray: GrayPattern ← GetColorGray[c];
SetColorArea[x1,y1,x2,y2, erase, @gray,, b];
END;
XorColorArea: PROC [x1, y1, x2, y2: INTEGER, c: Color, b: BitmapPtr ← NIL] = INLINE
BEGIN
gray: GrayPattern ← GetColorGray[c];
SetColorArea[x1,y1,x2,y2, invert, @gray,, b];
END;
ReplaceColorArea: PROC [x1, y1, x2, y2: INTEGER, c: Color, b: BitmapPtr ← NIL] = INLINE
BEGIN
color: GrayPattern ← GetColorGray[c];
IF c<16 THEN -- simple colors, no mask
SetColorArea[x1,y1,x2,y2, replace, @color,, b]
ELSE
BEGIN
mask: GrayPattern ← GetMaskGray[c];
SetColorArea[x1,y1,x2,y2, replace, @color, @mask, b];
END;
END;

DoColorArea
: PROC [x1, y1, x2, y2: INTEGER, fn: BitBltDefs.BBoperation,
slimByOne: BOOLEAN ← FALSE, cGray: GrayPatternPtr,
mGray: GrayPatternPtr ← NIL,
b: BitmapPtr ← NIL] = INLINE
BEGIN
IF slimByOne THEN
BEGIN
IF x1>x2 THEN x1 ← x1-1 ELSE IF x1<x2 THEN x2 ← x2-1;
IF y1>y2 THEN y1 ← y1-1 ELSE IF y1<y2 THEN y2 ← y2-1;
END;
SetColorArea[x1, y1, x2, y2, fn, cGray, mGray, b];
END;

SetColorArea
: PROC [x1,y1,x2,y2: INTEGER, fn: BitBltDefs.BBoperation,
cGray: GrayPatternPtr, mGray: GrayPatternPtr ← NIL, b: BitmapPtr ← NIL] = INLINE
BEGIN
BLT: BLTBlockPtr = AllocateBLT[];
SetupColorAreaBLT[BLT: BLT, x1: x1, y1: y1, x2: x2, y2: y2, fn: fn, b: b];
IF fn=replace AND mGray#NIL THEN
BEGIN
BLT.blk.function ← erase;
SetupBitBltGray[BLT, mGray];
BitBltDefs.BITBLT[@BLT.blk];
BLT.blk.function ← paint;
END;
SetupBitBltGray[BLT, cGray];
BitBltDefs.BITBLT[@BLT.blk];
FreeBLT[BLT];
END;

SetupColorAreaBLT: PROC [BLT: BLTBlockPtr,
x1,y1,x2,y2: INTEGER, fn: BitBltDefs.BBoperation, b: BitmapPtr ← NIL] ;
SetupBitBltGray: PROC [BLT: BLTBlockPtr, gray: GrayPatternPtr] = INLINE
BEGIN
BitBltGrayPtr: TYPE = POINTER TO ARRAY [0..4) OF CARDINAL;
LOOPHOLE[@BLT.blk.gray0, BitBltGrayPtr]↑ ←
LOOPHOLE[@gray[InlineDefs.BITAND[BLT.blk.dty, 3]], BitBltGrayPtr]↑;
END;

SetRed, SetGreen, SetBlue
:
PROC [gray: [0..256),newVal: [0..256),outputDevice: BitmapPtr ← NIL];
GetRed, GetGreen, GetBlue:
PROC [gray: [0..256),outputDevice: BitmapPtr ← NIL] RETURNS [CARDINAL];

GetColorGray, GetMaskGray
: PROC [c: Color] RETURNS[GrayPattern];
SetColorFromSource: PROC [source: BitmapPtr, x,y: INTEGER,
fn: BitBltDefs.BBoperation, sourceType: BitBltDefs.BBsourcetype ← block,
gray: GrayPatternPtr ← NIL, dest: BitmapPtr ← NIL] ;

END.