; ; File: PutOval.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: © 1981-1990 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <2> 8/2/90 gbm change LEFTEDGE and RIGHTEDGE in ovalstate record to avoid ; global conflicts ; <¥1.5> 7/14/89 BAL For Aurora: Final CQD ; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final ; ; To Do: ; ;EASE$$$ READ ONLY COPY of file Òputoval.aÓ ;¥1.5 BAL 07/14/1989 For Aurora: Final CQD ;¥1.4 BAL 05/29/1989 Blasting in 32-Bit QuickDraw version 1.0 Final ; File PutOval.a ; ; Copyright Apple Computer, Inc. 1981-1986 ; All Rights Reserved BLANKS ON STRING ASIS ;----------------------------------------------------------- ; ; --> 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. ; ;------------------------------------------------ ; ; 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 bsr.l INITOVAL ;INIT OVAL RECORD MOVE.W OVAL+LEFTMOSTEDGE(A6),OLDLEFT(A6) MOVE.W OVAL+RIGHTMOSTEDGE(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 BSR PUTPT ;PUTPOINT (OLDLEFT,VERT) MOVE OLDRIGHT(A6),D5 BSR.S PUTPT ;PUTPOINT (OLDRIGHT,VERT) ;----------------------------------------------------- ; ; FOR EACH VERTICAL, BUMP LEFTMOSTEDGE AND RIGHTMOSTEDGE. ; 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 bsr.l 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+LEFTMOSTEDGE(A6),D5 ;GET LEFTMOSTEDGE.INT CMP OLDLEFT(A6),D5 ;SAME AS OLDLEFT ? BEQ.S LEFTOK ;YES, CONTINUE BSR.S PUTPT ;PUTPOINT (NEWLEFT,VERT) MOVE OLDLEFT(A6),D5 BSR.S PUTPT ;PUTPOINT(OLDLEFT,VERT) MOVE OVAL+LEFTMOSTEDGE(A6),OLDLEFT(A6) ;UPDATE OLDLEFT ; CHECK RIGHT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED LEFTOK MOVE.W OVAL+RIGHTMOSTEDGE(A6),D5 ;GET RIGHTMOSTEDGE.INT CMP OLDRIGHT(A6),D5 ;SAME AS OLDRIGHT ? BEQ.S RIGHTOK ;YES, CONTINUE BSR.S PUTPT ;PUTPOINT (NEWRIGHT,VERT) MOVE OLDRIGHT(A6),D5 BSR.S PUTPT ;PUTPOINT(OLDRIGHT,VERT) MOVE OVAL+RIGHTMOSTEDGE(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 BSR.S PUTPT ;PUTPOINT (OLDLEFT,VERT) MOVE OLDRIGHT(A6),D5 BSR.S 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 cmp.l #65536-1024,a1 ;are we about to overflow? blt.s @sizeOK ;no, don't worry; be happy add.l A2,A3 ;MAKE BUFPTR UN-RELATIVE add.l A2,A1 ;MAKE BUFLIMIT UN-RELATIVE move #-147,qdErr ;indicate rgnTooBigErr rts @sizeOK 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 bsr.l 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 ENDPROC