.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