mirror of
https://github.com/jrk/QuickDraw.git
synced 2024-10-31 10:17:24 +00:00
160 lines
6.5 KiB
Plaintext
160 lines
6.5 KiB
Plaintext
|
.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
|