sys7.1-doc-wip/Toolbox/BitEdit/BitEdit.a
2019-07-27 22:37:48 +08:00

364 lines
12 KiB
Plaintext

;EASE$$$ READ ONLY COPY of file “BitEdit.a”
; 1.1 CCH 10/16/1989 Incorporated new changes from Craig Carper.
; 1.0 CCH 08/03/1989 Adding to EASE for Big Bang build as PACK ID=1.
; END EASE MODIFICATION HISTORY
; File BitEdit.a
; 19-jun-86
;
; version 1.0A1
;
BLANKS ON
STRING ASIS
PRINT OFF
LOAD 'StandardEqu.d'
PRINT ON
BE68K PROC EXPORT
;======================================================================
;
; PROCEDURE FixRect( r: Rect ); EXTERNAL;
;
;======================================================================
EXPORT FixRect
FixRect
MOVE.L (SP)+,A1 ; pop RTS
MOVE.L (SP)+,A0
MOVE D3,-(SP)
MOVEM (A0)+,D0-D3 ; get coordinates
CMP D0,D2 ; compare bottom to top
BGE.S @0
EXG D0,D2
@0
CMP D1,D3 ; compare right to left
BGE.S @1
EXG D1,D3
@1
MOVEM D0-D3,-(A0) ; restore coordinates
MOVE (SP)+,D3
JMP (A1)
GetSelPat PROC EXPORT
;XREF GetSelPat
;---------------------------------------------------------------
;
; PROCEDURE GetSelPat(patIndex: INTEGER; VAR pat: Pattern);
; given index, return striped "marching ants" pattern
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN
MOVE (SP)+,D0 ;POP PATINDEX
AND #7,D0 ;TREAT PATINDEX MOD 8
MOVE.B #$F8,D1 ;INIT PATTERN DATA
ROR.B D0,D1 ;USE PATINDEX TO ROTATE
MOVE #7,D2 ;INIT LOOP COUNT
NXTBYT1 MOVE.B D1,(A1)+ ;STORE BYTE OF PATTERN
ROL.B #1,D1 ;ROTATE FOR NEXT BYTE
DBRA D2,NXTBYT1 ;LOOP 8 BYTES
JMP (A0) ;AND RETURN
NewPtrClr PROC EXPORT
;XREF NewPtrClr
;---------------------------------------------------------------
;
; FUNCTION NewPtrClr(logicalSize: Size): Ptr
; given size, return a cleared newptr block
;
move.l (sp)+,a1 ; pop return addr
move.l (sp)+,d0 ; get size in d0
_NewPtr ,CLEAR ; get a cleared block
; move.l a0,-(sp) ; put ptr on stack
move.l a0,(sp) ; put ptr on stack - PEA 12/9/87
jmp (a1) ; and return
ClearHandle PROC EXPORT
;XREF ClearHandle
;---------------------------------------------------------------
;
; PROCEDURE ClearHandle(block: Handle);
; given handle, clear it
;
move.l (sp)+,a1 ; pop return addr
move.l (sp)+,a0 ; get handle in a0
move.l a3,-(sp) ; save work reg.
move.l a0,a3 ; preserve handle
_GetHandleSize ; get size in d0
move.l (a3),a0 ; get ptr in a0
lsr.l #1,d0 ; get # of words in handle
bra.s dodbra
clrloop
clr.w (a0)+
dodbra
dbra d0,clrloop
move.l (sp)+,a3 ; restore a3
jmp (a1) ; and return
GetRgnMax PROC EXPORT
;--------------------------------------------------------
;
; FUNCTION GetRgnMax: INTEGER;
;
MOVE.L GRAFGLOBALS(A5),A0
MOVE RGNMAX(A0),4(SP) ;GET RGNMAX
RTS
CalcEdges PROC EXPORT
;XREF CalcEdges
;----------------------------------------------------------------
;
; PROCEDURE CalcEdges(srcBuf,dstBuf: QDPtr;
; topVert,height,rowBytes: INTEGER;
; lassoBlack: BOOLEAN);
;
; Calc the edges of srcBuf into dstBuf.
;
; Registers used: A0: Pointer to source bitmap.
; A1: Pointer to destination bitmap.
; A2: Pointer to working storage.
;
; D1: Scratch computations.
; D2: Loop counter for inner loops.
; D3: # of scanlines to process- loop counter for outer loop.
; D5: # of words per scanline.
; D6: # of bytes per scanline.
;
;
ROW EQU 74 ;Bytes in scanline buffer.
PARAM7 EQU 16
SRC EQU PARAM7+8-4 ;LONG
DST EQU SRC-4 ;LONG
TOPVERT EQU DST-2 ;WORD, (GLOBAL coordinate)
HEIGHT EQU TOPVERT-2 ;WORD
ROWBYT1 EQU HEIGHT-2 ;ANOTHER WORD
LASSOBLK EQU ROWBYT1-2 ;BOOLEAN
LINK A6,#-ROW ;ALLOCATE SCANBUF
MOVEM.L A2/D3-D6,-(SP) ;SAVE REGS
moveq #0,d6 ; clear d6 'cause we use it as a long
move.w ROWBYT1(a6),d6 ;Bytes per row in d6
move.l d6,d5
asr.l #1,d5 ;Words per row in d5
CLR.L D4 ;CLEAR INVERTFLAG
TST.B LASSOBLK(A6) ;IS LASSOBLACK TRUE ?
BEQ.S NOTBLK ;NO, CONTINUE
NOT.L D4 ;YES, INVERTFLAG := ALL ONES
NOTBLK MOVE TOPVERT(A6),D0 ;GET TOP VERT
mulu d6,d0
MOVE.L SRC(A6),A0 ;POINT TO SRC
ADD.L D0,A0 ;OFFSET SRC TO TOPVERT
MOVE.L DST(A6),A1 ;POINT TO DST
ADD.L D0,A1 ;OFFSET DST TO TOPVERT
MOVE.L SP,A2 ;POINT TO SCANBUF
MOVE HEIGHT(A6),D3 ;GET SCANLINE COUNT
BRA.S START1 ;GO TO LOOP START
;
; Source (A0), destination (A1), and working storage (A2) now set up.
; (D3) is # of scan lines. We'll loop through Loop1 and Loop2 this many
; times.
;
; Loop 1: AND src data with scan lines above and below, right shift, store
; in scan buffer (A2).
;
nxtRow1 MOVE.L d5,d2
SUBQ.L #1,d2 ;For DBRA
SUB D0,D0 ;CLEAR X-BIT
LOOP3 MOVE.W (A0)+,D0 ;GET A word FROM SRC
NEG.L d6
AND.W -2(a0,d6.l),d0 ; AND with scanline above
NEG.L d6
AND.W -2(a0,d6.L),d0 ; AND with scanline below
MOVE.W D0,D1 ;COPY RESULT
ROXR.W #1,D1 ;SHIFT RIGHT WITH CARRY
AND.W D1,D0 ;AND WITH RIGHT-SHIFT
MOVE.W D0,(A2)+ ;STORE RESULT INTO SCANBUF
DBRA D2,LOOP3 ;LOOP however many LONGS
;
; Loop 2: AND with left shift, AND with original, store into destination.
;
ADDA.L d6,a1 ; Add offset, we're counting backwards
MOVE.L d5,d2
SUBQ.L #1,d2
SUB D0,D0 ;CLEAR X-BIT
LOOP4 MOVE.W -(A2),D0 ;GET LONG FROM SCANBUF
ROXL.W #1,D0 ;SHIFT LEFT WITH CARRY
AND.W (A2),D0 ;AND WITH UNSHIFTED
NOT.W D0 ;INVERT THE INSET RESULT
AND.W -(A0),D0 ;AND WITH ORIGINAL SRC
EOR.W D4,-(A1) ;INVERT DST IF LASSOBLACK
AND.W D0,(A1) ;AND RESULT INTO DST
DBRA D2,LOOP4 ;LOOP 17 LONGS
;Right here, A0 and A1 should both be back where they started...
ADDA.L d6,a0
ADDA.L d6,a1
START1 DBRA D3,nxtRow1 ;LOOP HEIGHT ROWS
MOVEM.L (SP)+,A2/D3-D6 ;RESTORE REGS
UNLK A6 ;RELEASE STACK FRAME
MOVE.L (SP)+,A0 ;POP RETURN ADDR
ADD #PARAM7,SP ;STRIP PARAMS
JMP (A0) ;AND RETURN
STRING Asis
Dc.b 'CalcEdge'
TrimBBox PROC EXPORT
;XREF TrimBBox
;---------------------------------------------------------------
;
; PROCEDURE TrimBBox(dstBuf: QDPtr; VAR dstRect: Rect; rowB: INTEGER);
;
PARAM6 EQU 10
DSTBUF1 EQU PARAM6+8-4 ;LONG
DSTRECT EQU DSTBUF1-4 ;LONG
rowB EQU DSTRECT-2 ;word (keep in d3)
LINK A6,#0 ;NO LOCALS
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS
MOVE.L DSTRECT(A6),A4 ;GET ADDR OF DSTRECT
MOVE.L DSTBUF1(A6),A3 ;GET ADDR OF DSTBUF
move.w rowB(a6),d3 ; get rowBytes in d3
MOVE BOTTOM(A4),D7 ;GET DSTRECT BOTTOM
SUB TOP(A4),D7 ;SUB TOP FOR HEIGHT
BLE EMPTY ;SKIP IF EMPTY
;
; SCAN FOR TOP NON-ZERO OR EMPTY
;
MOVE TOP(A4),D0 ;GET DSTRECT TOP
MULU d3,D0 ;TIMES ROW FOR OFFSET
MOVE.L A3,A0 ;COPY BUFSTART
ADD.L D0,A0 ;POINT TO RECT TOPLEFT
MOVE.L A0,A2 ;SAVE FOR LATER
MOVE D7,D1 ;GET HEIGHT
move.w d3,d5 ; get rowBytes in d5
divu #2,d5 ; divide by 2 for words
MULU d5,D1 ;TIMES words
SUB #1,D1 ;MINUS 1 FOR DBRA COUNT
TOPLP TST.W (A0)+ ;IS THIS LONG ZERO ?
DBNE D1,TOPLP ;LOOP TILL NON-ZERO OR EMPTY
BEQ EMPTY ;QUIT IF EMPTY
SUB #2,A0 ;UNDO AUTO-INCR
MOVE.L A0,D0 ;COPY ADDRESS
SUB.L A3,D0 ;SUBTRACT START ADDRESS
DIVU d3,D0 ;DIV BY ROW FOR VERT COORD
MOVE D0,TOP(A4) ;STORE TOP COORD INTO DSTRECT
;
; FIND BOTTOM NON-ZERO
;
MOVE BOTTOM(A4),D0 ;GET DSTRECT BOTTOM
MULU d3,D0 ;TIMES ROW FOR OFFSET
MOVE.L A3,A0 ;COPY BUFSTART
ADD.L D0,A0 ;POINT TO RECT BOTTOM
BOTLP TST.L -(A0) ;IS THIS LONG ZERO ?
BEQ.S BOTLP ;YES, LOOP TILL NON-ZERO
MOVE.L A0,D0 ;COPY ADDRESS
SUB.L A3,D0 ;SUBTRACT START ADDRESS
DIVU d3,D0 ;DIV BY ROW FOR VERT COORD
ADD #1,D0 ;ADD 1 FOR BBOX BOTTOM
MOVE D0,BOTTOM(A4) ;STORE BOTTOM INTO DSTRECT
;
; FIND LEFTMOST ONE-BIT
;
SUB #1,D7 ;CALC HEIGHT-1 FOR DBRA
MOVE LEFT(A4),D2 ;GET DSTRECT LEFT
AND #$FFF0,D2 ;TRUNCATE TO LEFT WORD
MOVE D2,D0 ;MAKE A COPY
LSR #3,D0 ;DIV BY 8 FOR BYTE OFFSET
MOVE.L A2,A1 ;POINT TO RECT TOP
ADD D0,A1 ;OFFSET TO LEFT
LMORE MOVE.L A1,A0 ;POINT TO TOP OF COLUMN
MOVE D7,D1 ;GET HEIGHT-1
CLR D0 ;CLEAR ACCUMULATOR
LSCAN OR (A0),D0 ;OR A WORD INTO ACCUMULATOR
ADD d3,A0 ;BUMP TO NEXT ROW
DBRA D1,LSCAN ;LOOP HEIGHT ROWS
BNE.S LFOUND ;BR IF COL NOT BLANK
ADD #16,D2 ;SKIP BLANK WORD
ADD #2,A1
BRA.S LMORE ;TRY ANOTHER COLUMN
LFOUND ADD D0,D0 ;GET A BIT FROM LEFT
BCS.S LDONE ;QUIT IF ITS A ONE
ADD #1,D2 ;ELSE BUMP DSTRECT LEFT
BRA.S LFOUND ;AND LOOP FOR MORE
LDONE MOVE D2,LEFT(A4) ;UPDATE NEW LEFT COORD
;
; FIND RIGHTMOST ONE-BIT
;
MOVE RIGHT(A4),D2 ;GET DSTRECT RIGHT
ADD #15,D2
AND #$FFF0,D2 ;ROUND UP TO RIGHT WORD
MOVE D2,D0 ;MAKE A COPY
LSR #3,D0 ;DIV BY 8 FOR BYTE OFFSET
LEA -2(A2,D0),A1 ;POINT TO RECT TOP RIGHT
RMORE MOVE.L A1,A0 ;POINT TO TOP OF COLUMN
MOVE D7,D1 ;GET HEIGHT-1
CLR D0 ;CLEAR ACCUMULATOR
RSCAN OR (A0),D0 ;OR A WORD INTO ACCUMULATOR
ADD d3,A0 ;BUMP TO NEXT ROW
DBRA D1,RSCAN ;LOOP HEIGHT ROWS
BNE.S RFOUND ;BR IF COL NOT BLANK
SUB #16,D2 ;SKIP BLANK WORD
SUB #2,A1 ;BUMP TO NEXT COL LEFT
BRA.S RMORE ;TRY ANOTHER COLUMN
RFOUND LSR #1,D0 ;GET A BIT FROM RIGHT
BCS.S RDONE ;QUIT IF ITS A ONE
SUB #1,D2 ;ELSE BUMP RIGHT COORD
BRA.S RFOUND ;AND LOOP FOR MORE
RDONE MOVE D2,RIGHT(A4) ;UPDATE NEW RIGHT COORD
BRA.S DONE
EMPTY CLR.L (A4)+ ;RETURN DSTRECT = (0,0,0,0)
CLR.L (A4)+
DONE MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS
UNLK A6 ;RELEASE STACK FRAME
MOVE.L (SP)+,A0 ;POP RETURN ADDR
ADD #PARAM6,SP ;STRIP PARAMS
JMP (A0) ;AND RETURN
STRING Asis
Dc.b 'TrimBBox'
END