mac-rom/QuickDraw/Classic/PutOval.m.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

285 lines
8.2 KiB
Plaintext

;
; 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