QuickDraw/PackRgn.a

160 lines
6.5 KiB
Plaintext
Executable File

.INCLUDE GRAFTYPES.TEXT
.PROC PACKRGN,3
.REF SETSIZE
;-----------------------------------------------------------------
;
; PROCEDURE PackRgn(srcHandle: Handle; nPoints: INTEGER; dstRgn: RgnHandle);
;
; Converts a sorted array of inversion points into a region.
; Calls storage allocator to make more room and trim result to minimum size.
;
; OUTPUT IS IN THE FOLLOWING FORM:
;
; RGNSIZE
; RGNBBOX
; V H .. H 32767
; V H .. H 32767
; V=32767
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE .EQU 10 ;TOTAL BYTES OF PARAMS
SRCHANDLE .EQU PARAMSIZE+8-4 ;LONG
NPOINTS .EQU SRCHANDLE-2 ;INTEGER
DSTRGN .EQU NPOINTS-4 ;LONG, HANDLE
;-------------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
BBOX .EQU -8 ;RECTANGLE
VARSIZE .EQU BBOX ;SIZE OF LOCAL VARIABLES
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
MOVE.L SRCHANDLE(A6),A4 ;GET SRC HANDLE
MOVE.L DSTRGN(A6),A3 ;GET DST RGNHANDLE
MOVE NPOINTS(A6),D6 ;GET NUMBER OF POINTS
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN
MOVE RGNSIZE(A1),D5 ;GET CURRENT RGNSIZE
MOVE.L (A4),A0 ;DE-REFERENCE SRCHANDLE
;------------------------------------------------------------------------
;
; CHECK NPOINTS TO SPECIAL CASE EMPTY AND RECTANGULAR REGIONS.
;
MOVEQ #10,D7 ;INIT RGNSIZE TO EMPTY RGN SIZE
CLR.L BBOX+TOPLEFT(A6) ;INIT BOUNDING BOX TO EMPTY
CLR.L BBOX+BOTRIGHT(A6)
CMP #4,D6 ;HOW MANY POINTS IN SOURCE ?
BGT.S NOTRECT ;MORE THAN 4, NOT RECTANGULAR
BLT.S DONE ;LESS THAN 4, EMPTY REGION
MOVE.L 0(A0),BBOX+TOPLEFT(A6) ;GET TOPLEFT OF BOUNDING BOX
MOVE.L 12(A0),BBOX+BOTRIGHT(A6) ;GET BOTRIGHT OF BOUNDING BOX
BRA.S DONE ;INSTALL RGNSIZE AND BBOX AND QUIT
;------------------------------------------------------------------------
;
; MORE THAN FOUR POINTS, NON-RECTANGULAR. SCAN FOR BBOX LEFT AND RIGHT.
;
NOTRECT MOVE V(A0),BBOX+TOP(A6) ;BBOX TOP:=FIRST POINT.V
MOVE H(A0),D1 ;INIT MINH TO FIRST HORIZ
MOVE D1,D2 ;INIT MAXH TO FIRST HORIZ ALSO
MOVE D6,D3 ;GET NUMPER OF POINTS IN SRC
SCAN SUB #1,D3 ;ANY POINTS LEFT ?
BLT.S ENDSCAN ;NO, QUIT SCANNING
MOVE.L (A0)+,D0 ;YES, GET NEXT POINT
CMP.W D1,D0 ;IS PT.H < MINH ?
BGE.S LEFTOK ;NO, CONTINUE
MOVE D0,D1 ;YES, MINH:=PT.H
BRA SCAN ;LOOP FOR MORE
LEFTOK CMP.W D2,D0 ;IS PT.H > MAXH ?
BLE SCAN ;NO, GO FOR NEXT
MOVE D0,D2 ;YES, MAXH:=PT.H
BRA SCAN ;GO FOR NEXT
ENDSCAN MOVE D1,BBOX+LEFT(A6) ;BBOX LEFT:=MINH
MOVE D2,BBOX+RIGHT(A6) ;BBOX RIGHT:=MAXH
MOVE -4+V(A0),BBOX+BOTTOM(A6) ;BBOX BOTTOM:=LAST POINT.V
;----------------------------------------------------------------
;
; EXPAND DSTRGN TO HOLD WORST CASE = 12 + 4*NPOINTS bytes.
;
MOVEQ #3,D5
ADD D6,D5 ;GET NPOINTS + 3
LSL #2,D5 ;TIMES 4
MOVE.L A3,-(SP) ;PUSH DSTRGN
MOVE D5,-(SP) ;PUSH NEW BYTECOUNT
JSR SetSize ;MAKE IT THAT BIG
;----------------------------------------------------
;
; NEWLY DE-REFERENCE SRC AND DST HANDLES
;
MOVE.L (A4),A0 ;DE-REFERENCE SRC HANDLE
MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN HANDLE
ADD D7,A1 ;SKIP OVER RGNSIZE & BBOX
SUB #1,D6 ;DBRA COUNT = NPOINTS - 1
MOVE (A0)+,D0 ;GET FIRST VERT COORD
MOVE #32767,D1
BRA.S START ;GO TO LOOP START
NEXTPT CMP (A0)+,D0 ;SAME VERT COORD ?
BEQ.S VSAME ;YES, CONTINUE
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
MOVE -2(A0),D0 ;GET NEW VERT COORD
START MOVE D0,(A1)+ ;PUT VERT COORD
VSAME MOVE (A0)+,(A1)+ ;PUT HORIZ COORD
DBRA D6,NEXTPT ;LOOP FOR ALL POINTS
MOVE D1,(A1)+ ;PUT END OF ROW MARKER
MOVE D1,(A1)+ ;PUT FINAL VERT = 32767
MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
SUB.L A0,A1 ;SUBTRACT FROM DSTPTR
MOVE.W A1,D7 ;TO COMPUTE RGNSIZE
;--------------------------------------------------------
;
; INSTALL RGNSIZE AND RGNBBOX.
;
DONE MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE
MOVE D7,(A0)+ ;INSTALL RGNSIZE
MOVE.L BBOX+TOPLEFT(A6),(A0)+ ;INSTALL BOUNDING BOX TOPLEFT
MOVE.L BBOX+BOTRIGHT(A6),(A0)+ ;AND BOTRIGHT
;--------------------------------------------------------
;
; TRIM DSTRGN TO EXACT SIZE IF IT ISN'T ALREADY.
;
CMP D7,D5 ;IS IT ALREADY THE RIGHT SIZE ?
BEQ.S SIZEOK ;YES, SKIP
MOVE.L A3,-(SP) ;PUSH DSTRGN HANDLE
MOVE D7,-(SP) ;PUSH NEW SIZE
JSR SETSIZE
;------------------------------------------------------
;
; CLEAN UP THE STACK AND GO HOME.
;
SIZEOK MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'PACKRGN '
.END