sys7.1-doc-wip/QuickDraw/MaskAsm.a
2019-07-27 22:37:48 +08:00

409 lines
15 KiB
Plaintext

;
; File: MaskAsm.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: © 1987-1990 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <3> 7/24/90 gbm fix more of those darned warnings
; <2> 2/1/90 BAL Exported the seedCFill labels: mySProc and myCProc.
; <•1.2> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
; <•1.1> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
; 1/15/89 BAL Altered GetTmpDevice to unlock the gdevice to keep master ptr 32
; bit clean.
; 3/3/87 EHB New today
;
; To Do:
;
;EASE$$$ READ ONLY COPY of file “MaskAsmPatch.a”
;•1.2 BAL 05/29/1989 Blasting in 32-Bit QuickDraw version 1.0 Final
;•1.1 BAL 04/12/1989 Blasting in 32-Bit QuickDraw 1.0B1
; File MaskAsmPatch.a
;
; Copyright Apple Computer, Inc. 1987
; All Rights Reserved
;
;
; This file contains the CalcCMask and SeedCFill Routines.
; MODIFICATION HISTORY
;
; 3 Mar 87 EHB New today
; 10 Sep 88 BAL/MCF Forced calculation of "words" to round up to multiple of 16.
; 15 Jan 89 BAL Altered GetTmpDevice to unlock the gdevice to keep master ptr 32 bit clean.
BLANKS ON
STRING ASIS
MACHINE MC68020
SeedCFill PROC EXPORT
EXPORT CalcCMask,MySProc,MyCProc
IMPORT GetTempDevice
;---------------------------------------------------------------
;
; PROCEDURE SeedCFill(srcBits, dstBits: BitMap;
; srcRect, dstRect: Rect;
; seedH, seedV: INTEGER; {note shared field w/calcCMask}
; matchProc: Ptr;
; matchData: LongInt); {caller-defined data}
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch MaskAsmPatch.a 01Jan1904 #??? (SeedCFill) (SeedCFill)
;
; Given a source bitMap or pixMap in srcBits, and a dst bitMap
; in dstBits, SeedCFill computes a destination bit image with 1's
; only in the pixels where paint can leak from the starting seed point.
;
; This is done in a two-stage process. First, a one bit mask of the
; source is made, in which 0's represent the pixels that match the one at
; the seed point. All other pixel values are replaced by 1's. Next, a
; normal seedFill call is performed on this image.
;
; The caller can provide a custom searchProc (matchProc) which will get called
; to translate from source RGB values to mask values. When the proc is called
; theGDevice^^.gdRefCon contains a pointer to a record whose fields are:
;
; matchRec = Record
; red: INTEGER;
; green: INTEGER;
; blue: INTEGER;
; matchData: LongInt; {caller-defined data}
; end;
;
; Since the caller both supplies and uses the matchData, it can be a handle
; or a pointer or simply data. It is copied directly from matchData passed to
; SeedCFill to the matchData in the matchRec.
;
; The matchProc should return 0's for colors that should be filled, and 1's for
; colors that shouldn't be added to the mask.
PARAMSIZE EQU 28
srcBits EQU paramSize+8-4 ;source bitmap
dstBits EQU srcBits-4 ;dst bitmap
srcRect EQU dstBits-4 ;source rectangle
dstRect EQU srcRect-4 ;dest rectangle
seedH EQU dstRect-2 ;horizontal seed
seedV EQU seedH-2 ;vertical seed
calcSeed EQU seedV ;seed RGB for calcMask
matchProc EQU seedV-4 ;proc for filtering colors
matchingData EQU matchProc-4 ;data for matchProc
myData EQU -4 ;copy of user's handle/ptr
seedRGB EQU myData-6 ;RGB of seed (MUST PRECEDE myData)
myHandle EQU seedRGB-4 ;place to save handle
saveGD EQU myHandle-4 ;save grafDevice
saveFG EQU saveGD-6 ;save fgColor
saveBK EQU saveFG-6 ;save bkColor
VARSIZE EQU saveBK ;size of locals
LINK A6,#VARSIZE ;allocate stack frame
MOVE.L seedV(A6),-(SP) ;push horizontal, vertical
PEA seedRGB(A6) ;push VAR myColor
_GetCPixel ;get pixel at h,v
LEA mySProc,A0 ;get default search proc
MOVEQ #-1,D0 ;calcFlag := -1 <BAL 24Feb89>
BRA.S SHARE ;=>jump to common code
CalcCMask
;---------------------------------------------------------------
;
; PROCEDURE CalcCMask(srcBits, dstBits: BitMap;
; srcRect, dstRect: Rect;
; seedRGB: Ptr; {note shared field w/seedCFill}
; matchProc: Ptr;
; matchData: LongInt);
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch MaskAsmPatch.a 01Jan1904 #??? (CalcCMask) (CalcCMask)
;
; Given a source bitMap or pixMap in srcBits, and a dst bitMap
; in dstBits, CalcCMask computes a destination bit image with 1's
; only in the pixels where paint cannot leak from outside the srcRect.
;
; By default the color that defines the outside of the mask is passed in
; in the seedRGB. If the caller supplies a matchProc and matchData, then
; the proc is called to determine which colors make up the mask's boundary
; and which do not. Such a proc should return a value of 1 for colors that
; are to be considered edges, and 0 for all other colors.
;
LINK A6,#VARSIZE ;allocate stack frame
MOVE.L calcSeed(A6),A0 ;point to seed RGB
LEA seedRGB(A6),A1 ;point to local copy
MOVE.L (A0)+,(A1)+ ;copy red, green
MOVE (A0)+,(A1)+ ;copy blue
LEA myCProc,A0 ;get default search proc
MOVEQ #0,D0 ;calcFlag := 0 <BAL 24Feb89>
SHARE MOVEM.L D3-D5/A2-A4,-(SP) ;save work registers
MOVE.L D0,D5 ;keep calcFlag in D5
; set up the matchProc. The default is in A0.
MOVE.L matchProc(A6),D0 ;is user supplying one?
BNE.S @ProcOK ;=>yes, all set
MOVE.L A0,matchProc(A6) ;else stuff default proc
; save the fg and bk colors, and set to black and white
@ProcOK PEA saveFg(A6) ;point to save area
_GetForeColor ;save the forground
MOVE.L #blackColor,-(SP) ;push black
_ForeColor ;and set forecolor
PEA saveBk(A6) ;point to the save area
_GetBackColor ;save the background
MOVE.L #whiteColor,-(SP) ;push white
_BackColor ;and set the backcolor
; now allocate a gDevice for the one bit copy, and set gDevice
@IsCM CLR.L -(SP) ;make room for long result
JSR GetTempDevice ;go allocate a gDevice
MOVE.L (SP)+,A4 ;A4 = GDevice
MOVE.L theGDevice,saveGD(A6) ;save theGDevice
MOVE.L A4,theGDevice ;and set our new one
; get device's pixMap into A3 and lock it down
MOVE.L (A4),A0 ;POINT TO GDEVICE
MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO PIXMAP
_HLOCK
MOVE.L (A0),A3 ;POINT TO PIXMAP
; put pointer to seed color into GDRefCon
MOVE.L (A4),A1 ;point to gdevice
LEA seedRGB(A6),A0 ;point to seed color
MOVE.L A0,GDRefCon(A1) ;and set up pointer
MOVE.L matchingData(A6),myData(A6) ;pass user's data
; install search proc
MOVE.L matchProc(A6),-(SP) ;push searchProc
_AddSearch ;and install it
; set bounds, rowbytes of pixmap, and allocate bits for image
MOVE.L SRCRECT(A6),A0 ;POINT AT SRC RECTANGLE
MOVE.L (A0)+,D1 ;GET TOPLEFT
MOVE.L (A0)+,D0 ;GET BOTRIGHT
MOVE D0,D4 ;GET A COPY OF RIGHT
SUB D1,D4 ;GET WIDTH IN PIXELS
EXT.L D4 ;MAKE IT LONG
MOVEQ #15,D2 ;GET 15
ADD.L D2,D4 ;ROUND UP TO NEAREST WORD BOUNDARY
ASR.L #4,D4 ;DIV BY 16
BLE NoBits ;IGNORE IF NEWROW <= 0
ADD D4,D4 ;DOUBLE FOR NEW ROWBYTES
LEA ROWBYTES(A3),A0 ;POINT TO ROWBYTES
MOVE D4,(A0) ;COPY ROWBYTES
OR #$8000,(A0)+ ;SET FLAG FOR NEW PIXMAP
MOVE.L D1,(A0)+ ;COPY BOUNDS.TOPLEFT
MOVE.L D0,(A0)+ ;COPY BOUNDS.BOTRIGHT
; ALLOCATE MEMORY FOR BIT IMAGE
SWAP D1 ;GET LEFTTOP
SWAP D0 ;GET RIGHTBOT
SUB D1,D0 ;GET HEIGHT
MULU D0,D4 ;GET DATA SIZE IN BYTES
MOVE.L D4,D0 ;make a copy <BAL 24Feb89>
moveq #15,d1 ;get a constant <BAL 24Feb89>
add.l d1,d0 ;round up to quad long boundary <BAL 24Feb89>
_NEWHANDLE ;ALLOCATE MEMORY FOR BITMAP
BNE NoBits ;=>ERROR, JUST RETURN
move.l (a0),a1 ;point at memory <BAL 24Feb89>
lsr.l #4,d4 ;compute number of quad longs to init <BAL 24Feb89>
move.l d4,d0 ; <BAL 24Feb89>
swap d0 ;get high word of count <BAL 24Feb89>
@nxt8 move.l d5,(a1)+ ;init to 1's for seedFill and 0's for calcMask
move.l d5,(a1)+ ;init to 1's for seedFill and 0's for calcMask
move.l d5,(a1)+ ;init to 1's for seedFill and 0's for calcMask
move.l d5,(a1)+ ;init to 1's for seedFill and 0's for calcMask
dbra d4,@nxt8 ; <BAL 24Feb89>
dbra d0,@nxt8 ; <BAL 24Feb89>
@doneFill MOVE.L A0,MYHANDLE(A6) ;SAVE FOR DISPOSE
_HLOCK ;LOCK THE HANDLE
MOVE.L (A0),BASEADDR(A3) ;AND SET BASE ADDRESS OF TEMP
; COPY TO OUR ONE-BIT IMAGE
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRC PIXMAP
MOVE.L A3,-(SP) ;PUSH DST PIXMAP
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
MOVE.L (SP),-(SP) ;DSTRECT = SRCRECT
CLR -(SP) ;MODE = SRC COPY
CLR.L -(SP) ;NO MASKRGN
_COPYBITS ;COPY THE PIXMAP
; CALCULATE ALL THE PARAMETERS FOR SEEDFILL/CALCMASK
MOVE.L DSTBITS(A6),A0 ;GET DST BITMAP
MOVE.L (A0)+,D0 ;GET BASEADDR
_STRIPADDRESS ;CLEAR FLAG BITS
MOVE.L D0,A1 ;AND SAVE IN A1
MOVE (A0)+,D0 ;GET ROWBYTES
MOVE.L (A0)+,D1 ;GET BOUNDS.TOPLEFT
MOVE.L DSTRECT(A6),A0 ;GET DSTRECT
MOVE.L (A0)+,D2 ;GET DSTRECT.TOPLEFT
MOVE.L (A0),D3 ;GET DSTRECT.BOTRIGHT
; NOTE: Following operations on SeedV, SeedH are meaningless for CalcCMask,
; but not harmful.
MOVE.L SEEDV(A6),D4 ;GET SEED V,H
SUB D2,D3 ;WIDTH := DSTRECT(RIGHT-LEFT)
add.w #15,d3 ;round up to multiple of 16 <BAL/MCF 10Sep88>
ASR #4,D3 ;WORDS := WIDTH/16
BLE.S @DoneSeed ;=>IF INVALID WIDTH, THEN RETURN
SUB D1,D4 ;CONVERT SEED.H TO GLOBAL
SUB D1,D2 ;CONVERT DSTRECT.LEFT TO GLOBAL
ADD D2,D4 ;MAKE SEED.H RELATIVE TO DSTRECT
ASR #3,D2 ;LEFT INDENT := LEFT OFFSET / 8
ADD D2,A1 ;ADD LEFT INDENT TO BASEADDR
SWAP D1 ;GET BOUNDS.TOP
SWAP D2 ;GET DSTRECT.TOP
SWAP D3 ;GET DSTRECT.BOTTOM
SWAP D4 ;GET SEED V
SUB D2,D3 ;GET HEIGHT
BLE.S @DoneSeed ;=>IF INVALID THEN RETURN
SUB D1,D4 ;CONVERT SEED.H TO GLOBAL
SUB D1,D2 ;CONVERT DSTRECT.TOP TO GLOBAL
ADD D2,D4 ;MAKE SEED.V RELATIVE TO DSTRECT
SWAP D4 ;GET SEED V,H
MULS D0,D2 ;VERTICAL OFFSET := DSTROW * TOP
ADD.L D2,A1 ;ADD VERTICAL OFFSET TO BASEADDR
; now use SeedFill or CalcMask to generate the final mask
MOVE.L BASEADDR(A3),-(SP) ;PUSH POINTER TO SRC BITS
MOVE.L A1,-(SP) ;PUSH DST POINTER
MOVE ROWBYTES(A3),D1 ;GET SRCROW
AND #nuRBMask,D1 ;CLEAR MASK BITS
MOVE D1,-(SP) ;PUSH SRCROW
MOVE D0,-(SP) ;PUSH DSTROW
MOVE.L D3,-(SP) ;PUSH HEIGHT, WORDS
TST D5 ;IS IT CALCMASK?
BEQ.S @DoCalc ;=>YES, DO CALCMASK <BAL 24Feb89>
MOVE.L D4,-(SP) ;PUSH SEED H, V
_SEEDFILL ;AND GENERATE FINAL MASK
BRA.S @DoneSeed ;=>SKIP OVER CALCMASK
@DoCalc _CALCMASK ;AND GENERATE FINAL MASK
@DoneSeed MOVE.L myHandle(A6),A0 ;GET TEMP HANDLE
_DISPOSHANDLE ;AND RELEASE IT
NoBits MOVE.L matchProc(A6),-(SP) ;was one provided?
_DelSearch ;and remove it
MOVE.L saveGD(A6),theGDevice ;restore theGDevice
MOVE.L A4,-(SP) ;push temp GDevice
_DisposGDevice ;and release it
PEA saveFg(A6) ;point to saved fgColor
_RGBForeColor ;and restore it
PEA saveBk(A6) ;point to saved bkColor
_RGBBackColor ;and restore it
MOVEM.L (SP)+,D3-D5/A2-A4 ;restore work registers
UNLK A6 ;deallocate stack frame
RTD #ParamSize ;strip params and return
MySProc
;----------------------------------------------------
; MYSEARCH IS A CUSTOM SEARCHPROC THAT RETURNS 0 IF IT MATCHES
; THE COLOR POINTED TO BY THE GDREFCON FIELD, OTHERWISE RETURNS 1.
myRes EQU 4 ;result
myRGB EQU 8 ;desired rgb
myRet EQU 12 ;returned boolean
MOVEQ #0,D1 ;value if colors match
MOVEQ #1,D0 ;value if colors don't match
ProcShare MOVE #$0100,myRet(SP) ;return TRUE
MOVE.L myRGB(SP),A0 ;point to specified RGB
MOVE.L theGDevice,A1 ;get handle to the gDevice
MOVE.L (A1),A1 ;point to theGDevice
MOVE.L GDRefCon(A1),A1 ;point to seed RGB
CMP.L (A0)+,(A1)+ ;compare red, green
BNE.S @NoMatch ;=>no match, just return
CMP (A0)+,(A1)+ ;compare blue
BNE.S @NoMatch ;=>no match, just return
EXG D0,D1 ;if match, then return white
@NoMatch MOVE.L myRes(SP),A0 ;pointer to result
MOVE.L D0,(A0) ;return result
RTD #8 ;strip params and return
MyCProc
;----------------------------------------------------
; MyCProc IS A CUSTOM SEARCHPROC THAT RETURNS 1 IF IT MATCHES
; THE COLOR POINTED TO BY THE GDREFCON FIELD, OTHERWISE RETURNS 0.
MOVEQ #1,D1 ;value if colors match
MOVEQ #0,D0 ;value if colors don't match
BRA.S ProcShare ;and use common code
GetTempDevice FUNC EXPORT
EXPORT MASKEND
;-------------------------------------------------------------------------
; GetTempDevice: GDHANDLE;
;
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
;AppleSystemPatch MaskAsmPatch.a 01Jan1904 #??? (GetTempDevice) (GetTempDevice)
;
; THIS ROUTINE ALLOCATES A GRAFDEVICE, SETS IT TO ONE BIT PER PIXEL,
; GIVES IT A UNIQUE SEED SO THAT PIXEL TRANSLATIONS WILL BE DONE.
;
MOVE.L A4,-(SP) ; SAVE WORK REGISTER
CLR.L -(SP) ; MAKE ROOM FOR LONG RESULT
CLR -(SP) ; NO REFNUM
MOVE.L MINUSONE,-(SP) ; INDICATE THAT THERE'S NO DRIVER
_NEWGDEVICE ; ALLOCATE THE GRAFDEVICE
MOVE.L (SP)+,A4 ; GET GRAFDEVICE HANDLE
move.l a4,a0 ; get GDHandle
_HUnlock ; remove nasty bits in master ptr <BAL 15Jan89>
MOVE.L (A4),A0 ; GET GDEVICE
MOVE.L GDPMAP(A0),A0 ; GET DEVICE'S PIXMAP HANDLE
MOVE.L (A0),A0 ; POINT AT PIXMAP
CLR PIXELType(A0) ; SET PIXEL Type <BAL 24Feb89>
MOVE #1,PIXELSIZE(A0) ; SET PIXEL DEPTH
MOVE #1,CMPSIZE(A0) ; AND SIZE OF EACH COMPONENT
MOVE.L PMTABLE(A0),A0 ; GET DEVICE'S COLOR TABLE HANDLE
MOVE.L (A0),A0 ; MAKE IT A POINTER
CLR.L -(SP) ; MAKE ROOM FOR SEED
_GETCTSEED ; GET UNIQUE SEED
MOVE.L (SP),CTSEED(A0) ; AND INSTALL IT
MOVE.L (A4),A0 ; GET GDEVICE PTR
MOVE.L ([GDITable,A0]),A0 ; get the Itable's master pointer
MOVE.L (SP)+,ITabSeed(A0) ; make it look up to date
MOVE.L A4,8(SP) ; RETURN GDEVICE
MOVE.L (SP)+,A4 ; RESTORE WORK REGISTER
RTS ; AND RETURN
MASKEND