mac-rom/QuickDraw/PutOval.a
Elliot Nunn 0ba83392d4 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-09-20 18:04:16 +08:00

273 lines
7.8 KiB
Plaintext

;
; 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? <BAL 28Apr89>
blt.s @sizeOK ;no, don't worry; be happy <BAL 28Apr89>
add.l A2,A3 ;MAKE BUFPTR UN-RELATIVE <BAL 28Apr89>
add.l A2,A1 ;MAKE BUFLIMIT UN-RELATIVE <BAL 28Apr89>
move #-147,qdErr ;indicate rgnTooBigErr <BAL 28Apr89>
rts
@sizeOK ADD #1024,A1 ;MAKE BUFLIMIT BIGGER <BAL 28Apr89>
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