-- BoxFns.mesa -- Written by Joe Maleson -- Last changed by Doug Wyatt, October 27, 1980 5:57 PM DIRECTORY BitBltDefs: FROM "BitBltDefs", GraphicsDefs: FROM "GraphicsDefs", InlineDefs: FROM "InlineDefs"; BoxFns: PROGRAM IMPORTS BitBltDefs, InlineDefs, GraphicsDefs EXPORTS GraphicsDefs = BEGIN Scale: PROCEDURE [factor,c: INTEGER] RETURNS [INTEGER] = INLINE BEGIN RETURN[(INTEGER[c*factor])/10];END; Screen: POINTER TO GraphicsDefs.Bitmap; CursorX: POINTER TO CARDINAL = LOOPHOLE[426B]; CursorY: POINTER TO CARDINAL = LOOPHOLE[427B]; NeedBoxInit: BOOLEAN _ TRUE; Allocate: PROCEDURE [nwords: CARDINAL] RETURNS [LONG POINTER] _ NIL; Free: PROCEDURE [LONG POINTER] _ NIL; (635)\f1 210b6B85b5B101b1B136b11B18b8B61b4B34b CreateBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box,width,height: CARDINAL] = BEGIN bm: GraphicsDefs.Bitmap; longP: LONG POINTER; IF NeedBoxInit THEN BEGIN NeedBoxInit _ FALSE; [Allocate,Free] _ GraphicsDefs.GetXMAlloc[]; Screen _ GraphicsDefs.GetDefaultBitmapHandle[]; END; bm _ [bank: ,nWords: ,nBits: width,nLines: height,nBitsPerPixel: Screen.nBitsPerPixel, portraitMode: Screen.portraitMode,scaleFactor: Screen.scaleFactor,bits:]; bm.nWords _ IF bm.portraitMode THEN ((Scale[bm.scaleFactor,width-1]+1)*bm.nBitsPerPixel+15)/16 ELSE ((Scale[bm.scaleFactor,height-1]+1)*bm.nBitsPerPixel+15)/16; longP _ Allocate[ IF bm.portraitMode THEN bm.nWords*(Scale[bm.scaleFactor,bm.nLines-1]+1) ELSE bm.nWords*(Scale[bm.scaleFactor,bm.nBits-1]+1)]; bm.bank _ InlineDefs.HighHalf[longP]; bm.bits _ InlineDefs.LowHalf[longP]; GraphicsDefs.EraseArea[0,0,width,height,@bm]; b^ _ [boxBitmap: bm,savedBits: NIL,displayBitmap:,displayX:,displayY:, displayed: FALSE,savedBank:,function: replace,type: normal,gray: ]; END; \f1b9B130b157B741b MakeLongPointer: PROCEDURE [ptr: POINTER,bank: CARDINAL] RETURNS [LONG POINTER] = MACHINE CODE BEGIN END; \f1b15B91b DestroyBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box,restore: BOOLEAN] = BEGIN IF restore THEN RemoveBox[b]; Free[MakeLongPointer[b.boxBitmap.bits,b.boxBitmap.bank]]; b.boxBitmap.bits _ NIL; END; \f1b10B194b DisplayBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box,x,y: CARDINAL, bitmap: POINTER TO GraphicsDefs.Bitmap _ NIL] = BEGIN IF bitmap = NIL THEN bitmap _ Screen; b.displayed _ FALSE; b.displayBitmap _ bitmap; MoveBox[b,x,y]; END; \f1b10B226b CursorInBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box] RETURNS [BOOLEAN] = BEGIN RETURN [CursorX^ IN [CARDINAL[MAX[20,INTEGER[b.displayX]]] - 20..b.displayX + b.boxBitmap.nBits + 20) AND CursorY^ IN [CARDINAL[MAX[20,INTEGER[b.displayY]]] - 20..b.displayY + b.boxBitmap.nLines + 20)]; END; \f1b11B287b ReleaseBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box] = BEGIN IF b.savedBits = NIL THEN RETURN; Free[MakeLongPointer[b.savedBits,b.savedBank]]; b.savedBits _ NIL; END; \f1b10B166b RemoveBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box] = BEGIN savedFunction: BitBltDefs.BBoperation _ b.function; savedType: GraphicsDefs.BoxType _ b.type; savedBits: POINTER _ b.boxBitmap.bits; savedBank: [0..77B] _ b.boxBitmap.bank; IF NOT b.displayed THEN RETURN; b.function _ replace;b.type _ normal; b.boxBitmap.bits _ b.savedBits; b.boxBitmap.bank _ b.savedBank; PaintBox[b]; b.function _ savedFunction;b.type _ savedType; b.boxBitmap.bits _ savedBits; b.boxBitmap.bank _ savedBank; b.displayed _ FALSE; ReleaseBox[b]; END; \f1b9B529b MoveBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box,cornerX,cornerY: CARDINAL] = BEGIN bm: GraphicsDefs.Bitmap _ b.displayBitmap^; bbox: GraphicsDefs.Bitmap _ b.boxBitmap; x: ARRAY [0..SIZE[BitBltDefs.BBTable]] OF UNSPECIFIED; mBLT: POINTER TO BitBltDefs.BBTable _ @x[LOOPHOLE[@x,CARDINAL] MOD 2]; savedX: CARDINAL _ cornerX; savedY: CARDINAL _ cornerY; bDisplayX: CARDINAL _ b.displayX; bDisplayY: CARDINAL _ b.displayY; IF NOT b.displayed THEN -- first time, do initialization BEGIN src,dest: GraphicsDefs.Rectangle; xOff: CARDINAL = IF INTEGER[cornerX] < 0 THEN -cornerX ELSE 0; yOff: CARDINAL = IF INTEGER[cornerY] < 0 THEN -cornerY ELSE 0; IF b.savedBits = NIL THEN BEGIN nScanLines: CARDINAL _ Scale[bm.scaleFactor,(IF bm.portraitMode THEN bbox.nLines ELSE bbox.nBits)-1]+1; longP: LONG POINTER _ Allocate[bbox.nWords*nScanLines]; b.savedBank _ InlineDefs.HighHalf[longP]; b.savedBits _ InlineDefs.LowHalf[longP]; END; b.displayed _ TRUE; src _ [cornerX+xOff,cornerY+yOff,cornerX+bbox.nBits-1,cornerY+bbox.nLines-1]; dest _ [xOff,yOff,bbox.nBits-1,bbox.nLines-1]; bbox.bits _ b.savedBits; bbox.bank _ b.savedBank; GraphicsDefs.TransferRectangle[Screen,@bbox,@src,@dest]; END ELSE --"normal" case BEGIN maxWidth,maxHeight: CARDINAL; mBLT.ptrs _ long; mBLT.dbca _ mBLT.sbca _ NIL; mBLT.pad _ 0; mBLT.sourcetype _ block; mBLT.function _ replace; mBLT.unused _ 0; IF bm.portraitMode THEN BEGIN cornerX _ Scale[bm.scaleFactor,cornerX]*bm.nBitsPerPixel; cornerY _ Scale[bm.scaleFactor,cornerY]; bDisplayX _ Scale[bm.scaleFactor,bDisplayX]*bm.nBitsPerPixel; bDisplayY _ Scale[bm.scaleFactor,bDisplayY]; bbox.nLines _ (Scale[bm.scaleFactor,b.boxBitmap.nLines-1]+1); bbox.nBits _ (Scale[bm.scaleFactor,b.boxBitmap.nBits-1]+1)*bm.nBitsPerPixel; bm.nLines _ (Scale[bm.scaleFactor,b.displayBitmap.nLines-1]+1); bm.nBits _ (Scale[bm.scaleFactor,b.displayBitmap.nBits-1]+1)*bm.nBitsPerPixel; END ELSE BEGIN t: CARDINAL; t _ Scale[bm.scaleFactor,(bm.nLines-1)-(cornerY+b.boxBitmap.nLines-1)]; cornerY _ Scale[bm.scaleFactor,cornerX];cornerX _ t*bm.nBitsPerPixel; t _ Scale[bm.scaleFactor,(bm.nLines-1) - (bDisplayY+b.boxBitmap.nLines-1)]; bDisplayY _ Scale[bm.scaleFactor,bDisplayX];bDisplayX _ t*bm.nBitsPerPixel; bbox.nLines _ Scale[bm.scaleFactor,b.boxBitmap.nBits-1]+1; bbox.nBits _ (Scale[bm.scaleFactor,b.boxBitmap.nLines-1]+1)*bm.nBitsPerPixel; bm.nLines _ Scale[bm.scaleFactor,b.displayBitmap.nBits-1]+1; bm.nBits _ (Scale[bm.scaleFactor,b.displayBitmap.nLines-1]+1)*bm.nBitsPerPixel; END; maxWidth _ MIN[bbox.nBits+MIN[INTEGER[bDisplayX],0], bm.nBits-1+MIN[INTEGER[bDisplayX],0]-bDisplayX]; maxHeight _ MIN[bbox.nLines+MIN[INTEGER[bDisplayY],0], bm.nLines-1+MIN[INTEGER[bDisplayY],0]-bDisplayY]; mBLT.dlbca _ MakeLongPointer[bm.bits,bm.bank]; mBLT.dbmr _ bm.nWords; mBLT.slbca _ MakeLongPointer[b.savedBits,b.savedBank]; mBLT.sbmr_bbox.nWords; --restore mBLT.dh _ maxHeight; mBLT.sty _ MAX[-INTEGER[bDisplayY],0]; mBLT.dty _ MAX[INTEGER[bDisplayY],0]; IF INTEGER[cornerX] < INTEGER[bDisplayX] THEN BEGIN --restore right mBLT.slx _ bbox.nBits-MIN[bDisplayX-cornerX,bbox.nBits]; mBLT.dlx _ bDisplayX+mBLT.slx; mBLT.dw _ IF INTEGER[mBLT.dlx+1] < INTEGER[bm.nBits] THEN MIN[bDisplayX-cornerX, (bm.nBits-1)-mBLT.dlx,bbox.nBits] ELSE 0; END ELSE BEGIN --restore left mBLT.dw _ MIN[cornerX-bDisplayX,maxWidth]; mBLT.slx _ MAX[-INTEGER[bDisplayX],0]; mBLT.dlx _ bDisplayX + mBLT.slx; END; BitBltDefs.BITBLT[mBLT]; mBLT.dw _ maxWidth; mBLT.slx _ ABS[MIN[INTEGER[bDisplayX],0]]; mBLT.dlx _ bDisplayX+mBLT.slx; IF INTEGER[cornerY] < INTEGER[bDisplayY] THEN BEGIN --restore bottom mBLT.sty _ bbox.nLines-MIN[bDisplayY-cornerY,bbox.nLines]; mBLT.dty _ bDisplayY+mBLT.sty; mBLT.dh _ IF INTEGER[mBLT.dty+1] < INTEGER[bm.nLines] THEN MIN[bDisplayY-cornerY, (bm.nLines-1)-mBLT.dty,bbox.nLines] ELSE 0; END ELSE BEGIN --restore top mBLT.dh _ MIN[cornerY-bDisplayY,maxHeight]; mBLT.sty _ MAX[-INTEGER[bDisplayY],0]; mBLT.dty _ bDisplayY + mBLT.sty; END; BitBltDefs.BITBLT[mBLT]; --move savedBits mBLT.dlbca _ mBLT.slbca _ MakeLongPointer[b.savedBits,b.savedBank]; mBLT.dbmr _ mBLT.sbmr _ bbox.nWords; mBLT.dh _ bbox.nLines; mBLT.sty _ 0; mBLT.dty _ 0; IF INTEGER[cornerX] < INTEGER[bDisplayX] THEN BEGIN --move right mBLT.slx _ 0; mBLT.dlx _ MIN[bDisplayX-cornerX,bbox.nBits]; mBLT.dw _ MIN[bbox.nBits-mBLT.dlx,bbox.nBits]; END ELSE BEGIN --move left mBLT.dlx _ 0; mBLT.slx _ cornerX-bDisplayX; mBLT.dw _ MIN[bbox.nBits-mBLT.slx,bbox.nBits]; END; BitBltDefs.BITBLT[mBLT]; mBLT.dw _ bbox.nBits; mBLT.slx _ 0; mBLT.dlx _ 0; IF INTEGER[cornerY] < INTEGER[bDisplayY] THEN BEGIN --move down mBLT.dty _ MIN[bDisplayY-cornerY,bbox.nLines]; mBLT.dh _ MIN[bbox.nLines-mBLT.dty,bbox.nLines]; mBLT.sty _ 0; BitBltDefs.BITBLT[mBLT]; END ELSE BEGIN --move up i: CARDINAL; da,sa: POINTER; deltaY: CARDINAL _ cornerY-bDisplayY; da _ b.savedBits; sa _ da + deltaY*bbox.nWords; IF b.savedBank = 0 THEN FOR i IN [deltaY..bbox.nLines) DO InlineDefs.COPY[to: da,from: sa,nwords: bbox.nWords]; da _ da + bbox.nWords; sa _ sa + bbox.nWords; ENDLOOP ELSE FOR i IN [deltaY..bbox.nLines) DO InlineDefs.LongCOPY[to: MakeLongPointer[da,b.savedBank], from: MakeLongPointer[sa,b.savedBank],nwords: bbox.nWords]; da _ da + bbox.nWords; sa _ sa + bbox.nWords; ENDLOOP; END; --save maxWidth _ MIN[bbox.nBits,(bm.nBits-1)-cornerX]; maxHeight _ MIN[bbox.nLines,(bm.nLines-1)-cornerY]; mBLT.dlbca _ MakeLongPointer[b.savedBits,b.savedBank];mBLT.sbmr_bbox.nWords; mBLT.slbca _ MakeLongPointer[bm.bits,bm.bank];mBLT.sbmr _ bm.nWords; mBLT.dty _ MAX[-INTEGER[cornerY],0]; mBLT.dh _ maxHeight - mBLT.dty; mBLT.sty _ cornerY+mBLT.dty; IF INTEGER[cornerX] < INTEGER[bDisplayX] THEN BEGIN --save left mBLT.dlx _ MAX[-INTEGER[cornerX],0]; mBLT.slx _ cornerX + mBLT.dlx; mBLT.dw _ MIN[bDisplayX - cornerX,maxWidth]; mBLT.dw _ mBLT.dw - MIN[mBLT.dw,mBLT.dlx]; END ELSE BEGIN --save right mBLT.dlx _ bbox.nBits - MIN[cornerX-bDisplayX,bbox.nBits]; mBLT.slx _ cornerX + mBLT.dlx; mBLT.dw _ MIN[cornerX - bDisplayX,maxWidth]; END; BitBltDefs.BITBLT[mBLT]; mBLT.dlx _ MAX[-INTEGER[cornerX],0]; mBLT.dw _ maxWidth - mBLT.dlx; mBLT.slx _ cornerX+mBLT.dlx; IF INTEGER[cornerY] < INTEGER[bDisplayY] THEN BEGIN --save top mBLT.dty _ MAX[-INTEGER[cornerY],0]; mBLT.sty _ cornerY + mBLT.dty; mBLT.dh _ MIN[bDisplayY - cornerY,maxHeight]; mBLT.dh _ mBLT.dh - MIN[mBLT.dh,mBLT.dty]; END ELSE BEGIN --save bottom mBLT.dh _ MIN[cornerY - bDisplayY,maxHeight]; mBLT.dty _bbox.nLines-MIN[cornerY-bDisplayY,bbox.nLines]; mBLT.sty _ cornerY + mBLT.dty; END; BitBltDefs.BITBLT[mBLT]; END; -- end of "real" MoveRectangle code b.displayX _ savedX; b.displayY _ savedY; PaintBox[b]; END; \f1b7B6929b PaintBox: PUBLIC PROCEDURE [b: POINTER TO GraphicsDefs.Box] = BEGIN bm: GraphicsDefs.Bitmap _ b.displayBitmap^; bbox: GraphicsDefs.Bitmap _ b.boxBitmap; magicBitmap: LONG POINTER TO ARRAY [0..0) OF CARDINAL _ NIL; offX,offY: INTEGER; cornerX: INTEGER _ b.displayX; cornerY: INTEGER _ b.displayY; IF (cornerX > INTEGER[b.displayBitmap.nBits]) OR (cornerY > INTEGER[b.displayBitmap.nLines]) OR (INTEGER[cornerX+bbox.nBits] <= 0) OR (INTEGER[cornerY+bbox.nLines] <= 0) THEN RETURN; --trivial exclusion --coords convert IF bm.portraitMode THEN BEGIN cornerX _ Scale[bm.scaleFactor,cornerX]*bm.nBitsPerPixel;cornerY _ Scale[bm.scaleFactor,cornerY]; bbox.nLines _ (Scale[bm.scaleFactor,b.boxBitmap.nLines-1]+1); bbox.nBits _ (Scale[bm.scaleFactor,b.boxBitmap.nBits-1]+1)*bm.nBitsPerPixel; bm.nLines _ (Scale[bm.scaleFactor,b.displayBitmap.nLines-1]+1); bm.nBits _ (Scale[bm.scaleFactor,b.displayBitmap.nBits-1]+1)*bm.nBitsPerPixel; END ELSE BEGIN t: CARDINAL; t _ Scale[bm.scaleFactor,(bm.nLines-1)-(cornerY+b.boxBitmap.nLines-1)]; cornerY _ Scale[bm.scaleFactor,cornerX];cornerX _ t*bm.nBitsPerPixel; bbox.nLines _ Scale[bm.scaleFactor,b.boxBitmap.nBits-1]+1; bbox.nBits _ (Scale[bm.scaleFactor,b.boxBitmap.nLines-1]+1)*bm.nBitsPerPixel; bm.nLines _ Scale[bm.scaleFactor,b.displayBitmap.nBits-1]+1; bm.nBits _ (Scale[bm.scaleFactor,b.displayBitmap.nLines-1]+1)*bm.nBitsPerPixel; END; offX _ IF cornerX < 0 THEN -cornerX ELSE 0; offY _ IF cornerY < 0 THEN -cornerY ELSE 0; BEGIN maxWidth: CARDINAL = MIN[bbox.nBits-offX,(bm.nBits-offX-1)-cornerX]; maxHeight: CARDINAL = MIN[bbox.nLines-offY,(bm.nLines-offY-1)-cornerY]; x: ARRAY [0..SIZE[BitBltDefs.BBTable]] OF UNSPECIFIED; pBLT: POINTER TO BitBltDefs.BBTable _ @x[LOOPHOLE[@x,CARDINAL] MOD 2]; pBLT.ptrs _ long; pBLT.dbca _ pBLT.sbca _ NIL; pBLT.pad _ 0; pBLT.sourcetype _ block; pBLT.function _ b.function; IF (b.type # normal) OR (b.function # replace) THEN BEGIN magicBitmap _ Allocate[bbox.nWords*bbox.nLines]; InlineDefs.LongCOPY[from: MakeLongPointer[b.savedBits,b.savedBank], to: magicBitmap, nwords: bbox.nWords*bbox.nLines]; pBLT.dlbca _ magicBitmap;pBLT.dbmr _ bbox.nWords; pBLT.dlx _ offX;pBLT.dty_offY; pBLT.slbca_MakeLongPointer[bbox.bits,bbox.bank]; pBLT.sbmr_bbox.nWords;pBLT.slx_offX;pBLT.sty_offY; pBLT.dh _ maxHeight;pBLT.dw _ maxWidth; SELECT b.type FROM outline => BEGIN dx: CARDINAL _ bm.nBitsPerPixel; dy: CARDINAL _ 1; pBLT.function _ IF b.function=paint THEN erase ELSE paint; pBLT.dw _ maxWidth-dx;pBLT.slx_offX+dx; BitBltDefs.BITBLT[pBLT]; --left pBLT.slx_offX;pBLT.dlx_offX+dx; BitBltDefs.BITBLT[pBLT]; --right pBLT.dw _ maxWidth;pBLT.dlx _ offX; pBLT.dh _ maxHeight-dy;pBLT.sty _ offY+dy; BitBltDefs.BITBLT[pBLT]; --above pBLT.sty _ offY;pBLT.dty _ offY+dy; BitBltDefs.BITBLT[pBLT]; --below pBLT.dty_offY;pBLT.dh _ maxHeight; pBLT.function _ b.function; BitBltDefs.BITBLT[pBLT]; --true colors END; gray => --must call external routine which knows about gray matrix BEGIN destBitmap: GraphicsDefs.Bitmap _ b.boxBitmap; --all but bits are same destBitmap.bank _ InlineDefs.HighHalf[magicBitmap]; destBitmap.bits _ InlineDefs.LowHalf[magicBitmap]; GraphicsDefs.SetGrayLevel[b.gray]; GraphicsDefs.PutGrayBitmap[@b.boxBitmap,0,0,@destBitmap]; END; ENDCASE => BitBltDefs.BITBLT[pBLT]; pBLT.function _ replace; END; --BLT pBLT.dlbca _ MakeLongPointer[bm.bits,bm.bank];pBLT.dbmr _ bm.nWords; pBLT.dlx _ cornerX+offX;pBLT.dty_cornerY+offY; IF magicBitmap = NIL THEN pBLT.slbca_MakeLongPointer[bbox.bits,bbox.bank] ELSE pBLT.slbca_magicBitmap; pBLT.sbmr_bbox.nWords;pBLT.slx_offX;pBLT.sty_offY; pBLT.dh _ maxHeight;pBLT.dw _ maxWidth; BitBltDefs.BITBLT[pBLT]; IF magicBitmap # NIL THEN Free[magicBitmap]; END; END; END. \f1b8B