; ; File: PutOval.m.a ; ; Contains: xxx put contents here (or delete the whole line) xxx ; ; Written by: xxx put name of writer here (or delete the whole line) xxx ; ; Copyright: © 1988-1990 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <2> 7/20/90 gbm Put stackframe definition inside proc, to avoid global name ; conflicts ; <1.1> 11/11/88 CCH Fixed Header. ; <1.0> 11/9/88 CCH Adding to EASE. ; <1.2> 10/12/88 CCH Changed “m.GrafType.a” to “GrafType.m.a”. ; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE. ; <1.0> 2/11/88 BBM Adding file for the first time into EASE… ; ; To Do: ; ;EASE$$$ READ ONLY COPY of file “PUTOVAL.m.a” ; 1.1 CCH 11/11/1988 Fixed Header. ; 1.0 CCH 11/ 9/1988 Adding to EASE. ; OLD REVISIONS BELOW ; 1.2 CCH 10/12/1988 Changed “m.GrafType.a” to “GrafType.m.a”. ; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE. ; 1.0 BBM 2/11/88 Adding file for the first time into EASE… ; END EASE MODIFICATION HISTORY BLANKS ON STRING ASIS INCLUDE 'GRAFTYPES.m.a' ;----------------------------------------------------------- ; ; --> PUTOVAL.TEXT ; ; Routine to add the inversion points for an oval to a region. ; PUTOVAL PROC EXPORT IMPORT INITOVAL,BUMPOVAL,SETHSIZE ;---------------------------------------------------------------- ; ; PROCEDURE PutOval(dstRect: Rect; ovalWidth,ovalHeight: INTEGER; ; bufHandle: Handle; VAR index,size: INTEGER); ; ; Create region inversion points for an oval or roundRect. ; ;------------------------------------------------------ ; ; OFFSETS IN AN OVAL STATE RECORD: ; OVALTOP EQU 0 ;INTEGER OVALBOT EQU OVALTOP+2 ;INTEGER OVALY EQU OVALBOT+2 ;INTEGER RSQYSQ EQU OVALY+2 ;LONGINT SQUARE EQU RSQYSQ+4 ;64 BIT LONGFIX ODDNUM EQU SQUARE+8 ;64 BIT LONGFIX ODDBUMP EQU ODDNUM+8 ;64 BIT LONGFIX LEFTEDGE EQU ODDBUMP+8 ;32 BIT FIXED POINT RIGHTEDGE EQU LEFTEDGE+4 ;32 BIT FIXED POINT ONEHALF EQU RIGHTEDGE+4 ;32 BIT FIXED POINT OVALSIZE EQU ONEHALF+4 ;SIZE OF AN OVALREC ;------------------------------------------------ ; ; A6 OFFSETS OF PARAMETERS AFTER LINK: ; PARAMSIZE EQU 20 ;TOTAL SIZE OF PARAMETERS DSTRECT EQU PARAMSIZE+8-4 ;ADDR OF RECT OVALWIDTH EQU DSTRECT-2 ;INTEGER OVALHEIGHT EQU OVALWIDTH-2 ;INTEGER BUFHANDLE EQU OVALHEIGHT-4 ;LONG, HANDLE INDEX EQU BUFHANDLE-4 ;LONG, VAR SIZE EQU INDEX-4 ;LONG, VAR ;------------------------------------------------ ; ; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK: ; OVAL EQU -OVALSIZE ;OVAL RECORD SKIPTOP EQU OVAL-2 ;WORD SKIPBOT EQU SKIPTOP-2 ;WORD OLDLEFT EQU SKIPBOT-2 ;WORD OLDRIGHT EQU OLDLEFT-2 ;WORD VARSIZE EQU OLDRIGHT ;SIZE OF LOCAL VARIABLES ENTRY LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS ;--------------------------------------------------------------- ; ; INIT AN OVAL RECORD ; MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT LEA OVAL(A6),A1 ;POINT TO OVAL RECORD MOVE OVALWIDTH(A6),D2 ;GET OVALWIDTH MOVE OVALHEIGHT(A6),D1 ;GET OVALHEIGHT JSR INITOVAL ;INIT OVAL RECORD MOVE.W OVAL+LEFTEDGE(A6),OLDLEFT(A6) MOVE.W OVAL+RIGHTEDGE(A6),OLDRIGHT(A6) MOVE OVALHEIGHT(A6),D0 ;GET OVALHEIGHT ASR #1,D0 ;CALC OVAL HEIGHT DIV 2 ADD OVAL+OVALTOP(A6),D0 ;ADD OVAL TOP MOVE D0,SKIPTOP(A6) ;SAVE SKIPTOP MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT ADD BOTTOM(A0),D0 ;ADD BOTTOM SUB TOP(A0),D0 ;SUBTRACT TOP SUB OVALHEIGHT(A6),D0 ;SUBTRACT OVALHEIGHT MOVE D0,SKIPBOT(A6) ;SAVE SKIPBOT ;----------------------------------------------------------------- ; ; GET BUF HANDLE, DE-REFERENCE IT, AND ADD INDEX ; MOVE.L BUFHANDLE(A6),A3 ;GET HANDLE MOVE.L (A3),A3 ;DE-REFERENCE IT MOVE.L A3,A2 ;REMEMBER BUFSTART FOR LATER MOVE.L INDEX(A6),A0 ;GET ADDR OF INDEX ADD (A0),A3 ;ADD INDEX TO BUFPTR ;---------------------------------------------------------- ; ; BUFLIMIT := BUFSTART + BUFSIZE ; MOVE.L A2,A1 ;GET BUFSTART MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE ADD (A0),A1 ;LEAVE BUFLIMIT IN A1 ;------------------------------------------------ ; ; PUT THE TOP EDGE ; MOVE OVAL+OVALTOP(A6),D6 ;START VERT:= OVAL TOP MOVE OLDLEFT(A6),D5 JSR PUTPT ;PUTPOINT (OLDLEFT,VERT) MOVE OLDRIGHT(A6),D5 JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT) ;----------------------------------------------------- ; ; FOR EACH VERTICAL, BUMP LEFTEDGE AND RIGHTEDGE. ; IF THEY DIFFER FROM OLDLEFT AND OLDRIGHT, PUT INVERSION ; POINTS FOR THE DIFFERENCES ; NXTVERT CMP SKIPTOP(A6),D6 ;IS VERT < SKIPTOP ? BLT.S YESBUMP ;YES, BUMP OVAL RECORD CMP SKIPBOT(A6),D6 ;IS VERT >= SKIPBOT ? BLT.S RIGHTOK ;NO, SKIP BUMPING YESBUMP MOVEM.L D6/A1-A3,-(SP) ;PRESERVE REGS LEA OVAL(A6),A3 ;POINT TO OVAL RECORD MOVE D6,D0 ;GET CURRENT VERT JSR BUMPOVAL ;BUMP IT TO NEXT SCANLINE MOVEM.L (SP)+,D6/A1-A3 ;RESTORE REGS ; CHECK LEFT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED MOVE.W OVAL+LEFTEDGE(A6),D5 ;GET LEFTEDGE.INT CMP OLDLEFT(A6),D5 ;SAME AS OLDLEFT ? BEQ.S LEFTOK ;YES, CONTINUE JSR PUTPT ;PUTPOINT (NEWLEFT,VERT) MOVE OLDLEFT(A6),D5 JSR PUTPT ;PUTPOINT(OLDLEFT,VERT) MOVE OVAL+LEFTEDGE(A6),OLDLEFT(A6) ;UPDATE OLDLEFT ; CHECK RIGHT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED LEFTOK MOVE.W OVAL+RIGHTEDGE(A6),D5 ;GET RIGHTEDGE.INT CMP OLDRIGHT(A6),D5 ;SAME AS OLDRIGHT ? BEQ.S RIGHTOK ;YES, CONTINUE JSR PUTPT ;PUTPOINT (NEWRIGHT,VERT) MOVE OLDRIGHT(A6),D5 JSR PUTPT ;PUTPOINT(OLDRIGHT,VERT) MOVE OVAL+RIGHTEDGE(A6),OLDRIGHT(A6) ;UPDATE OLDRIGHT RIGHTOK ADD #1,D6 ;BUMP CURRENT VERT CMP OVAL+OVALBOT(A6),D6 ;DONE WITH THE OVAL ? BLT NXTVERT ;LOOP FOR ALL VERTICALS ;------------------------------------------------ ; ; PUT THE BOTTOM EDGE ; MOVE OLDLEFT(A6),D5 JSR PUTPT ;PUTPOINT (OLDLEFT,VERT) MOVE OLDRIGHT(A6),D5 JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT) ;---------------------------------------------------- ; ; UPDATE INDEX TO REFLECT POINTS ADDED, CLEAN UP STACK AND GO HOME. ; SUB.L A2,A3 ;CALC BUFPTR-BUFSTART MOVE.L INDEX(A6),A0 ;GET VAR ADDR OF INDEX MOVE A3,(A0) ;UPDATE INDEX MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS UNLINK PARAMSIZE,'PUTOVAL ' ;----------------------------------------------------------------------- ; ; Local routine to Append a point to the end of the saved points buffer, ; extending buffer if necessary. If pt is a duplicate of the last pt, ; cancel both instead. ; ; INPUTS: D5: HORIZ COORD ; D6: VERT COORD ; A1: BUFLIMIT GETS EXPANDED AND RELOCATED ; A2: BUFSTART GETS RELOCATED ; A3: BUFPTR GETS BUMPED AND RELOCATED ; ; ALTERS: A1,A2,A3, VAR SIZE ; PUTPT CMP.L A1,A3 ;IS BUFPTR < BUFLIMIT ? BLT.S SIZEOK ;YES, CONTINUE ;--------------------------------------------------------------------- ; ; BUFFER IS FULL, CALL STORAGE ALLOCATOR TO MAKE ROOM FOR 256 MORE POINTS. ; UPDATE BUFPTR, BUFSTART, BUFLIMIT, AND BUFSIZE AFTER RELOCATION. ; SUB.L A2,A3 ;MAKE BUFPTR RELATIVE SUB.L A2,A1 ;MAKE BUFLIMIT RELATIVE ADD #1024,A1 ;MAKE BUFLIMIT BIGGER MOVEM.L D0-D7/A0-A3,-(SP) ;SAVE REGS MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE MOVE A1,(A0) ;UPDATE BUFFER SIZE MOVE.L BUFHANDLE(A6),-(SP) ;PUSH HANDLE PARAM MOVE A1,-(SP) ;PUSH NEW SIZE JSR SETHSIZE ;MAKE THE BUFFER BIGGER MOVEM.L (SP)+,D0-D7/A0-A3 ;RESTORE REGS MOVE.L BUFHANDLE(A6),A2 ;GET BUF HANDLE MOVE.L (A2),A2 ;GET NEW BUFSTART ADD.L A2,A3 ;MAKE BUFPTR UN-RELATIVE ADD.L A2,A1 ;MAKE BUFLIMIT UN-RELATIVE ;------------------------------------------------------------------- ; ; ADD NEW POINT TO THE SAVE BUFFER UNLESS IT MATCHED THE PREVIOUS PT. ; DELETE DUPLICATE POINTS SINCE THEY WILL CANCEL EACH OTHER ANYWAY. ; SIZEOK CMP.L A2,A3 ;IS BUFPTR=STARTPTR ? BEQ.S APPEND ;BR IF FIRST POINT CMP -4+H(A3),D5 ;IS PREVIOUS HORIZ SAME ? BNE.S APPEND ;NO, APPEND NEW POINT CMP -4+V(A3),D6 ;YES, IS PREVIOUS VERT SAME TOO ? BNE.S APPEND ;NO, APPEND NEW POINT SUB #4,A3 ;YES, DELETE OLD INSTEAD RTS APPEND MOVE D6,(A3)+ ;PUT VERT COORD MOVE D5,(A3)+ ;PUT HORIZ COORD RTS END