mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-22 23:29:27 +00:00
4325cdcc78
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.
2923 lines
103 KiB
Plaintext
2923 lines
103 KiB
Plaintext
;EASE$$$ READ ONLY COPY of file ÒFontMgrPatch.aÓ
|
|
; 1.3 CCH 04/17/1989 Unconditionalized fixes from 6.0.3.
|
|
; 1.2 CCH 01/31/1989 Merged changes from 6.0.3.
|
|
; 1.1 CCH 01/16/1989 Merged 6.0.3 final sources into 7.0.
|
|
; 1.0 CCH 11/16/1988 Added to EASE.
|
|
; END EASE MODIFICATION HISTORY
|
|
; File: FontMgrPatch.a
|
|
;
|
|
;________________________________________________________________________________
|
|
; NOTICE: When entering patches use the format that is described below...
|
|
;
|
|
; Please read the following description for
|
|
; the Patch Collator. Patch Collator will
|
|
; aid us in finding out where system
|
|
; patches are located. Therefore, making
|
|
; it a little easier to track down rodents!
|
|
;
|
|
;
|
|
; Patch Collator for the Macintosh System Disk
|
|
; ============================================
|
|
;
|
|
; File: patch.c
|
|
; Language: "C"
|
|
;
|
|
; Date: April 16, 1987
|
|
; Revision: 1.0
|
|
; Author: Charlton E. Lui
|
|
;
|
|
; Patch collator is a simple program that scans through files looking for Apple System Patches.
|
|
; It finds a patch comment by finding a header that looks like this...
|
|
;
|
|
; *** One to one mapping of a fix ***
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;*AppleSystemPatch FontMgrPatch.a 08Jul85 #0 (InstallRDrivers) (InstallRDrivers)
|
|
;
|
|
; *** One to many mapping of a fix ***
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;*AppleSystemPatch FontMgrPatch.a 09Dec85 #13 (SoundVBLAddress) (RecoverHandle,ROMBMap)
|
|
;
|
|
; *** Many to one mapping of a fix ***
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;*AppleSystemPatch FontMgrPatch.a 17May86 #47 (FontMgr,DialogMgr) (GetRsrc)
|
|
;
|
|
; *** One to many mapping of a fix ***
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;*AppleSystemPatch FontMgrPatch.a 23Apr86 #43 (BTFlush,BTClose) (BTFlush,BTClose)
|
|
;
|
|
;
|
|
;
|
|
; The examples show the many mappings a fix may have. Each file should have the appropiate ROM
|
|
; version already inserted atop the file so it does not need be entered.
|
|
;
|
|
; WARNING: To make sure the scan works properly, use parenthesis around the routine field(s).
|
|
;
|
|
; This header will be inserted atop of each patch file. Whenever a new patch is entered the person
|
|
; who is entering the patch will copy the header down to the place where they are making the fix
|
|
; and enter the pertinent information.
|
|
;
|
|
; IMPORTANT! Make sure to take out the asterix before the AppleSystemPatch symbol.
|
|
; The "*" was added so that Patch Collator would not mistake the comments above as
|
|
; an actual patch. So delete the "*" before. Also, make sure that there is no
|
|
; space between the ";"(semicolon) and the "AppleSystemPatch" symbol. It should look like this
|
|
; ";AppleSystemPatch".
|
|
;
|
|
; A file will contain a list of names of the main patch files. Patch collator will use
|
|
; MPW's funnel facility to feed the names into the patch collator.
|
|
;
|
|
; PatchCollator < PatchFiles
|
|
;
|
|
; The files will also be scanned for other patch file includes. The included patch files will
|
|
; be added to the list of patch files.
|
|
;
|
|
; Each file will be scanned for patch information and then entered into a binary tree.
|
|
; The binary tree is used to sort the patch list alpabetically. After it finishes,
|
|
; it disposes of all of the nodes of the tree.
|
|
;
|
|
; Patch Collator uses simple parsing techniques. It does not check whether or not the information
|
|
; is correct or not. Patch Collator will leave that for the AI group.
|
|
;
|
|
; Output will contain the information something like this...
|
|
;
|
|
; Files working on...
|
|
; ===================
|
|
; #1) Reading file PatchPlusROM.a
|
|
; Includes patch files for PatchPlusROM.a are as follows...
|
|
; #3) DrawPicturePatch.a
|
|
; #4) TEPatch.a
|
|
; #5) FontMgrPatch.a
|
|
; #6) MenuMgr.a
|
|
; #7) HMenuPatch.Install
|
|
; #2) Reading file PatchSEROM.a
|
|
; Includes patch files for PatchSEROM.a are as follows...
|
|
; #3) DrawPicturePatch.a
|
|
; #6) MenuMgr.a
|
|
; #7) HMenuPatch.Install
|
|
; #3) **Warning - could not open DrawPicturePatch.a
|
|
; #4) **Warning - could not open TEPatch.a
|
|
; #5) **Warning - could not open FontMgrPatch.a
|
|
; #6) **Warning - could not open MenuMgr.a
|
|
; #7) **Warning - could not open HMenuPatch.Install
|
|
; ====================================================================================================
|
|
; *****PATCH COLLATOR*****
|
|
; ====================================================================================================
|
|
;
|
|
; ** Column Condition:
|
|
; ** X means this trap is patched to fix another trap.
|
|
; Y means that this trap is being fixed by a trap ( possibly itself ).
|
|
;
|
|
; Patch List Condition Patch# Fix File Line# Date
|
|
; ====================================================================================================
|
|
;
|
|
; AsynchDrvrs Y #3 PatchPlusROM.a 2348 14Oct85
|
|
; AsynchDrvrs Y #42 PatchPlusROM.a 2302 14Oct85
|
|
; atalk:lap.a X #P019 PatchSEROM.a 2273 23Dec86
|
|
; atalk:nonres.a X #PA073 PatchSEROM.a 2276 2Mar87
|
|
; AutoInt1 X #21 PatchPlusROM.a 1700 01Jan1904
|
|
; BasicIO X #50 PatchPlusROM.a 2540 11Sep86
|
|
; BasicIO Y #50 PatchPlusROM.a 2540 11Sep86
|
|
; BTClose X #43 PatchPlusROM.a 2404 23Apr86
|
|
; BTClose Y #43 PatchPlusROM.a 2404 23Apr86
|
|
;
|
|
; Notice: The files that couldn't be opened will give a warning. This could have resulted in
|
|
; a typo or perhaps the file was not found in the directory.
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;_______________________________________________________________________________________
|
|
|
|
FontManager PROC EXPORT
|
|
|
|
EXPORT InitFonts
|
|
EXPORT SetFontLock
|
|
EXPORT GetFontName
|
|
EXPORT FMSwapFont
|
|
EXPORT RealFont
|
|
EXPORT FontMetrics
|
|
EXPORT SetFScaleDisable
|
|
EXPORT SetFractEnable
|
|
EXPORT FMgrEnd
|
|
|
|
EXPORT FPointOne ; (so that first reference wil be seen.)
|
|
|
|
bugFix EQU 1
|
|
patch EQU 1
|
|
|
|
FoutCurStyle EQU FOutUnused ;post the current style used here.
|
|
|
|
NumTables EQU 12
|
|
WidListSize EQU NumTables*4
|
|
|
|
FMSwapTrap EQU $101 ;the FMSwapFont trap number for _GetTrapAddr
|
|
|
|
; format of a width table:
|
|
|
|
WidTabData EQU 0 ;256 fixed point widths
|
|
WidTabFont EQU 1024 ;(long) font handle used to generate this width table
|
|
WidthSExtra EQU WidTabFont+4 ;(long) fixed point space extra used for this table
|
|
WidthStyle EQU WidthSExtra+4 ;(long) fixed point extra due to style, used for this table
|
|
WidthFID EQU WidthStyle+4 ;(word) font family ID for this table
|
|
WidthFSize EQU WidthFID+2 ;(word) font size request that generated this table
|
|
WidthFace EQU WidthFSize+2 ;(word) face request that generated this table
|
|
WidthDevice EQU WidthFace+2 ;(word) device requested
|
|
WidthScales EQU WidthDevice+2 ;(8 bytes) scale factors requested on input
|
|
WidthAFID EQU WidthScales+8 ;(word) actual font family ID for this table
|
|
WidthFHand EQU WidthAFID+2 ;(long) font family handle for this table
|
|
WidthUsedFam EQU WidthFHand+4 ;(boolean) whether we used fixed point family widths
|
|
WidthAFace EQU WidthUsedFam+1 ;(byte) actual face produced (may differ for styled fonts)
|
|
WidthVOutput EQU WidthAFace+1 ;(word) vertical scale output value
|
|
WidthHOutput EQU WidthVOutput+2 ;(word) horizontal scale output value
|
|
WidthVFactor EQU WidthHOutput+2 ;(word) vertical scale output value
|
|
WidthHFactor EQU WidthVFactor+2 ;(word) horizontal scale output value
|
|
WidthASize EQU WidthHFactor+2 ;(word) actual size of font strike used
|
|
WidTabSize EQU WidthASize+2 ;total size of a width table.
|
|
|
|
|
|
|
|
; FOND format definition
|
|
|
|
FONDFlags EQU 0 ; 0 (word) Flags word for family
|
|
FONDFamID EQU FONDFlags+2 ; 2 (word) Family ID number
|
|
FONDFirst EQU FONDFamID+2 ; 4 (word) first character in font
|
|
FONDLast EQU FONDFirst+2 ; 6 (word) last character in font
|
|
FONDAscent EQU FONDLast+2 ; 8 (word) maximum Ascent expressed for 1 pt.
|
|
FONDDescent EQU FONDAscent+2 ; A (word) maximum Descent expressed for 1 pt.
|
|
FONDLeading EQU FONDDescent+2 ; C (word) maximum Leading expressed for 1 pt.
|
|
FONDWidMax EQU FONDLeading+2 ; E (word) maximum MaxWidth expressed for 1 pt.
|
|
FONDWTabOff EQU FONDWidMax+2 ;10 (long) Offset to width table
|
|
FONDKernOff EQU FONDWTabOff+4 ;14 (long) Offset to kerning table
|
|
FONDStylOff EQU FONDKernOff+4 ;18 (long) Offset to Style Mapping Table
|
|
FONDProperty EQU FONDStylOff+4 ;1C (12 words) contains style property info
|
|
FONDAssoc EQU FONDProperty+24 ;34 (variable length) Font Association Table.
|
|
|
|
FAssocSiz EQU 6 ;size of a font association table entry.
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; PROCEDURE InitFonts -- initialize the font manager data structures
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (InitFonts) (InitFonts)
|
|
;
|
|
|
|
InitFonts
|
|
IF bugFix THEN
|
|
MOVEQ #-1,D2 ;get some ones
|
|
CLR.W FOutError ;clear once at init time
|
|
ELSE
|
|
CLR.W FOutError ;clear once at init time
|
|
CLR.L FOutFontHandle ;may point to non-existent font, so clear
|
|
MOVEQ #-1,D2 ;get some ones
|
|
MOVE.W D2,FONDID ;init FOND cache
|
|
CLR.L LastFOND
|
|
ENDIF
|
|
BSR SetScreenDevice ;make the screen the default device
|
|
CLR.W CurFMDevice ;make the device 0
|
|
CLR.B FScaleDisable ;enable font scaling
|
|
CLR.B FractEnable ;for now, turn off fractWidths
|
|
ST FontFlag ;set to note that a call is not re-entrant
|
|
MOVE.W SPFont,ApFontID ;set up default font ID
|
|
ADDQ.W #1,ApFontID ;bump it by 1
|
|
MOVE.B #12,FMDefaultSize ;set up FMDefault Size
|
|
|
|
; allocate and initialize the width table in the system heap, if we haven't already
|
|
MOVE.L WidthTabHandle,D0 ;already got it?
|
|
BNE.S @4 ;if we have it, skip
|
|
|
|
MOVE.L #WidTabSize,D0 ;size of table
|
|
_NewHandle ,SYS ;new handle in sysHeap
|
|
BNE.S CantAllocWTab ;if an error, skip
|
|
|
|
MOVE.L A0,WidthTabHandle ;remember it
|
|
|
|
; allocate a width table list if there is room for them.
|
|
IF bugFix THEN
|
|
ELSE
|
|
CLR.L WidthListHand ;assume not enough memory for other tables.
|
|
CMP.W #2,MemTop ;are we in a small memory system?
|
|
BLS.S @4 ;yes, then forget the second width table handle.
|
|
ENDIF
|
|
MOVE.L #WidListSize,D0 ;size of table
|
|
_NewHandle ,SYS,CLEAR ;new handle in sysHeap, cleared
|
|
BNE.S @4 ;if an error, skip
|
|
MOVE.L A0,WidthListHand ;remember it
|
|
|
|
; Invalidate all of the extra width tables, if they exist.
|
|
|
|
@4
|
|
; set up swapFont jump table entry
|
|
IF patch THEN
|
|
MOVE #$101,D0
|
|
_GetTrapAddress
|
|
MOVE.L A0,JSwapFont
|
|
ELSE
|
|
MOVE.L $1204,JSwapFont ;set up the jump vector
|
|
ENDIF
|
|
|
|
BSR.S InValWidths ;invalidate all of the width tables.
|
|
|
|
; new system font logic to handle non-12 point, or non-Chicago system font.
|
|
|
|
MOVE.L OneOne,-(SP) ;scale factor denominator
|
|
MOVE.L OneOne,-(SP) ;scale factor numerator
|
|
CLR.L -(SP) ;clear face, need bits, device
|
|
CLR.L -(SP) ;pass system family, size
|
|
SUBQ #4,SP ;room for function result
|
|
PEA 4(SP) ;pass the address of the input record
|
|
_FMSwapFont
|
|
ADD #20,SP ;toss function result & input record
|
|
MOVE.L FOutFontHandle,RomFont0 ;salt away system font for backwards compat.
|
|
@skipRest
|
|
RTS
|
|
|
|
|
|
; we couldn't allocate the width table so issue the out-of-memory deepShit alert
|
|
; >> note that since there is no system font yet, this will flash the box repeatedly until the stack
|
|
; >> runs into something important. There must be a better way!
|
|
CantAllocWTab
|
|
MOVEQ #25,D0 ;out of mem code
|
|
_SysError ;self-destruct...
|
|
|
|
|
|
; Invalidate all of the extra width tables, if they exist.
|
|
|
|
InValWidths
|
|
; * restore purge state of old FOND first
|
|
MOVE.L LastFOND,A0
|
|
MOVE.B FONDstate,D0
|
|
CMP.B #$FF,D0
|
|
BEQ.S @skipUnintialized
|
|
_HSetState
|
|
@skipUnintialized
|
|
MOVEQ #-1,D2 ;get some ones
|
|
MOVE.L D2,LastSPExtra ;flag that we can't get a match next time <DLD 24-Oct-85>
|
|
|
|
IF bugFix THEN
|
|
MOVE.W D2,FONDID ;init FOND cache (bug fix: not specific to color)
|
|
ENDIF
|
|
|
|
MOVE.L WidthListHand,D0
|
|
BEQ.S InvalWidthTab
|
|
MOVE.L D0,A1
|
|
MOVE.L (A1),A1 ;handle->pointer
|
|
MOVEQ #NumTables-1,D1
|
|
@5
|
|
MOVE.L (A1)+,D0 ;get a handle from the table
|
|
BEQ.S InvalWidthTab ;end of table.
|
|
MOVE.L D0,A0
|
|
MOVE.L (A0),D0 ;was this handle purged?
|
|
BEQ.S @55
|
|
MOVE.L (A0),A0
|
|
MOVE.L D2,WidTabFont(A0) ;invalidate it
|
|
MOVE.W D2,WidthFID(A0) ;and invalidate requested font ID.
|
|
@55
|
|
DBRA D1,@5 ;until end of table.
|
|
|
|
; Invalidate the width table.
|
|
|
|
InvalWidthTab
|
|
MOVEQ #-1,D2 ;set up invalid value
|
|
BSR.S DerefWidthTab
|
|
MOVE.L D2,WidTabFont(A0) ;invalidate it
|
|
MOVE.W D2,WidthFID(A0) ;and invalidate requested font ID.
|
|
MOVE D2,CurFMFamily ;and avoid simple match
|
|
RTS
|
|
|
|
;common dereference
|
|
DerefWidthTab
|
|
MOVE.L WidthTabHandle,A0
|
|
MOVE.L (A0),A0 ;handle->pointer
|
|
RTS
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; FamSizeInD0 returns both the family and the high word and the size in the low word.
|
|
|
|
FamSizeInD0
|
|
MOVEQ #0,D1 ;zero high byte of size
|
|
MOVE (A3),D0 ;get the family
|
|
BNE.S @notSystem ;only system if it is zero
|
|
MOVE SysFontFam,D0 ;set up system family (could be zero, OK)
|
|
MOVE SysFontSize,D1 ;set up system size (less OK if zero)
|
|
BNE.S @sysSizeOK ;if nonzero, keep it
|
|
@notSystem
|
|
MOVE.B FMDefaultSize,D1 ;get default font size
|
|
BNE.S @sizeNonZero
|
|
MOVEQ #12,D1 ;if low memory is no help, hard code to 12
|
|
@sizeNonZero
|
|
CMP #1,D0 ;is the font the application font?
|
|
BNE.S @sysSizeOK ;if not, donÕt change it
|
|
MOVE ApFontID,D0 ;change family to application family
|
|
@sysSizeOK
|
|
SWAP D0 ;save the family
|
|
MOVE fmInSize(A3),D0 ;get current size
|
|
BNE.S @notSizeZero ;if nonzero, leave alone
|
|
MOVE D1,D0 ;else use either SysFontSize or FMDefaultSize
|
|
@notSizeZero
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; A6 offsets for SwapFont
|
|
copyInput EQU -16 ;place to hold copy of CurFMInput
|
|
styleID EQU copyInput-4 ;saved style and ID from FOND (set up in GoLoadStrike)
|
|
paramBlk EQU styleID-ioQElSize
|
|
saveMap EQU paramBlk-2 ;the applicationÕs resource map in the system sub case
|
|
fwidStyle EQU saveMap-2 ;the style of the best width table found in the FOND
|
|
stackFrame EQU fwidStyle ;size of stack frame
|
|
|
|
;
|
|
; FUNCTION FMSwapFont(inRec:FontInputRecord):^FontOutputRecord
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (FMSwapFont) (FMSwapFont)
|
|
;AppleSystemPatch PatchIIROM.a 27Aug87 #PABM253 (GetHandleSize) (RealFont)
|
|
;
|
|
; FMSwapFont is the heart of the font manager. It receives an input record
|
|
; from QuickDraw specifying the font, face, device and scale of the requested
|
|
; font and figures out the best set of bits to load and return in the output
|
|
; record. It is optimized so that if the request is the same as the previous
|
|
; one, it returns as fast as it can.
|
|
|
|
; Some init conditions are rolled in from patches...
|
|
;
|
|
; To (try to) understand FontFlag, see the comments at SubFont, far, far below.
|
|
;
|
|
FMSwapFont
|
|
|
|
; Check FontFlag to see if we got here through SysError first.
|
|
LEA FMgrOutRec,A0 ;get pointer to our output record
|
|
MOVE.L A0,8(SP) ;return it as the result
|
|
MOVEQ #-1,D2 ;common constant to invalidate globals
|
|
CMP.L LastSpExtra,D2
|
|
BEQ GoDifFont
|
|
ADDQ.B #1,FontFlag ;if not a re-entrant call, this sets to zero
|
|
BEQ.S @notReentrant
|
|
BSR.S InvalWidthTab ;donÕt use the current cache; may be incomplete
|
|
|
|
; Here we know that the call to LoadResource failed, the disk switch hook is trying to go up, or a real
|
|
; SysError occured.
|
|
|
|
CMP.B #9,FontFlag ;are all substitutions exhausted ?
|
|
BEQ GoTryChicago ;if so, go straight for the ROM font
|
|
BGT FMSwapDone ;if that didnÕt work, this just return the last record
|
|
MOVE.B #8,FontFlag ;set to next re-entrant range.
|
|
@notReentrant
|
|
|
|
; the most important thing to do is to see if the input record is the same
|
|
; as it was last time, as fast as we can
|
|
|
|
MOVE.L 4(SP),A0 ;keep input record pointer in A3
|
|
LEA CurFMInput,A1 ;point at last request
|
|
|
|
CMPM.L (A0)+,(A1)+ ;the same?
|
|
BEQ.S @okFamSize ;if so, skip
|
|
MOVE.L A3,-(SP) ;maybe just substitution
|
|
MOVE.L 8(SP),A3 ;set up input record for utility
|
|
BSR.S FamSizeInD0 ;returns family, size
|
|
MOVE.L D0,D2 ;save input record, substituted
|
|
LEA CurFMInput,A3 ;maybe actuals need subbing as well
|
|
BSR.S FamSizeInD0 ;get last family, size
|
|
MOVE.L (SP)+,A3 ;restore
|
|
CMP.L D2,D0 ;the same?
|
|
BNE.S GoDifFont
|
|
MOVE.L -4(A0),-4(A1) ;jam original so next time is fast
|
|
@okFamSize
|
|
CMPM.L (A0)+,(A1)+ ;face, needbits, device the same?
|
|
BEQ.S @okFaceBitsDev ;if so, fine, continue fast case
|
|
; ! assume for now that I can get away without matching needBits
|
|
MOVE.L -(A0),D0 ;get the request face, needBits, device
|
|
MOVE.L -(A1),D1 ;check that against the last accessed face, bits, dev.
|
|
EOR.L D0,D1 ;set the bits that are different
|
|
AND.L #$FF00FFFF,D1 ;clear the needBits part
|
|
BNE.S GoDifFont ;if more is different, go handle it
|
|
MOVE.L (A0)+,(A1)+ ;make fast for next time, continue fast case
|
|
@okFaceBitsDev
|
|
CMPM.L (A0)+,(A1)+ ;numer the same?
|
|
BNE.S GoDifFont ;if not, skip
|
|
|
|
CMPM.L (A0)+,(A1)+ ;denom the same?
|
|
BNE.S GoDifFont ;if so, we're cool!
|
|
|
|
; ugh -- now we have to pull SpExtra out of the port to see if
|
|
; that changed. If not, we're cool.
|
|
; Believe it or not, it is possible that QuickDraw is not around at all, so test first.
|
|
|
|
TST.B QDExist ;is QuickDraw around
|
|
BMI.S StraightLineCP
|
|
MOVE.L grafGlobals(A5),A0 ;get grafGlobals
|
|
MOVE.L thePort(A0),D0 ;get thePort
|
|
BEQ.S StraightLineCP ;if no port, donÕt check space extra
|
|
MOVE.L D0,A0
|
|
@checkLastSp
|
|
MOVE.L LastSpExtra,D0 ;get spaceExtra <DLD 24-Oct-85>
|
|
CMP.L SpExtra(A0),D0 ;did it change? <DLD 24-Oct-85>
|
|
BEQ.S StraightLineCP ;if not, skip
|
|
|
|
; spaceExtra changing is not such a big deal; we don't have to recalculate
|
|
; everything. Dive in at the right spot...
|
|
LINK A6,#stackFrame
|
|
CLR saveMap(A6) ;in case substitution must switch res. maps
|
|
CLR fwidStyle(A6) ;just in case, remember no styled widths have been found
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;save work registers
|
|
MOVE.L 8(A6),A3 ;get input pointer
|
|
SUBQ.B #2,FontFlag ;set up substitution position to try again.
|
|
BRA AdjustSpace ;dive in...
|
|
|
|
; the request is different from the last one, so do things the slow way
|
|
|
|
GoDifFont
|
|
BRA.S DifFont ;go handle it
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Hurray! the font was the same as last time so we can return right away. The
|
|
; only thing left to do is to make sure the font wasn't purged. The master pointer can only contain
|
|
; a real live font or NIL. No need to check to see if the resource bits are set or if the master pointer
|
|
; is part of the free chain or if the handle has been reused since any calls to OpenResFile, CloseResFile
|
|
; and ReleaseResource have invalidated any cached handle state.
|
|
|
|
; A large scale change made here is to branch to DifFont if the font can not be loaded. This allows the
|
|
; same substitution to be used by all. Before, the system font was loaded instead, using the CurFMInput
|
|
; record. The new code is possibly disasterous since CheckPurged is called at the tail end of DifFont, so
|
|
; the space extra only special case can use the same code as the long way around. I need to make sure
|
|
; that DifFont only gets this far if the font has been successfully loaded, and no further purging sort of
|
|
; operations have occurred.
|
|
|
|
StraightLineCP
|
|
SUBQ.B #2,FontFlag ;set up substitution position to try again.
|
|
|
|
CheckPurged
|
|
MOVE.L FOutFontHandle,A0 ;get the font handle.
|
|
TST.L (A0)
|
|
BNE.S FMSwapDone
|
|
MOVE.L A0,-(SP) ;push it
|
|
MOVE.W #MapTrue,ROMMapInsert ;get it from ROM if possible <10 Jul 85>
|
|
_LoadResource ;make sure its loaded
|
|
CMP.B #-1,FontFlag ;hit disk-switch?
|
|
BEQ.S GoDifFont ;other data is inconsistent so start over.
|
|
TST.L (A0) ;still NIL?
|
|
BEQ.S GoDifFont ;if so, in trouble
|
|
BSR BuildCharTable ;need to rebuild character table
|
|
|
|
; all done with FMSwapFont so restore registers and return to our caller
|
|
|
|
FMSwapDone
|
|
|
|
; we must re-establish widthPtr each time we are called, as the heap might
|
|
; have been compacted. Note that this is for backwards compatability only.
|
|
|
|
MOVE.L WidthTabHandle,A0
|
|
MOVE.L (A0),WidthPtr ;assume color QD needs this no more.
|
|
ST FontFlag ;no more worry about re-entrancy
|
|
|
|
; If returning to previous font manager call (via LoadResource, GetResource, etc.), will need to check
|
|
; FontFlag to see if it is -1; if so, start substitution all over since state is no good.
|
|
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
ADDQ #4,SP ;strip parameter
|
|
JMP (A0) ;return to caller
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Utility called by DoMapFont when the correct widths were found in the width cache. It is called twice
|
|
; to set up FOutNumer h & v, FScaleVFact & FScaleHFact. A1 first points to widthVOutput in the FOND.
|
|
; D1 is either 0 (for v) or 2 (for h).
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
SetUpScale
|
|
IF patch THEN
|
|
IF onMac THEN
|
|
JMP $40EA96
|
|
ELSEIF onMacPP THEN
|
|
JMP $41931C ; *NB Patch* need addresses for both SE and Plus.
|
|
ENDIF
|
|
ELSE
|
|
LEA fmOutNumer+FOutRec,A0 ;set up the scale factor in the output record.
|
|
MOVE.W (A1)+,0(A0,D1) ;save @ FOutNumer. (FOutDenom is always 256.)
|
|
|
|
LEA FScaleVFact,A0 ;also set up scale factor in low memory.
|
|
MOVEQ #0,D0 ;clear high word (unsigned?)
|
|
MOVE.W 2(A1),D0 ;widthVFactor or widthHFactor
|
|
ASL.L #8,D0 ;adjust 8.8 number to 16.16
|
|
ADD D1,D1 ;double to 0 or 4.
|
|
NEG.W D1 ;make 0 or -4. (Low memory is h, v; table is v, h)
|
|
MOVE.L D0,0(A0,D1) ;save @ FScaleVFact, then FScaleHFact
|
|
RTS
|
|
ENDIF
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Given a handle to a FONT, NFNT or FOND in A0, DeRefResource loads it if it has been purged (skipping
|
|
; the trap call if it is already in memory.) A0 is set on output to point to the resource, or equals NIL
|
|
; if the call to LoadResource fails. The Z flag is set if the call to load resource failed.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DeRefResource
|
|
TST.L (A0) ;see if it is already loaded.
|
|
BNE.S alreadyLoaded ;if so, do nothing.
|
|
MOVE.L A0,-(SP) ;push it
|
|
MOVE.W #MapTrue,ROMMapInsert ;get it from ROM if possible <10 Jul 85>
|
|
_LoadResource ;make sure its loaded
|
|
CMP.B #-1,FontFlag ;hit disk-switch?
|
|
BEQ.S badLoad ;other data is inconsistent so start over.
|
|
TST.L (A0) ;still NIL?
|
|
BEQ.S badLoad ;if so, in trouble
|
|
alreadyLoaded
|
|
MOVE.L (A0),A0 ;handle -> pointer
|
|
RTS
|
|
badLoad
|
|
BRA Pop4SubFont ;start substituting (throw away return address)
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; DifFont - handle a font or style change.
|
|
;
|
|
; We reach this point when the family, size, scale or device has been changed, which usually means that
|
|
; we have to load in some new bits. The first thing to do is see if the device changed and, if it has, ask it
|
|
; for a new style table and dots/inch values.
|
|
;
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DifFont
|
|
LINK A6,#stackFrame ;might as well use locals as locals.
|
|
CLR saveMap(A6) ;in case substitution must switch res. maps.
|
|
CLR fwidStyle(A6) ;just in case, remember no styled widths have been found
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;save work registers
|
|
|
|
MoreDifFont
|
|
MOVE.L 8(A6),A0 ;pick up request pointer
|
|
LEA copyInput(A6),A1
|
|
MOVEQ #$10,D0
|
|
_BlockMove ;make copy of request
|
|
MOVE.L A1,A3
|
|
|
|
MOVE.B fmInFace(A3),FOutCurStyle ;set up desired style
|
|
MOVE.W fmInDevice(A3),D0 ;get device in request
|
|
CMP.W CurFMDevice,D0 ;did it change?
|
|
BEQ.S @sameDevice ;if not, we're cool
|
|
BSR SetNewDevice ;otherwise, read in the new stuff
|
|
@sameDevice
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
;
|
|
; The TryAgain entry point is used if no size/style variant of the requested font was found. SubFont has
|
|
; changed the family field and restored the size field from the original input record before entering here.
|
|
;
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
TryAgain
|
|
BSR FamSizeInD0
|
|
MOVE.L D0,(A3) ;save the size, family
|
|
; remember that copy has needBits cleared, but spline code (??) should check A6 input record !!!
|
|
CLR.B fmInNeedBits(A3)
|
|
LEA FontFlag,A4 ;we save a word here.
|
|
CMP.B #6,(A4) ;did we just substitute the ROM font?
|
|
BLT.S @skipROMFamily ;if not, all is well
|
|
CLR (A3) ;zero family, but leave substituted size
|
|
@skipROMFamily
|
|
|
|
; if we got here from the shortcut exact match or space extra only change, and LoadResource of
|
|
; the font failed, then FontFlag is set to -2.
|
|
|
|
TST.B (A4) ;test FontFlag for -2
|
|
BPL.S DoMapFont ;if 0 or greater, no problem
|
|
BSR InvalWidthTab ;invalidate WidthTabHandle
|
|
CLR.B (A4) ;advance to real substitution
|
|
|
|
; Use the info from the old width table if it applies.
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; DoMapFont searches handles pointed to by the width list for a table of widths matching the font
|
|
; requested by the input pointer.
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (DoMapFont) (DoMapFont)
|
|
;
|
|
; Registers used:
|
|
; D0 = size of width table, scratch D1 = scratch D2 = last purged handle entry offset
|
|
; D3 = last invalidated entry offset D4 = table full flag D5 = offset into entry list
|
|
; D6 = call MapFont flag D7 = last nonpurged offset A0 = scratch
|
|
; A1 = scratch A2 = A3 = input pointer
|
|
; A4 = width list handle, pointer
|
|
;
|
|
; Significant changes made since the Macintosh + ROM:
|
|
;
|
|
; 12-Aug-86 CRC Details, detailsÉ
|
|
; The algorithm for determining which entry to use was:
|
|
; Check list until match, or entry = 0, or entry has been purged, or the end of the list is reached.
|
|
; If an entry was purged, reallocate it and use it.
|
|
; If entry = 0, allocate it and use it.
|
|
;
|
|
; The algorithm is now:
|
|
; Check list until match or entry = 0 or the end of the list is reached.
|
|
; if no match, use the last invalidated entry in the list.
|
|
; if memory is not full:
|
|
; if no invalidated entry, reallocate the last purged entry in the list.
|
|
; if no purged entry, and the last entry = 0, allocate a new entry at the end of the list.
|
|
; if memory is full or the list is full:
|
|
; reuse the last nonpurged entry in the list.
|
|
; if there isnÕt a nonpurged entry then weÕre out of luck; donÕt use cache.
|
|
; if a memory allocation call fails, then the system heap is in bad shape; donÕt use cache.
|
|
;
|
|
; The actual size and font are stored in the width table instead of 0 or applFont.
|
|
;
|
|
; NewHandle, ReallocHandle recover if an error is returned.
|
|
;
|
|
; Entries in queue are rotated so that list is ordered most recently accessed to least recently
|
|
; accessed. If the system heap has room for all twelve elements, the least recently accessed is
|
|
; reused first. Otherwise, the Memory Manager roving purge pointer spins the wheel of fortune to
|
|
; decide who is purged (but only if some other process allocates heap space, or if the system heap
|
|
; is sufficiently fragmented.)
|
|
;
|
|
; Just for grins, all local branches are forward except for branches to the tops of loops.
|
|
;
|
|
; Any newly allocated or reused width table has the font handle and family ID fields invalidated to
|
|
; allow optimization of the remainder of the table fill-in code.
|
|
;
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DoMapFont
|
|
MOVE.L WidthListHand,D0 ;do we have any spare width tables?
|
|
BEQ.S @shortSkip ;if not, then skip this nonsense.
|
|
|
|
; Check if the width-table cache is still valid. <18-Oct-85>
|
|
|
|
MOVEQ #-1,D2 ;handy invalidation constant
|
|
CMP.L LastSpExtra,D2 ;invalidated through normal means or switcher?
|
|
BEQ.S @invalAll
|
|
|
|
CMP CurFMFamily,D2 ;just reuse WidthTabHandle?
|
|
BNE.S @notInvalid
|
|
BRA.S @shortSkip
|
|
@invalAll
|
|
BSR InvalWidths ;invalidate all of the width tables.
|
|
@shortSkip
|
|
BRA @skipCache ;
|
|
|
|
; We know that there has been some change. Search the list of width tables for a match.
|
|
|
|
@notInvalid
|
|
MOVE.L D0,A4 ;get the width list handle.
|
|
MOVE.L (A4),A4
|
|
MOVEQ #-1,D2 ;no purged handles found so far.
|
|
MOVEQ #-1,D3 ;no invalidated entries found so far.
|
|
SF D4 ;assume that table is not full.
|
|
MOVEQ #-4,D5 ;list entry counter is incremented at the top of loop.
|
|
SF D6 ;do call MapFont
|
|
MOVEQ #-1,D7 ;no nonpurged handles found so far.
|
|
|
|
; Check each list entry to see if it has been allocated, or if the table has purged.
|
|
|
|
@loopTop
|
|
ADDQ #4,D5 ;advance to next entry in width table handle
|
|
MOVE.L (A4),D1 ;get a possible width table handle.
|
|
BEQ @outOfLoop ;if none, create a new entry.
|
|
MOVE.L D1,A0
|
|
MOVE.L (A0),D0 ;get the master pointer.
|
|
BEQ @rememberPurge ;skip if it has been purged.
|
|
MOVE D5,D7 ;remember that this one was not purged.
|
|
MOVE.L D0,A1 ;we are pointing at the table now.
|
|
|
|
; We know that the device and scales match. But does the old table match the requested style?
|
|
|
|
MOVEQ #3,D1 ;number of longs to check - 1
|
|
MOVE.L A3,A0 ;copy the input pointer
|
|
LEA WidthFID(A1),A1 ;point to old width's info.
|
|
CMP #-1,(A1) ;check to see if it is valid.
|
|
BNE.S @valid ;skip if valid.
|
|
MOVE D5,D3 ;remember offset to invalid entry
|
|
@valid
|
|
CMPM.L (A0)+,(A1)+ ;does family, size; face, needbits, device;
|
|
DBNE D1,@valid ; numer; denom match?
|
|
BNE.S @loopBottom ;
|
|
|
|
; We already have the font handle (from the old width table), so skip most of MapFont.
|
|
|
|
ST D6 ;donÕt call MapFont
|
|
MOVE (A1),D0 ;get new font family ID
|
|
CMP FONDID,D0 ;different from old one?
|
|
BEQ.S @sameFOND ;if not, fond globals are already set up
|
|
MOVE.B FONDState,D0 ;get old FOND state
|
|
MOVE.L LastFOND,A0 ;maybe zero; if so, HSetState will reject
|
|
_HSetState ;restore purge state
|
|
|
|
MOVE.L (A4), A0 ; Get the Width Table handle <PMAB528>
|
|
_HNoPurge ; Make the Width Table non-purgeable <PMAB528>
|
|
|
|
MOVE (A1)+,D0 ;get new FOND ID
|
|
MOVE D0,FONDID ;save it
|
|
MOVE.L (A1)+,A0 ;get new FOND handle
|
|
MOVE.L A0,LastFOND ;save it
|
|
BEQ.S @noFOND
|
|
BSR DerefResource ;load it if it has purged
|
|
MOVE.B (A0),SaveFondFlags ;save the high byte of the FOND flags.
|
|
MOVE.L LastFOND,A0
|
|
_HGetState ;get the purge state
|
|
MOVE.B D0,FONDState ;preserve it until the next change
|
|
_HNoPurge ;and make the font nonpurgable
|
|
|
|
MOVE.L WidthListHand, A4 ; Get the list handle of Width Tables <PMAB528>
|
|
MOVE.L (A4), A4 ; Pointer to Width Table Handles <PMAB528>
|
|
ADD D5, A4 ; Add Offset of current Width Table <PMAB528>
|
|
MOVE.L (A4), A1 ; Handle to Width Table <PMAB528>
|
|
MOVE.L (A1), A1 ; Width Table ptr <PMAB528>
|
|
LEA WidthUsedFam(A1), A1 ; Load the address of the WidthUsedFam <PMAB528>
|
|
|
|
BRA.S @noFOND ;skip skip
|
|
@sameFOND
|
|
ADDQ #6,A1 ;skip over FOND ID, handle
|
|
@noFOND
|
|
MOVE.B (A1)+,UsedFWidths ;remember if we used family widths.
|
|
|
|
; We are changing back to an old style, so set up FOutFontHandle from our width.
|
|
|
|
MOVE.B (A1)+,FOutCurStyle ;set up real style (computed along with width table).
|
|
|
|
MOVEQ #0,D1
|
|
BSR SetUpScale ;set up the vertical scale factor and output.
|
|
MOVEQ #2,D1
|
|
BSR SetUpScale ;set up the horizontal scale factor and output.
|
|
|
|
; If we really want an expanded version, see if it already exists.
|
|
|
|
MOVE.L (A4),A0 ;get width handle.
|
|
MOVE.L (A0),A1 ;pointer to width table.
|
|
MOVE.L WidTabFont(A1),A1 ;corresponding font handle.
|
|
MOVE.L A1,FOutFontHandle ;get the font handle.
|
|
BRA.S @toSkipNew ;insert width handle in list.
|
|
|
|
; This entry did not match the request, so go on to the next one.
|
|
|
|
@rememberPurge
|
|
MOVE D5,D2 ;remember that this one was purged.
|
|
@loopBottom ;
|
|
ADDQ #4,A4 ;bump the list pointer.
|
|
CMP.W #(NumTables-1)*4,D5 ;done with the table yet?
|
|
BLO @loopTop ;try for a match on the next one in the list.
|
|
|
|
; end of loop
|
|
ST D4 ;remember that the table was full.
|
|
SUBQ #4,A4 ;point back at the one we want to use.
|
|
|
|
@outOfLoop
|
|
|
|
; if no exact match was found, check the existing WidthTabHandle to see if it is already invalid.
|
|
|
|
MOVE.L WidthTabHandle,A1 ;get address of handle
|
|
MOVE.L (A1),A1 ;get master pointer
|
|
CMP.W #-1,WidthFID(A1) ;has it been marked invalid?
|
|
BEQ.S @skipCache ;it is all ready to use.
|
|
|
|
EXG D3,D5 ;set up invalid position, preserve end of table.
|
|
TST D5 ;was an invalid table found?
|
|
BPL.S @reuseIt ;if so, skip purge check.
|
|
MOVE.L #WidTabSize,D1 ;get size of a table, in case we must allocate it.
|
|
IF bugFix THEN
|
|
_MaxBlock ,SYS ;better than FreeMem; unfortunately, didnÕt know for Aladdin ROM
|
|
ELSE
|
|
MOVE.L TheZone,A1
|
|
MOVE.L SysZone,TheZone
|
|
_FreeMem ;get the total free space in the system heap.
|
|
MOVE.L A1,TheZone
|
|
ENDIF
|
|
CMP.L D1,D0 ;is there enough room?
|
|
BLE.S @useNonpurged ;if not, use the last nonpurged entry in the list.
|
|
MOVE.L D1,D0 ;set up size to allocate.
|
|
MOVE D2,D5 ;was a purged handle found (to be missing)?
|
|
BPL.S @reuseIt ;if so, since we have enough memory, reuse it.
|
|
TST.B D4 ;is the table full?
|
|
BNE.S @useNonpurged ;if so, re-use nonpurged entry.
|
|
|
|
; We are beyond all list entries, so create a new one.
|
|
|
|
MOVE D3,D5 ;restore end of table position.
|
|
_NewHandle ,SYS ;_NewHandle in system heap.
|
|
BNE.S @skipCache ;use it only if allocation successful.
|
|
BRA.S @reuseIt ;reset width list pointer since it may have moved.
|
|
@useNonpurged
|
|
MOVE D7,D5 ;last nonpurged entry.
|
|
BMI.S @skipCache ;if not one, all out of options.
|
|
@reuseIt
|
|
MOVE.L WidthListHand,A4 ;get the width list handle again.
|
|
MOVE.L (A4),A4 ;since it may have moved.
|
|
LEA 0(A4,D5),A4 ;determine list entry address.
|
|
MOVE.L (A4),D1 ;get the master pointer.
|
|
BEQ.S @newWidthTable ;if zero, just created; skip purge test.
|
|
MOVE.L D1,A0 ;get the master pointer.
|
|
TST.L (A0) ;has it been purged?
|
|
BNE.S @newWidthTable ;if non-purged, mark as invalid.
|
|
|
|
; We found a purged list entry, so let's re-allocate it.
|
|
|
|
_ReAllocHandle
|
|
BNE.S @skipCache ;it failed, so nothing can be cached.
|
|
BRA.S @reuseIt ;reset width list pointer since it may have moved.
|
|
|
|
; If ReallocHandle or NewHandle fail, then there is no room to cache anything (since all other cache
|
|
; members would have purged to allow ReallocHandle or NewHandle to succeed).
|
|
|
|
; At this point and at the entry point skipNew, A0 is the handle to be
|
|
; installed at the front of the table, A4 points to the entry position being reused, and D5 is the offset
|
|
; from the front of the table to the reused position.
|
|
|
|
@newWidthTable
|
|
@toSkipNew
|
|
BRA.S @skipNew ;dive in.
|
|
|
|
@skipNext
|
|
MOVE.L -(A4),4(A4) ;move previous entry to this one.
|
|
@skipNew
|
|
SUBQ #4,D5 ;see if this is the first entry.
|
|
BPL.S @skipNext ;if so, nothing to do.
|
|
@swapHandles
|
|
MOVE.L WidthTabHandle,D1 ;save current handle - it's old now.
|
|
MOVE.L A0,WidthTabHandle ;save it in widthTabHandle.
|
|
_HNoPurge ;the current handle can't purge.
|
|
MOVE.L D1,(A4) ;save old handle in the front of the list.
|
|
MOVE.L D1,A0
|
|
_HPurge ;now it can purge if it wants.
|
|
|
|
; check to see if font is already figured out and installed
|
|
|
|
TST.B D6 ;call MapFont?
|
|
BNE.S GotFontHandle ;donÕt bother if the widths were found
|
|
|
|
; call MapFont to do all the hard work, installing a font in the output record
|
|
|
|
@skipCache
|
|
; Invalidate the new table entry.
|
|
BSR InvalWidthTab
|
|
BSR MapFont ;figure out font and install it
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
GotFontHandle
|
|
MOVE.L FOutFontHandle,A0 ;get the current font handle
|
|
BSR DeRefResource ;load resource who's handle is in A0.
|
|
|
|
; set up ascent, descent, etc...
|
|
|
|
TST.B FScaleDisable ; if scaling disabled, do new way
|
|
BNE.S newSetupHeight
|
|
|
|
LEA FOutAscent,A1 ;point to the info section
|
|
MOVE.B FAscent+1(A0),(A1)+ ;copy ascent
|
|
MOVE.B FDescent+1(A0),(A1)+ ;copy descent
|
|
MOVE.B FWidMax+1(A0),(A1)+ ;copy max width
|
|
MOVE.B FLeading+1(A0),(A1) ;copy leading
|
|
BRA.S DoStyle
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; ByteScale, ByteHScale are utility routines used to figure the font metrics for this font.
|
|
; FScaleVFact contains the nice factor to allow scaling to be disabled so that QD can do no or easy bitmap
|
|
; scaling. The value to be scaled is passed in D0, and scaled by the value in D1.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
ByteScale
|
|
MOVE.L FScaleVFact,D1
|
|
ByteHScale
|
|
EXT D0 ;fix-ize the byte in D0
|
|
SWAP D0
|
|
CLR D0 ;clear fract
|
|
MOVEM.L D0-D3/A0-A1,-(SP) ;D0, D1are operands; D2, D3 make room for results,
|
|
;preserves A0, A1.
|
|
_FixMul ;
|
|
_FixRound
|
|
MOVE (SP)+,D0 ;get result in low byte
|
|
ADDQ #2,SP ;throw away the other half of D3
|
|
MOVEM.L (SP)+,A0-A1 ;restore registers
|
|
MOVE.B D0,(A1)+ ;save it in FMgrOutRec
|
|
RTS
|
|
|
|
newSetupHeight
|
|
LEA FOutAscent,A1 ;point to the info section
|
|
MOVE.B FAscent+1(A0),D0
|
|
BSR.S ByteScale ;copy integer ascent
|
|
MOVE.B FDescent+1(A0),D0
|
|
BSR.S ByteScale ;copy descent
|
|
MOVE.B FWidMax+1(A0),D0 ;maxwidth needs a horizontal factor adjustment.
|
|
MOVE.L FScaleHFact,D1
|
|
BSR.S ByteHScale ;copy max width
|
|
MOVE.B FLeading+1(A0),D0
|
|
BSR.S ByteScale ;copy leading
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; At this point, we have the proper bits but the style parameters are wrong.
|
|
; Fill out the style record using a table supplied by the current device
|
|
|
|
DoStyle
|
|
MOVE.B FOutCurStyle,D1 ;get style byte
|
|
|
|
LEA FOutBold,A0 ;point at style part of output record
|
|
CLR.L (A0)+ ;set everything to 0
|
|
CLR.W (A0)+ ;clear some more
|
|
CLR.B (A0)+ ;clear seven bytes total
|
|
|
|
; special case the most common case -- plain text (ie, style byte is 0)
|
|
|
|
TST.B D1 ;plain?
|
|
BEQ.S CheckWTable ;if so, skip the loop
|
|
|
|
; we must fill out the style record the hard way, by looping through the
|
|
; driver-supplied style definition table
|
|
|
|
MOVEQ #0,D2 ;clear high part for indexing
|
|
LEA FMStyleTab,A1 ;point to the style table
|
|
MOVEQ #6,D0 ;consider 7 bits worth
|
|
LEA FOutBold,A0 ;point to style params
|
|
@fmStyloop
|
|
MOVE.B (A1)+,D2 ;get index
|
|
MOVE.B (A1)+,D3 ;get field increment
|
|
MOVE.B (A1)+,D4 ;get extra increment
|
|
|
|
LSR #1,D1 ;examine next style bit
|
|
BCC.S @nextSBit ;if its off, don't bother
|
|
|
|
ADD.B D3,0(A0,D2) ;increment proper style param
|
|
ADD.B D4,FOutExtra ;also increment extra
|
|
@nextSBit
|
|
DBRA D0,@fmStyloop ;loop till done
|
|
|
|
; special case underlining since it doesn't fit into our model
|
|
|
|
BTST #ULineBit,FOutCurStyle ;underlining on?
|
|
BEQ.S CheckWTable ;if not, skip
|
|
|
|
LEA FOutULOffset,A0 ;point to underline parameters
|
|
MOVE.B (A1)+,(A0)+ ;copy the three underline parameters
|
|
MOVE.B (A1)+,(A0)+ ;copy second byte
|
|
MOVE.B (A1)+,(A0)+ ;copy third byte
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Now the style is all set up so its time to make sure the width table is cool. First check to see if the
|
|
; widths were already cached, so we can skip the most time-consuming part of the work.
|
|
|
|
CheckWTable
|
|
|
|
; These tests decide to use either the integral style extra provided by the Font Manager, or the
|
|
; fractional style extra in the FOND.
|
|
|
|
MOVE.L LastFond,D0 ;check if there is a last FOND.
|
|
BEQ MakeITab ;if not, style extra canÕt be fractional.
|
|
|
|
TST.B FDevDisable ;set if the device would prefer the FOND style extra.
|
|
BNE.S @skipDevice
|
|
|
|
TST.B fmInDevice(A3) ;if the device is not the screen, it can supply itÕs
|
|
BNE MakeITab ; own style widths, so skip looking at the FOND widths.
|
|
@skipDevice
|
|
BTST #5,saveFondFlags ;set if fractional style extra is never from FOND.
|
|
BNE.S MakeITab
|
|
|
|
BTST #4,saveFondFlags ;set if fractional style extra is always from FOND.
|
|
BNE.S @computeFractExtra ; <06Nov85>
|
|
|
|
TST.B FractEnable ;set if application allows fractional spacing
|
|
BEQ.S MakeITab ;if not, donÕt figure fractional style extra from FOND. <06Nov85>
|
|
|
|
@computeFractExtra ;
|
|
|
|
; We can only get this far if the FOND has valid style extra entries (part of the FOND flags)?
|
|
; Next, compute the fixed point extra into D6 when we do have a family definition record present.
|
|
|
|
MOVE.L D0,A0 ;get the last fond.
|
|
BSR DeRefResource ;load resource who's handle is in A0.
|
|
|
|
; But wait, maybe this FOND is an empty FOND created by Font/DA Mover. If so, the FONDLast field
|
|
; will contain a zero.
|
|
|
|
TST FONDLast(A0) ;see if last character is zero.
|
|
BEQ.S MakeITab ;if so, do not calculate style here.
|
|
|
|
LEA FONDProperty(A0),A0 ;point to start of table
|
|
|
|
MOVE.W (A0)+,D6 ;get plain extra
|
|
EXT.L D6
|
|
|
|
; If the FOND has a width table with a style already calculated in it, it is not necessary to figure out the
|
|
; style extra for the styles already contained in the widths. Earlier, in GotEntry, a style with the correct
|
|
; widths found was saved in a local.
|
|
|
|
MOVE.B FOutCurStyle,D1 ;get style byte
|
|
BEQ.S @gotFractExtra ;if plain, skip the loop
|
|
BTST #6,saveFondFlags ;does this FOND have width tables at all?
|
|
BNE.S @noStyleInWidths ;if set (like for Courier) there are no width tables in FOND
|
|
MOVE fwidStyle(A6),D0 ;get style of widths already found
|
|
NOT D0 ;use as mask,
|
|
AND D0,D1 ;to turn off any style attributes already in widths
|
|
|
|
@noStyleInWidths
|
|
|
|
; we must fill out the style record the hard way, by looping through the
|
|
; driver-supplied style definition table
|
|
|
|
MOVEQ #7,D0 ;consider 8 bits worth
|
|
@exStyloop
|
|
MOVE.W (A0)+,D2 ;get extra value
|
|
|
|
LSR #1,D1 ;examine next style bit
|
|
BCC.S @nextExBit ;if its off, don't bother
|
|
|
|
; here we can add Adobe fix to look for funny sign bit sort of negative number
|
|
|
|
CMP #$8FFF,D2 ;is it -7.001 or smaller?
|
|
BGT.S @doNormalAdd
|
|
BCLR #15,D2 ;throw away sign bit
|
|
NEG D2 ;make into a normal twoÕs complement number
|
|
@doNormalAdd
|
|
EXT.L D2
|
|
ADD.L D2,D6 ;add it in
|
|
@nextExBit
|
|
DBRA D0,@exStyloop ;loop till done
|
|
@gotFractExtra
|
|
ASL.L #4,D6 ;adjust 4.12 to 16.16 fixed point
|
|
|
|
SUBQ #6,SP ;space for FixMul, FixRound results
|
|
CLR.W -(SP) ;fraction part zero.
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
MOVE.W WidthASize(A0),-(SP) ;get the actual size.
|
|
MOVE.L D6,-(SP) ;compute floating extra times pointsize
|
|
_FixMul
|
|
MOVE.L (SP),D6 ;get fixed point answer
|
|
_FixRound ;round in case fractions are disabled
|
|
MOVE (SP)+,D0 ;pop the answer
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
TST.B FractEnable ;fractional widths? <06Nov85>
|
|
BNE.S MakeWTab ;yes, then donÕt use the rounded result.
|
|
|
|
; Must overwrite default value of FoutExtra if FractEnable is not true but we are using fractional extra
|
|
; anywayÑe.g. the FOND flags specify always use fractional widths. <PMAB559 BAL 9/7/88>
|
|
|
|
MOVE.B D0,FOutExtra ;and save the byte-sized result <PMAB569 BAL 9/7/88>
|
|
|
|
MakeITab
|
|
MOVEQ #0,D6 ;clear out D6
|
|
MOVE.B FOutExtra,D6 ;get extra value
|
|
EXT.W D6 ;sign extend it
|
|
SWAP D6 ;make it fixed point
|
|
MakeWTab
|
|
|
|
; the font changed so we have to make the table from scratch. First
|
|
; init the meta fields in the new table.
|
|
|
|
BSR DerefWidthTab ;get a pointer to the width table in A0
|
|
CMP #-1,widthFID(A0) ;is it a new one?
|
|
BNE AdjustSpace ;just take care of space extra
|
|
|
|
LEA WidthSExtra(A0),A1 ;point just past widths
|
|
CLR.L (A1)+ ;set lastSpExtra to 0
|
|
MOVE.L D6,(A1) ;set lastStyExtra to value
|
|
ADD.W #WidthAFID-WidthStyle,A1
|
|
MOVE.W FONDID,(A1)+
|
|
MOVE.L LastFOND,(A1)
|
|
|
|
; there are two cases for building the width table, depending on whether
|
|
; the font comes with a fixed-point table or not. Point A1 at either
|
|
; the offset/width table or the fixed-point width table
|
|
; better load it if it purged
|
|
|
|
MOVE.L FOutFontHandle,A0 ;get the current font handle, prepare for deref. later
|
|
BSR DeRefResource ;load resource who's handle is in A0.
|
|
|
|
; D2 holds the flags word, D3 has firstChar and D4 has lastChar. Compute
|
|
; the size of the tables in D5.
|
|
|
|
MOVEM.W (A0),D2-D4 ;get flags, first, last
|
|
MOVE D4,D5 ;copy lastChar
|
|
SUB.W D3,D5 ;compute lastChar-firstChar
|
|
MOVE D5,D1 ;keep # in D1
|
|
ADDQ #3,D5 ;# of chars, including missing
|
|
ADD.W D5,D5 ;compute size of table
|
|
EXT.L D5 ;make it a longWord
|
|
|
|
; compute address of offset/width table into A1
|
|
|
|
IF bugFix THEN
|
|
MOVE.W fNDescent(A0),D0 ;possibly the high word of owTLoc
|
|
SWAP D0 ;put it in the high word
|
|
BPL.S @notNegative
|
|
ENDIF
|
|
MOVEQ #0,D0
|
|
@notNegative
|
|
MOVE.W fOWTLoc(A0),D0 ;get size till owTable
|
|
ADD.L D0,D0 ;double for bytes
|
|
LEA fOWTLoc(A0,D0.L),A1
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; case out on the font format, pointing A1 at the right table and getting
|
|
; the width of the missing character in long format in D7
|
|
|
|
MOVEQ #0,D7 ;clear out D7
|
|
|
|
TST.B FractEnable ;use expanded widths?
|
|
BEQ.S @noExWidth ;if not, skip
|
|
|
|
BTST #1,D2 ;expanded width table present?
|
|
BNE.S @gotExWidth ;if so, skip
|
|
|
|
BTST #6,saveFondFlags ;set if FOND fractional widths are not (to be) used.
|
|
BNE.S @noExWidth ;if not, compute integral values from the font.
|
|
|
|
; See if we have a family width table for this font. A4 contains an offset to it if there is one
|
|
; (set up by MapFont) or is NIL.
|
|
|
|
MOVE.L A4,D0 ;got family width table?
|
|
BEQ.S @noExWidth ;if not, skip
|
|
|
|
; handle case of figuring out missing character width for family width table
|
|
|
|
MOVE.L LastFOND,A1 ;get famDef record
|
|
MOVE.L (A1),A1 ;handle -> pointer
|
|
ADD.L A4,A1 ;compute width tab ptr
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
MOVE.W WidthASize(A0),D0 ;get size in D0
|
|
MOVE.W -4(A1,D5),D7 ;get fixed point width
|
|
MULS D0,D7 ;scale it up
|
|
ASL.L #4,D7 ;convert to 32 bits <28Jun AJH>
|
|
BRA.S DoWTable ;back to common code
|
|
|
|
|
|
; this font doesn't have an expanded width table, so A1 is cool. Fetch
|
|
; the width of the missing character.
|
|
|
|
@noExWidth
|
|
MOVE.B -3(A1,D5),D7 ;get byte width
|
|
SWAP D7 ;convert to fixed point
|
|
BRA.S DoWTable ;go make the table
|
|
|
|
; the font does have an expanded width table, so adjust A1 and fetch the
|
|
; width of the missing character
|
|
|
|
@gotExWidth
|
|
ADD.L D5,A1 ;bump to expanded table
|
|
MOVE.W -4(A1,D5),D7 ;get fixed point width
|
|
ASL.L #8,D7 ;convert to 32 bits
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; build the width table
|
|
|
|
DoWTable
|
|
|
|
; set up D5 with a boolean that specifies whether we have to call FixMul
|
|
; to do the scale-disable scaling
|
|
|
|
CMP.L #$10000,FScaleHFact ;scale factor = 1
|
|
SNE D5 ;if = 1, make it 0 <10-30-85>
|
|
AND.B FScaleDisable,D5 ;FScaleDisable must be on, too
|
|
|
|
; OK, start making the width table by filling in the missing characters
|
|
; for "minChar" characters
|
|
|
|
MOVE.L D7,D0 ; <10-30-85>
|
|
BSR.S AddD6ScaleD0 ;add extra to missing width, scale by FScaleHFactor.
|
|
MOVE.L D0,D7 ; <10-30-85>
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
|
|
BRA.S @minCharSkip ;WHILE, not REPEAT
|
|
@minCharLoop
|
|
MOVE.L D7,(A0)+ ;stuff in missing width
|
|
@minCharSkip
|
|
DBRA D3,@minCharLoop ;repeat till done
|
|
|
|
; now we case out to two separate loops for filling out the body of the
|
|
; width table, depending on if we have an expanded table.
|
|
|
|
CLR.B UsedFWidths ;assume we don't use them
|
|
|
|
TST.B FractEnable ;fraction widths enabled?
|
|
BEQ.S CalcOldWLoop ;if not, skip
|
|
BTST #1,D2 ;which format? (check for width table in font)
|
|
BEQ.S CheckFracWidths ;if not expanded, see if there is a FOND.
|
|
|
|
@gotXWid1
|
|
MOVEQ #0,D0 ;clear out D0
|
|
MOVE.W (A1)+,D3 ;get 8.8 character width
|
|
|
|
CMP.W #-1,D3 ;is it missing?
|
|
BNE.S @notMissing ;if not, go handle
|
|
|
|
MOVE.L D7,D0 ;use missing width
|
|
BRA.S @stuffWidth ;go stuff it
|
|
@notMissing
|
|
MOVE.W D3,D0 ;get width
|
|
ASL.L #8,D0 ;make it 16.16 fixed-point
|
|
BSR.S AddD6ScaleD0 ;add extra, and scale if enabled
|
|
@stuffWidth ;
|
|
MOVE.L D0,(A0)+ ;stuff it
|
|
|
|
DBRA D1,@gotXWid1 ;loop for # of chars
|
|
|
|
ST UsedFWidths ;we used them
|
|
BRA.S FillTheRest
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; we might have a family width table -- if we do, use a different loop
|
|
CheckFracWidths
|
|
BTST #6,saveFondFlags ;set if no fractional family widths
|
|
BNE.S CalcOldWLoop ;if set, compute integral values from the font.
|
|
|
|
MOVE.L A4,D0 ;got a family one?
|
|
BEQ.S CalcOldWLoop ;if not, must be old way.
|
|
|
|
; use family widths to figure sizes
|
|
|
|
MOVE.L WidthTabHandle,A4
|
|
MOVE.L (A4),A4
|
|
MOVE.W WidthASize(A4),-(SP) ;get the actual size, keep on stack.
|
|
MOVE.L D0,A4 ;restore index to family widths
|
|
@fxWidLoop
|
|
MOVEQ #0,D0 ;clear out D0
|
|
MOVE.W (A1)+,D3 ;get 4.12 1-point width
|
|
|
|
CMP.W #-1,D3 ;is it missing?
|
|
BNE.S @0 ;if not, go handle
|
|
|
|
MOVE.L D7,D0 ;use missing width
|
|
BRA.S @1 ;go stuff it
|
|
@0
|
|
MOVE.W D3,D0 ;get width
|
|
MULU (SP),D0 ;scale it up
|
|
ASL.L #4,D0 ;adjust to 16.16 fixed point
|
|
BSR.S AddD6ScaleD0 ;add extra, and scale if enabled
|
|
@1 ; <10-30-85>
|
|
MOVE.L D0,(A0)+ ;stuff it
|
|
|
|
DBRA D1,@fxWidLoop ;loop for # of chars
|
|
|
|
ADDQ #2,SP ;pop off point size
|
|
ST UsedFWidths ;we used them
|
|
BRA.S FillTheRest
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; common utility routine
|
|
; AddD6ScaleD0 adds in the style extra in D6, then multiplies the value in D0 by the
|
|
; FScaleDisable scale factor.
|
|
|
|
AddD6ScaleD0
|
|
TST.L D0 ;is it zero?
|
|
BEQ.S @0 ;if it has no width, do nothing
|
|
ADD.L D6,D0 ;add in style extra first
|
|
TST.B D5 ; need to scale it?
|
|
BEQ.S @0
|
|
|
|
; *** note that the smaller ELSE case is OK, since changing FixMulÕs register conventions breaks applications
|
|
|
|
IF 0 THEN
|
|
MOVEM.L A1/A0/D1,-(SP) ;save registers used by FixMul (D1, A0, A1)
|
|
SUBQ #4,SP ;make room for result
|
|
MOVE.L D0,-(SP) ;pass param D0
|
|
MOVE.L FScaleHFact,-(SP)
|
|
_FixMul ;
|
|
MOVEM.L (SP)+,D0-D1/A0-A1 ;function result (D0), restore registers (D1, A0, A1)
|
|
ELSE
|
|
MOVEM.L A1/A0/D1/D0,-(SP) ;save registers used by FixMul (A0, A1)
|
|
;make room for result (D1), pass param D0
|
|
MOVE.L FScaleHFact,-(SP)
|
|
_FixMul ;
|
|
MOVEM.L (SP)+,D0/A0-A1 ;function result (D0), restore registers (A0, A1)
|
|
ENDIF
|
|
@0
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
CalcOldWLoop
|
|
; its the old format, so walk down the o/w table, computing the fixed point
|
|
; widths and stuffing them into the table.
|
|
MOVEQ #0,D0 ;clear out D0
|
|
MOVE.W (A1)+,D3 ;get offset/width
|
|
CMP #-1,D3 ;is it missing?
|
|
BNE.S @skipMiss ;if non-missing, skip
|
|
|
|
MOVE.L D7,D0 ;use missing width
|
|
BRA.S @stuffIt ;go stuff it
|
|
@skipMiss
|
|
MOVE.B D3,D0 ;get width
|
|
SWAP D0 ;make it fixed-point
|
|
BSR.S AddD6ScaleD0 ; nop if not scale disabled
|
|
@stuffIt ;
|
|
MOVE.L D0,(A0)+ ;stuff it
|
|
|
|
DBRA D1,CalcOldWLoop ;loop for # of chars
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; OK, now fill out the end of the table with the missing character width
|
|
FillTheRest
|
|
MOVE #255,D0
|
|
SUB.W D4,D0 ;how many left?
|
|
BRA.S @whileStart ;let DBRA decrement first
|
|
@maxCharLoop
|
|
MOVE.L D7,(A0)+ ;stuff the width
|
|
@whileStart
|
|
DBRA D0,@maxCharLoop ;repeat till done
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Short cut space extra check at the beginning of SwapFont jumps to here. Also, cached widths case jumps
|
|
; here.
|
|
|
|
AdjustSpace
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
LEA widthSExtra(A0),A1 ;figure where space is
|
|
|
|
; Believe it or not, it is possible that QuickDraw is not around at all, so test first.
|
|
|
|
MOVE.L (A1),D7
|
|
TST.B QDExist ;is QuickDraw around
|
|
BMI.S @noQuickDraw
|
|
MOVE.L grafGlobals(A5),A0 ;get grafGlobals
|
|
MOVE.L thePort(A0),D0 ;get thePort
|
|
BEQ.S @noQuickDraw
|
|
MOVE.L D0,A0
|
|
MOVE.L spExtra(A0),D7 ;get current space extra
|
|
@noQuickDraw
|
|
MOVE.L D7,LastSpExtra ;and remember it for next time.
|
|
|
|
SUB.L (A1),D7 ;subtract old with current
|
|
BEQ.S @checkDevice ;if same, nothing to do
|
|
|
|
; D7 has the difference in the value of spaceExtra. The only problem is spaceExtra is given in screen
|
|
; coordinates but we must return stuff in font coordinate space. Thus we must scale spaceExtra before
|
|
; adding it in. FMInNumer.h FOutDenom.h
|
|
; width = ÑÑÑÑÑÑÑÑ * ÑÑÑÑÑÑÑÑ * spExtra
|
|
; FMInDenom.h FOutNumer.h
|
|
|
|
ADD.L D7,(A1) ;remember new value
|
|
|
|
SUB.W #12,SP ;make space on stack
|
|
|
|
MOVE.W FMInNumer+2(A3),-(SP) ;push x input numer
|
|
MOVE.W FMInDenom+2(A3),-(SP) ;push x input denom
|
|
_FixRatio ;compute ratio
|
|
|
|
SUBQ #4,SP ;make space for result
|
|
MOVE.W FOutDenom+2,-(SP) ;push x output denom
|
|
MOVE.W FOutNumer+2,-(SP) ;push x output numer
|
|
_FixRatio ;compute ratio
|
|
_FixMul ;calculate scale factor
|
|
|
|
MOVE.L D7,-(SP) ;push space extra
|
|
_FixMul ;scale it
|
|
|
|
; we have the adjustment factor on the stack, so add it into the table
|
|
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
MOVE.L (SP)+,D0 ;get scaled delta
|
|
ADD.L D0,4*' '(A0) ;adjust space width
|
|
|
|
; Now that we finally have everything the way we want it, let the current
|
|
; device have a crack at changing things if it wants to.
|
|
|
|
@checkDevice
|
|
MOVEQ #-1,D0 ;get lots of ones
|
|
MOVE.B FMInDevice(A3),D0 ;get the device number
|
|
BEQ.S @doneStyle ;if its the screen, we're done
|
|
|
|
; call the driver to give it a chance to change the output record
|
|
|
|
LEA paramBlk(A6),A0 ;point A0 at OS block
|
|
MOVE.W D0,IORefNum(A0) ;set up the refNum
|
|
MOVE.W #FMgrCtl1,CSCode(A0) ;set up the control code
|
|
MOVE.L A3,CSParam(A0) ;pass the input record as a parameter
|
|
MOVE.W FMInDevice(A3),CSParam+4(A0) ;pass subclass, too
|
|
_Control
|
|
|
|
; All done now so copy the input record into the current record for the next time.
|
|
|
|
@doneStyle
|
|
MOVE.L 8(A6),A3 ;point to original input record
|
|
MOVE.L A3,A0
|
|
LEA CurFMInput,A1 ;point to current record
|
|
|
|
MOVE.L (A0)+,(A1)+ ;copy first 4 bytes
|
|
MOVE.L (A0)+,(A1)+ ;copy next 4 bytes
|
|
MOVE.L (A0)+,(A1)+ ;copy next 4 bytes
|
|
MOVE.L (A0)+,(A1)+ ;copy last 4 bytes
|
|
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
CMP #-1,widthFID(A0) ;already filled out? (cache case)
|
|
BNE.S @skipFill
|
|
|
|
MOVE.B UsedFWidths,WidthUsedFam(A0);update UsedFam.
|
|
MOVE.B FOutCurStyle,WidthAFace(A0) ;update Actual Face.
|
|
|
|
LEA widthFID(A0),A1 ;point to request info (Font ID etc) in width.
|
|
BSR FamSizeInD0
|
|
MOVE.L D0,(A1)+ ;update requested Font ID and Size.
|
|
ADDQ #4,A3
|
|
MOVE.L (A3)+,(A1)+ ;update requested face and device.
|
|
CLR.B -3(A1) ;but clear the needBits field
|
|
MOVE.L (A3)+,(A1)+ ;update numer, denom
|
|
MOVE.L (A3),(A1) ; of the scale factors.
|
|
@skipFill
|
|
MOVEM.L (SP)+,D3-D7/A2-A4 ;restore work registers.
|
|
MOVE saveMap(A6),D0 ;saved resource map or 0
|
|
BEQ.S @skipSave
|
|
MOVE D0,curMap
|
|
@skipSave
|
|
UNLK A6
|
|
BRA CheckPurged
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; MapFont does all the hard work in FMSwapFont. Given a pointer to the
|
|
; font input record in A3, it normalizes the scale, finds the best set
|
|
; of bits it can and installs them into the output record.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
MapFont
|
|
SUB.L A4,A4 ;no family widths yet!
|
|
MOVE.W fmInSize(A3),D5 ;get the size in D5
|
|
MOVE.W fmInFamily(A3),D3 ;get the family
|
|
|
|
; OK, now D3 has the family we want. Now scale the size based on the current
|
|
; DotsPerInch and numer/denom and build the resource ID of the font we want
|
|
; (even though we might not have it)
|
|
|
|
CalcRealSize
|
|
SUB #14,SP ;make space for function results
|
|
MOVE.W FMDotsPerInch+2,-(SP) ;push horizontal dots/inch
|
|
MOVE.W #80,-(SP) ;push nominal dots/inch
|
|
_FixRatio ;turn into fixed point
|
|
|
|
SUBQ #4,SP ;make some room
|
|
MOVE.W fmInNumer+2(A3),-(SP) ;push horizontal numerator
|
|
MOVE.W fmInDenom+2(A3),-(SP) ;push horizontal denominator
|
|
_FixRatio ;make that a fixed point, too
|
|
_FixMul ;multiply them together.
|
|
|
|
CLR.W -(SP) ;fraction part is 0
|
|
MOVE.W D5,-(SP) ; push the size
|
|
_FixMul ;scale the size.
|
|
|
|
_FixRound ;round it off
|
|
|
|
; At this point the desired family is in D3 and the desired size is on the top of the stack. See if we have a
|
|
; family definition record for this family; if so, handle it the new way. Try to get a record of type
|
|
; <FOND,D3> into D0. Since this is sometimes speed critical, we implement a cache to skip the difficult
|
|
; resource search if we can. The FOND in the first element of the cache, WidthTabHandle, is always
|
|
; unpurgable.
|
|
|
|
TryForFond
|
|
CMP.W FondID,D3 ;same as last time
|
|
BEQ.S @sameFDef ;if so, short-circuit
|
|
|
|
MOVE.L LastFOND,A0 ;get old one (if zero, _HSetState will reject)
|
|
MOVE.B FondState,D0
|
|
_HSetState ;restore purge state
|
|
MOVE D3,D1
|
|
MOVE.W #MapTRUE,ROMMapInsert ;get from ROM if possible <10 Jul 85>
|
|
BSR GetFOND ;use common utility below (GetFontName)
|
|
BEQ.S @doneFDEFGet ;if no FOND, skip caching
|
|
|
|
; OK, we're changing the state of the cache so restore the purge state of
|
|
; the old one (if any), and make the new one unpurgable
|
|
|
|
MOVE.L (A0),A1 ;get a byte of FOND flag word and save it in low mem.
|
|
MOVE.B (A1),saveFondFlags ;bit 6 will be used to disable fractional junk.
|
|
|
|
_HGetState
|
|
MOVE.B D0,FondState ;save the old state
|
|
_HNoPurge ;make it non-purgable
|
|
@doneFDEFGet
|
|
|
|
; Check disk switch status here; better late than neverÉ
|
|
|
|
CMP.B #-1,FontFlag
|
|
BEQ Pop6SubFont ;if so, go start over.
|
|
|
|
MOVE.W D3,FONDID ;moved these two lines from above <DLD,8-19-85>
|
|
MOVE.L A0,LastFOND ;so we will cache when no FOND. <DLD,8-19-85>
|
|
|
|
; the cache worked, so fetch it from low memory
|
|
|
|
@sameFDef
|
|
MOVE.L LastFOND,D0
|
|
BNE NewFontLookUp ;if so, go look up size
|
|
CMP #512,D3 ;if greater than 511, must have FOND
|
|
BLO.S OldFontLookUp ;if in old range, use old method
|
|
BRA Pop6SubFont ;if not, start up the great substitution engine
|
|
|
|
; utility subroutine to save code -- or in the size
|
|
|
|
OrInSize
|
|
AND #$FF80,D3 ;use high nine bits from that
|
|
OR D0,D3 ;combine family and size
|
|
BSR GetFontHandle ;got it? return to caller
|
|
BVS Pop8SubFont ;go start over if disk switch hook came up.
|
|
RTS
|
|
|
|
; after all that work, the desired size is on the top of the stack. Now we'll
|
|
; use it to build the resource ID of the desired font in D3
|
|
|
|
OldFontLookUp
|
|
MOVE.W (SP)+,D0 ;get the desired size
|
|
BNE.S @notZero ;this calculated if zero, should be made 1.
|
|
MOVEQ #1,D0
|
|
@notZero
|
|
AND #$007F,D0 ;use only low 7 bits
|
|
ASL #7,D3 ;make room for size field
|
|
OR D0,D3 ;add in the size bits
|
|
MOVE D0,D7 ;save target size
|
|
|
|
; At this point, D3 has the resource ID of the font we want. See if its there.
|
|
|
|
BSR GetFontHandle ;get the font, if we can
|
|
BVS Pop4SubFont ;;go start over if disk switch hook came up.
|
|
BNE.S GotTheFont ;if we got it, stop searching
|
|
|
|
; we couldn't find the one we wanted so try for 2X and .5X for the general
|
|
; search.
|
|
|
|
MOVE.W D3,D4 ;remember where we started
|
|
|
|
MOVE D7,D0 ;get target size
|
|
CMP #64,D0 ;is it > 64?
|
|
BGE.S SkipDouble ;if so, forget about doubling
|
|
|
|
ADD D0,D0 ;compute doubled size
|
|
BSR.S OrInSize ;or in the size
|
|
BNE.S GotTheFont ;if so, use it
|
|
|
|
; well, 2X didn't work so try .5X
|
|
|
|
SkipDouble
|
|
MOVE D7,D0 ;get target size
|
|
LSR #1,D0 ;divide by 2
|
|
BCS.S SkipHalf ;if odd, we're out of luck
|
|
|
|
BSR.S OrInSize ;or in the size
|
|
BNE.S GotTheFont ;if so, go use it
|
|
|
|
; we couldn't find a 2X or 1/2X match so start scanning up. If that doesn't
|
|
; work, scan down.
|
|
|
|
SkipHalf
|
|
MOVE D4,D3 ;retreive starting place
|
|
MOVEQ #1,D6 ;search up first
|
|
TST.B FScaleDisable ;scaling disabled?
|
|
BEQ.S scanFontLoop
|
|
MOVEQ #-1,D6 ;search down then
|
|
ScanFontLoop
|
|
ADD D6,D3 ;bump to the next size
|
|
AND #$007F,D3 ;only the low 7 bits are significant
|
|
BEQ ScanDone ;if we reach zero, done direction
|
|
|
|
MOVE D4,D0 ;get the original
|
|
AND #$FF80,D0 ;mask off size
|
|
OR D0,D3 ;build new one
|
|
|
|
; see if we have this one
|
|
|
|
BSR GetFontHandle ;get the font handle if we can
|
|
BVS Pop4SubFont ;go start over if disk switch hook came up.
|
|
BEQ.S ScanFontLoop ;if we couldn't, loop again
|
|
|
|
; we found a font so install it and compute the appropriate numer/denom
|
|
;
|
|
; Numer' := Numer * requested size * DotsPerInch
|
|
; -----------------------------------------------
|
|
; Denom' := Denom * actual size * 80
|
|
;
|
|
; Font handle in A0, size in D3.
|
|
GotTheFont
|
|
MOVE.L A0,FOutFontHandle ;install the font handle
|
|
BSR BuildCharTable ;make the character (height) table
|
|
|
|
SUBQ #4,SP ;make room for result
|
|
MOVE fmInSize(A3),-(SP) ;push desired size
|
|
MOVE D3,-(SP) ;push actual size
|
|
AND #$007F,(SP) ;use only low 7 bits
|
|
_FixRatio ;make it a fixed point number.
|
|
MOVE.L (SP)+,D6 ;keep size scale in D6
|
|
|
|
BSR DerefWidthTab ;get pointer to width table in A0
|
|
MOVE.W D3,WidthASize(A0) ;save actual size in width table.
|
|
MOVE.L FOutFontHandle,WidTabFont(A0)
|
|
|
|
MOVEQ #0,D5 ;first do the vertical
|
|
BSR.S MapScale ;calculate numer.v/denom.v
|
|
MOVEQ #2,D5 ;now do the horizontal
|
|
|
|
; compute the new numer/demon as a fixed point number, then rationalize it
|
|
; and stick it where it belongs
|
|
|
|
MapScale
|
|
SUB #12,SP ;make some space for results *** was 12 ***
|
|
MOVE.W fmInNumer(A3,D5),-(SP) ;push the numer
|
|
MOVE.W fmInDenom(A3,D5),-(SP) ;push the denom
|
|
_FixRatio ;compute the ratio.
|
|
|
|
SUBQ #4,SP ;make room for result
|
|
LEA FMDotsPerInch,A0 ;point to the dots/inch factor
|
|
MOVE.W 0(A0,D5),-(SP) ;push the dots/inch
|
|
MOVE.W #80,-(SP) ;the screen is 80 dots/inch
|
|
_FixRatio ;make it a rational number.
|
|
_FixMul ;multiply them together.
|
|
MOVE.L D6,-(SP) ;push the size scale
|
|
_FixMul ;multiply that in, too.
|
|
|
|
|
|
LEA FOutNumer,A0 ;point to the place to stuff result
|
|
MOVE.L (SP)+,D0 ;get the fixed point result
|
|
ADD.L #$80,D0 ;*** round it up
|
|
LSR.L #8,D0 ;take the middle 16 bits
|
|
|
|
MOVE.W D0,0(A0,D5) ;store the numerator
|
|
|
|
MOVE.W #256,4(A0,D5) ;the denom is 256
|
|
|
|
MOVE.L FPointOne,D1 ;set up FScaleHFact, FScaleVFact when disabled
|
|
TST.B FScaleDisable ;scaling disabled?
|
|
BEQ.S GoScaleLess ;if not, skip
|
|
|
|
MOVEQ #0,D1 ;zero top half of scale factor
|
|
MOVE.W D0,D1 ;remember it
|
|
MOVE #256,D0 ;start value for numerator
|
|
@2
|
|
CMP #512,D1 ; scale up > 2 x
|
|
BLO.S @4
|
|
|
|
ASL #1,D0 ; multiply numer by two
|
|
ASR #1,D1 ; divide scale factor by two
|
|
BRA.S @2
|
|
@4
|
|
CMP #192,D1 ; scale down < .75?
|
|
BHS.S @6
|
|
|
|
ASR #1,D0 ; multiply by 1/2
|
|
ASL #1,D1 ; divide by 1/2
|
|
BRA.S @4
|
|
@6
|
|
CMP #256,D1 ; scale down between 1x and 2x
|
|
BHS.S @doneScale
|
|
|
|
MOVE D0,D2 ; * 3
|
|
ADD D0,D0
|
|
ADD D2,D0
|
|
ASR #2,D0 ; multiply by 3/4ths
|
|
ASL #2,D1 ; divide by 3/4ths
|
|
DIVU #3,D1
|
|
EXT.L D1
|
|
@doneScale
|
|
MOVE.W D0,0(A0,D5) ;stuff numer
|
|
ASL.L #8,D1 ;fixate scale factor
|
|
|
|
; scaling is disabled so calculate the width factor adjustment
|
|
GoScaleLess
|
|
TST D5 ;horizontal?
|
|
BEQ.S @didVChange ;if not, skip
|
|
|
|
MOVE.L D1,FScaleHFact ;save new scale factor
|
|
BRA.S @scaleless
|
|
|
|
; compute vertical scaling factor too
|
|
|
|
@didVChange
|
|
MOVE.L D1,FScaleVFact ; record new V factor
|
|
@scaleless
|
|
MOVE.L WidthTabHandle,A1
|
|
MOVE.L (A1),A1 ;and remember it in the width table too.
|
|
LEA WidthVOutput(A1),A1
|
|
MOVE.W D0,0(A1,D5)
|
|
ASR.L #8,D1 ;shift scale factor back to a word.
|
|
MOVE.W D1,WidthVFactor-WidthVOutput(A1,D5)
|
|
|
|
RTS ;second time through, this ends MapFont
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; At this point, we've scanned all we can in one direction. If scaling is not allowed, then we started
|
|
; scanning down so now we must scan up; the opposite is true if scaling is allowed. If we have scanned
|
|
; in both directions, then start up the great font substitution machine.
|
|
|
|
ScanDone
|
|
TST.B FScaleDisable ; scaling disabled?
|
|
BEQ.S @0
|
|
NEG D6 ;negate the direction
|
|
BMI.S Pop4SubFont ;if negative now, we must substitute
|
|
BRA.S @1 ; go on
|
|
@0
|
|
NEG D6 ;negate the direction
|
|
BPL.S Pop4SubFont ;if positive now, we must substitute
|
|
@1
|
|
MOVE D4,D3 ;start with the target again
|
|
BRA ScanFontLoop ;try our luck scanning down
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
;A word or two about font substitution:
|
|
;
|
|
; FontFlag is set to the current substitution level. If we get to SubFont, then the font requested is not
|
|
; available, or the disk switch hook drew in the system font while loading the requested FOND, FONT or
|
|
; NFNT. The value in FontFlag indicates what just happened, and what should be substituted next:
|
|
; -2 = The LoadResource failed at CheckPurged, although the font is the same one returned the last
|
|
; time SwapFont was called. (Maybe the user filled up memory, purging a large font.) Try for
|
|
; the same font again, so that a family-related substitute will be returned.
|
|
; -1 = The code was re-entered by the SysError (either a real problem or the disk switch hook.) The
|
|
; requested FOND, NFNT, or FONT may have been loaded, but the cache & low memory is no good.
|
|
; Try for the same font again.
|
|
; 0 = The requested font is not available, nor any reasonable family-related substitute. Try the
|
|
; ApFontID, if it is in the same neighborhood.
|
|
; 2 = The ApFontID family is not available. Try the base of the neighborhood.
|
|
; 4 = The base of the neighborhood is not available (Geneva, for the Roman neighborhood). Try the
|
|
; SysFontFam if it is in the same neighborhood.
|
|
; 6 = The SysFontFam family is not available. Try Font 0, setting curMap to the system map.
|
|
; 8 = (Disk switch only.) Give Chicago 12 a shot (same as 6).
|
|
|
|
|
|
; we have to substitute; use either the application or system font.
|
|
; Substitution order is:
|
|
; if the apFontID is in the same neighborhood as the requested font, use it.
|
|
; if not, or not available, use the base of the neighborhood (Geneva if the neighborhood is Roman.)
|
|
; if not available, use the sysFontFam, but only if it is in the same neighborhood as the request.
|
|
; if not, or not available, use the ROM font (hard coded to family 0, Chicago.)
|
|
|
|
Pop8SubFont
|
|
ADDQ #2,SP ;entry for throwing 2 return addresses away
|
|
Pop6SubFont
|
|
ADDQ #2,SP ;entry for throwing away scaled size, return address
|
|
Pop4SubFont
|
|
ADDQ #4,SP ;throw away return address for next time through
|
|
SubFont
|
|
; determine which to go to next
|
|
MOVE (A3),D3 ;set up font family
|
|
MOVEQ #0,D0
|
|
MOVE.B FontFlag,D0
|
|
BPL.S @noDiskSwitch
|
|
BSR InvalWidthTab ;otherwise, toss first cache entry
|
|
CLR.B FontFlag ;set up to 0 to start all over
|
|
BRA.S @skipDispatch
|
|
@noDiskSwitch
|
|
ADDQ.B #2,FontFlag
|
|
MOVE SubJump(D0),D0
|
|
JSR SubJump(D0)
|
|
@skipDispatch
|
|
MOVE.L 8(A6),A1 ;get pointer to original input record
|
|
MOVE D3,fmInFamily(A3) ;set up new substitute family
|
|
MOVE fmInSize(A1),fmInSize(A3) ;copy size since may have to map to system font.
|
|
BRA TryAgain
|
|
|
|
SubJump DC.W tryApFontID-SubJump ;0
|
|
DC.W tryNeighborhoodBase-SubJump ;2
|
|
DC.W trySysFontFam-SubJump ;4
|
|
DC.W tryChicago-SubJump ;6
|
|
DC.W tryChicago-SubJump ;8
|
|
|
|
; Use apFontID if it is in the same neighborhood.
|
|
tryApFontID
|
|
MOVE ApFontID,D1
|
|
checkNeighborhood ;common entry point for system family as well.
|
|
MOVEQ #9,D2 ;convenient constant
|
|
LSR D2,D1
|
|
SUB #31,D1
|
|
BPL.S @apForiegn
|
|
MOVEQ #0,D1
|
|
@apForiegn
|
|
MOVE D3,D0 ;copy family
|
|
LSR D2,D0 ;divide by 512 (unsigned)
|
|
SUB #31,D0 ;first $4000 is Roman, rest are neighborhoods
|
|
BPL.S @notRoman
|
|
MOVEQ #0,D0 ;Roman is 0, first neighborhood 1, etc.
|
|
@notRoman
|
|
CMP D0,D1 ;is apFontID in the same neighborhood as D3?
|
|
BNE.S Pop4SubFont ;if not, use next substitution method
|
|
MOVE ApFontID,D3
|
|
RTS
|
|
|
|
; Use the base of the neighborhood.
|
|
tryNeighborhoodBase
|
|
CMP #$4000,D3
|
|
BLO.S @mustBeRoman
|
|
AND #$FE00,D3 ;base is neighborhood & ~512
|
|
RTS
|
|
@mustBeRoman
|
|
MOVEQ #3,D3 ;hard code to Geneva
|
|
RTS
|
|
|
|
; Use the SysFontFam if it is in the same neighborhood.
|
|
trySysFontFam
|
|
MOVE SysFontFam,D1
|
|
BRA.S checkNeighborhood
|
|
|
|
; This entry point is called from the top of SwapFont if from within SysError we failed.
|
|
GoTryChicago
|
|
LINK A6,#stackFrame
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;save work registers
|
|
MOVE.L 8(A6),A3 ;get input pointer
|
|
BSR.S tryChicago
|
|
BRA MoreDifFont
|
|
|
|
; Use the ROM font.
|
|
; have to be very careful here that D3 is not later substituted
|
|
tryChicago
|
|
MOVE CurMap,saveMap(A6) ;save the current map
|
|
MOVE SysMap,CurMap ;hard code to the system map
|
|
MOVEQ #0,D3 ;hard code to Chicago
|
|
RTS
|
|
|
|
|
|
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; SetNewDevice is called when we notice that the device has changed.
|
|
; If the device is 0 (the screen), fill out the info ourselves,
|
|
; otherwise make a status call to the driver to get it. Called only in DifFont after noting that the device
|
|
; has changed.
|
|
|
|
SetNewDevice
|
|
IF patch THEN
|
|
IF onMac THEN
|
|
JMP $40EE82
|
|
ELSEIF onMacPP THEN
|
|
JMP $419A9A ; *NB Patch* need addresses for both SE and Plus.
|
|
ENDIF
|
|
ELSE
|
|
TST D0 ;is it the screen?
|
|
BEQ.S SetScreenDevice ;if so, no need to call the driver
|
|
|
|
MOVEQ #-1,D0 ;get some ones
|
|
MOVE.B fmInDevice(A3),D0 ;build the refNum
|
|
|
|
MOVEQ #IOQElSize,D1 ;get size of pBlock
|
|
SUB.L D1,SP ;make space for control record
|
|
|
|
LEA IORefNum(SP),A0 ;point A0 at OS block
|
|
MOVE.W D0,(A0)+ ;set up the refNum
|
|
MOVE.W #FMgrCtl1,(A0)+ ;set up the control code
|
|
LEA FMDotsPerInch,A1 ;get place to stash info
|
|
MOVE.L A1,(A0)+ ;tell the driver about it
|
|
MOVE.W fmInDevice(A3),(A0)+ ;pass subclass, too
|
|
MOVE.L SP,A0 ;point A0 at pBlock
|
|
_Status ;ask the driver
|
|
|
|
ADD.L D1,SP ;pop off parameter block
|
|
RTS
|
|
ENDIF
|
|
|
|
; Set up parameters for the screen
|
|
|
|
SetScreenDevice
|
|
IF patch THEN
|
|
IF onMac THEN
|
|
JMP $40EEAC
|
|
ELSEIF onMacPP THEN
|
|
JMP $419AC4 ; *NB Patch* need addresses for both SE and Plus.
|
|
ENDIF
|
|
ELSE
|
|
LEA FMDotsPerInch,A1 ;get place to stash info
|
|
LEA ScreenStyleTab,A0 ;point to the info
|
|
MOVEQ #28,D0 ;28 bytes of info to move
|
|
_BlockMove ;move it in
|
|
RTS
|
|
ENDIF
|
|
|
|
; we found it, but better make sure we can load it
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
;
|
|
; Four ways to get a font handle:
|
|
;
|
|
; GetStrike: returns handle to unloaded FONT to get resource attributes of ID passed in D1.
|
|
; GetFontHandle: returns handle to loaded FONT passed in D3.
|
|
; GoLoadStrike: returns handle to loaded FONT or NFNT inside FOND offset in A0.
|
|
; LoadNewStrike: returns handle to loaded FONT or NFNT passed in D0.
|
|
;
|
|
; All routines return the font handle in A0 and D0, with the Z-flag set to reflect if it is nil.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
GoLoadStrike
|
|
MOVE.L (A0),D0 ;get style/ID words from FOND
|
|
MOVE.L D0,styleID(A6) ;remember for later
|
|
LoadNewStrike
|
|
MOVE.W #MapTRUE,ROMMapInsert ;ResLoad True for GetResource <10 july 85>
|
|
LoadNoROM
|
|
MOVE D0,-(SP) ;preserve ID
|
|
|
|
SUBQ #4,SP
|
|
MOVE.L #'NFNT',-(SP) ;push NFNT
|
|
MOVE.W D0,-(SP)
|
|
_GetResource ;got it?
|
|
MOVE.L (SP)+,D0
|
|
BEQ.S fontOnlyLoad ;if not, look for FONT
|
|
ADDQ #2,SP ;don't need original ID
|
|
BRA.S weGotIt ;return z clear, handle in D0.
|
|
|
|
; we couldn't find the NFNT, so look for a FONT
|
|
; Change GetStrike to GetResource with loading off, in order to get handle, but to bypass doomed GetHandleSize. <PBM164>
|
|
GetStrike
|
|
MOVE.W #MapFALSE,ROMMapInsert ;don't load the font <10 July 85>
|
|
SUBQ #4,SP ;make space for function result <PBM164>
|
|
MOVE.L #'FONT',-(SP) ;'FONT' is resType
|
|
MOVE.W D1,-(SP) ;push ID
|
|
_GetResource
|
|
MOVE.L (SP)+,D0 ;get the love handle
|
|
BRA.S weGotIt ;use common code
|
|
GetFontHandle
|
|
MOVE D3,-(SP)
|
|
fontOnlyLoad
|
|
MOVE.W #MapTRUE,ROMMapInsert ;get FONT from ROM if possible <10july 85>
|
|
MOVE (SP)+,D0 ;recover ID
|
|
SUBQ #4,SP ;make space for function result
|
|
MOVE.L #'FONT',-(SP) ;'FONT' is resType
|
|
MOVE.W D0,-(SP) ;push ID
|
|
_GetResource
|
|
|
|
; But wait! What if we didnÕt get a font at all? (Most probably because of some quirk of data in FOND, we just asked
|
|
; for and got the zero size FONT, which exists only in name.)
|
|
|
|
MOVE.L (SP)+,D0 ;sets Z flag
|
|
BEQ.S @weDidntGetIt ;if missing, skip checking size
|
|
MOVE.L D0,-(SP) ;protect handle from resource manager call
|
|
SUBQ #4,SP ;make room for function result
|
|
MOVE.L D0,-(SP)
|
|
_MaxSizeRsrc ;<1July87>
|
|
|
|
; A font with a single character has a $1A header, at least a 1 word strike, 2 word loc table, 2 entry o/w table, thus:
|
|
;
|
|
; Since Radius returns a 16 point system font which is not a resource, errors from MaxSizeRsrc
|
|
; are ignored.
|
|
|
|
CMP.L #$24,(SP)+ ;is it smaller than the minimal size
|
|
SLO D0 ;set D0 if it is too small to be useful
|
|
MOVE.L (SP)+,A0 ;restore handle to font
|
|
BRA.S setZBit
|
|
@weDidntGetIt
|
|
weGotIt
|
|
MOVE.L D0,A0 ;return it in A0
|
|
SEQ D0 ;save Z flag
|
|
setZBit
|
|
AND #4,D0 ;set only Z bit
|
|
CMP.B #-1,FontFlag ;was there a disk switch?
|
|
BNE.S @noDskSwitch ;if not, leave V flag clear
|
|
BSET #1,D0 ;set V bit
|
|
@noDskSwitch
|
|
MOVE D0,CCR ;return V set if switch, Z set if no resource
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; FindSize is a utility the scans the font family data structure for the
|
|
; size that's passed in D3. It uses the famDef handle in A2.
|
|
; >> rather than implied return for GoLoadStrike, may need to check FontFlag for -1.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
FindSize
|
|
MOVE.L (A2),A0 ;handle->pointer
|
|
LEA FONDAssoc(A0),A0 ;bump past header
|
|
MOVE.W (A0)+,D1 ;get the # of entries
|
|
@fSizeLoop
|
|
CMP.W (A0)+,D3 ;this the one?
|
|
BEQ.S GoLoadStrike ;if so, go load it (code above)
|
|
BLT.S @cantFind ;if too big, too late
|
|
|
|
ADDQ #FAssocSiz-2,A0 ;bump to next entry
|
|
DBRA D1,@fSizeLoop ;check them all out
|
|
@cantFind
|
|
MOVEQ #0,D0 ;z-flag set, return NIL
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; NewFontLookUp is passed the family definition record in D0 and the
|
|
; desired size on the top of the stack. It decides on the best strike
|
|
; to use, then uses common code to finish up.
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
NewFontLookUp
|
|
MOVE.W (SP)+,D5 ;get desired size
|
|
MOVE.L D0,A2 ;keep fDef handle in A2
|
|
|
|
; first go for an exact match
|
|
|
|
MOVE D5,D3
|
|
BSR.S FindSize
|
|
BVS.S NewFailed
|
|
BNE.S GoFoundTheSize
|
|
|
|
; if FScaleDisable is on, don't bother to look for 2X and .5X first
|
|
|
|
TST.B FScaleDisable
|
|
BNE.S FindClosest
|
|
|
|
; now try for the one that's twice the size
|
|
|
|
ADD.W D3,D3
|
|
BSR.S FindSize
|
|
BVS.S NewFailed
|
|
BNE.S GoFoundTheSize
|
|
|
|
; try for the half-size one
|
|
|
|
MOVE D5,D3
|
|
LSR #1,D3
|
|
BCS.S FindClosest ;skip if the original size is odd.
|
|
BSR.S FindSize
|
|
BVS.S NewFailed
|
|
GoFoundTheSize
|
|
BNE.S FoundTheSize
|
|
|
|
; oh, well, beggars can't be choosers. Scan to find the closest one
|
|
; in size
|
|
|
|
FindClosest
|
|
MOVE.L (A2),A0 ;point to famDef
|
|
LEA FONDAssoc(A0),A0 ;point to size list
|
|
MOVE.W (A0)+,D4 ;get # of entries-1
|
|
MOVEQ #0,D1 ;no font yet
|
|
; << note the unnecessary limit of the 127 point size
|
|
; *** letÕs try 32767 instead
|
|
MOVE #$7FFF,D2 ;closest delta so far
|
|
Scan4SizeLoop
|
|
MOVE.W D5,D0 ;get one we want <DLD-12-Sep-85>
|
|
SUB.W (A0),D0 ;compute delta
|
|
BPL.S @2
|
|
|
|
TST.B FScaleDisable ; scaling disabled?
|
|
BEQ.S @1 ; if so, see if we've got one lower
|
|
TST D1 ; if so, skip town
|
|
BNE.S sizeFound ; because we want to scale up
|
|
@1
|
|
NEG.W D0 ;absolute value
|
|
@2
|
|
CMP D2,D0 ;closest one yet
|
|
BGT.S NxtSizeLoop ;if not, skip
|
|
MOVE D0,D2 ;remember it
|
|
MOVE (A0),D1 ;remember font, too
|
|
NxtSizeLoop
|
|
ADDQ #FAssocSiz,A0 ;bump to next entry
|
|
DBRA D4,Scan4SizeLoop ;search them all
|
|
sizeFound
|
|
MOVE D1,D3 ;get best alternative
|
|
BSR.S FindSize ;try to get it...
|
|
BVS.S NewFailed
|
|
BEQ.S NewFailed ;if canÕt get it, skip
|
|
|
|
; OK, we found the size so now worry about the style. The Font handle is
|
|
; in D0.
|
|
|
|
FoundTheSize
|
|
MOVE.L A0,D0 ;save the font handle in D0
|
|
MOVE.L (A2),A0 ;handle->pointer
|
|
LEA FONDAssoc(A0),A0 ;skip header
|
|
MOVE.W (A0)+,D1 ;fetch # of entries
|
|
FTSLoop
|
|
CMP.W (A0),D3 ;search for matching size
|
|
BEQ.S GotEntry
|
|
ADDQ #FAssocSiz,A0
|
|
DBRA D1,FTSLoop
|
|
;when could this ever fall through?
|
|
|
|
NewFailed ;we can't find any in the family FOND record so try the old way
|
|
MOVE D5,-(SP) ;put size on stack
|
|
MOVE (A3),D3 ;get the requested family
|
|
BRA OldFontLookUp
|
|
|
|
; Modification history:
|
|
; 13-Aug-86 CRC Fixed bugs with uninitialized FOND entry pointer, looking at data past end of FOND.
|
|
;
|
|
|
|
; Registers used:
|
|
; D0 = handle to font (input) D1 = left in assoc. table (input) D2 = user style descriptor, scratch
|
|
; D3 = actual size (input) D4 = best style weight, temp. D5 = scratch
|
|
; D6 = FOND style descriptor D7 = scratch A0 = FOND data pointer (input)
|
|
; A1 = best style entry A2 = handle to FOND A3 = input record
|
|
; A4 = offset to width table in FOND
|
|
;
|
|
; A0 points to the first entry of this size in the FOND, but maybe the FOND contains a stylized font that
|
|
; is better. Loop through to pick up the best qualifying one. The first font in the actual
|
|
; size pointed to by the FOND has already been successfully loaded, and is pointed to by D0.
|
|
|
|
; Both this routine and the earlier call to FindSize only make one call to GetResource; if that call fails,
|
|
; then other styles in the same size are not tried before going on to other methods of font substitution.
|
|
; A major reorganization of the code should include a thorough family search, retrying after failure until
|
|
; the family has been exhausted.
|
|
|
|
; >>> Styleweights needs to be driver supplied, at least for alternate display devices?
|
|
; StyleWeights is a table of weights for the font style bits, to determine which strike to display on
|
|
; the screen. Styles not provided by the strike returned are generated by QuickDraw.
|
|
|
|
StyleWeights
|
|
DC.B 4 ;weight for bold
|
|
DC.B 8 ;weight for italic
|
|
DC.B 1 ;weight for underline
|
|
DC.B 3 ;weight for outline
|
|
DC.B 3 ;weight for shadow
|
|
DC.B 2 ;weight for condensed
|
|
DC.B 1 ;weight for extended
|
|
DC.B 0 ;bit 7 unused
|
|
|
|
|
|
GotEntry
|
|
MOVEQ #0,D2 ;zero high byte of style
|
|
ADDQ #2,A0 ;point to style field
|
|
MOVEQ #-2,D4 ;init best metric
|
|
MOVE.B fmInFace(A3),D2 ;get style we want
|
|
@selectStyleLoop
|
|
MOVE.W (A0),D6 ;get style descriptor (want low byte only)
|
|
CMP D6,D2 ;do they match?
|
|
BNE.S @noStyleMatch
|
|
MOVE.L A0,A1 ;if so, we've got it!
|
|
BRA.S @foundMatch0
|
|
@noStyleMatch
|
|
MOVEQ #-1,D5 ;take the first entry for starters
|
|
MOVE D2,D7
|
|
NOT D7
|
|
AND D6,D7 ;can we use it?
|
|
BNE.S @nextStyle ;if not, skip
|
|
|
|
; it qualifies, so determine its weighting
|
|
|
|
MOVEQ #0,D5 ;initial weight is 0
|
|
MOVEQ #7,D7 ;start with bit 8
|
|
AND D2,D6 ;only bits set in both request & available
|
|
@styMagLoop
|
|
ASL.B #1,D6 ;bit set?
|
|
BCC.S @nextStyMag ;if not, skip
|
|
ADD.B StyleWeights(D7),D5 ;add in weight
|
|
@nextStyMag
|
|
DBRA D7,@styMagLoop ;loop for 8 bits
|
|
|
|
; OK, now see if the resulting weight (in D1) is the biggest so far
|
|
|
|
@nextStyle
|
|
CMP D5,D4 ;best so far?
|
|
BGE.S @loopBottom ;if not, forget it!
|
|
|
|
; its the biggest so far, so remember it
|
|
|
|
MOVE D5,D4 ;remember metric value
|
|
MOVE.L A0,A1 ;remember entry
|
|
|
|
; if we have more to consider, go handle them
|
|
|
|
@loopBottom
|
|
|
|
ADDQ #FAssocSiz-2,A0 ;bump to next entry
|
|
CMP.W (A0)+,D3 ;next one same size?
|
|
DBNE D1,@selectStyleLoop ;if not, or if out of entries, decide the style
|
|
|
|
; no more of this size so the winner is the one pointed to by A1. If the
|
|
; ID is the same as the one we already got, we don't have to get it
|
|
; again
|
|
|
|
@foundMatch0
|
|
MOVE.W (A1)+,D6 ;get the style of winner
|
|
MOVE.W styleID+2(A6),D1 ;get resID of one in D0
|
|
CMP.W (A1),D1 ;do we already have it?
|
|
MOVE.L D0,A0 ;keep fontHandle from now on in addr. reg.
|
|
BEQ.S @foundItAll ;if so, don't have to load
|
|
|
|
; it changed, so we have to get it again
|
|
|
|
MOVE.L A0,D4 ;remember old fonHandle
|
|
|
|
MOVE.W (A1),D0 ;get ID
|
|
BSR LoadNewStrike ; << this is the only call to this subroutine,
|
|
; << but it is inside goLoadStrike (which is
|
|
; << also called only once.)
|
|
; << uses only A0, D0
|
|
BVS.S NewFailed ;disk switch, oh no.
|
|
BNE.S @foundItAll
|
|
|
|
@noTweakedFont
|
|
; we couldn't load it, so stick with the old one
|
|
|
|
MOVE.L D4,A0 ;recover fontHandle
|
|
MOVE.W styleID(A6),D6 ;recover style
|
|
|
|
; OK, the fontHandle is in D0 and its style is in D6. Set up FOutCurStyle
|
|
; with the proper value, and dive back in to the font manager proper.
|
|
|
|
@foundItAll
|
|
NOT D6 ;invert mask of what we got
|
|
AND.B D6,FOutCurStyle ;turn off built-in properties
|
|
|
|
; at this point D6 has the inverse of the style we actually got. A2 has
|
|
; the family definition record handle. Look for a matching width table;
|
|
; if we got one, return its offset in A4.
|
|
|
|
MOVE.L (A2),A1 ;point to famDef
|
|
|
|
MOVE.W FONDLast(A1),D1 ;get lastChar
|
|
BEQ.S @noFamWidths ;if zero, must be a ÒnullÓ FOND set up by Font/DA Mover
|
|
|
|
SUB.W FONDFirst(A1),D1 ;compute # of chars-1
|
|
ADDQ #4,D1 ;compute word size of wTab (include style wd.)
|
|
ADD.W D1,D1 ;compute size of table
|
|
|
|
MOVE.L FONDWTabOff(A1),D0 ;get offset to widthTabs
|
|
BEQ.S @noFamWidths ;if none, skip
|
|
|
|
ADD.L D0,A1 ;point to the width tables
|
|
MOVE.W (A1)+,D2 ;get # of tables-1
|
|
BMI.S @noFamWidths ;skip if none
|
|
|
|
; here's the loop where we search for the appropriate family width table
|
|
; >> Adobe pointed out a bug here. If the FOND has a style width table, but the style screen font is not
|
|
; >> around, the plain width table will be used incorrectly. The right solution is for the styles to be
|
|
; >> searched and compared on a weighted basis just like the screen styles, except for the weights are
|
|
; >> different. Bold first, Condensed next, and Italic third? What about the idea of masking out
|
|
; >> underline, outline, shadow, and always forcing stylistic extras to be used, unless an exact match
|
|
; >> is found?
|
|
; >> Certainly, if a style width has styles outside of the requested style, it can not be used.
|
|
|
|
; >> Although this code is very similar to the screen font code above, I canÕt see any trival way of
|
|
; >> rolling them together. For one, all registers are used.
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; bug fix, implemented as a patch on Aladdin - the problem is that FOND widths will only be used
|
|
; if FractEnable is true; otherwise, the widths will be gotten from the strike.
|
|
; probably can skip this whole mess if FractEnable is false ---
|
|
IF bugFix THEN
|
|
@srchFamWTab
|
|
MOVEQ #-1,D4 ;best match found so far
|
|
TST.B FractEnable ;are fractions allowed?
|
|
BNE.S @useBestStyle ;if so, use the best width table around
|
|
NOT D6 ;reverse strike style once more
|
|
MOVE D6,-(SP) ;use width table equivalent to strike
|
|
BRA.S @nextFamWTab
|
|
@useBestStyle
|
|
MOVEQ #0,D0 ;zero high word
|
|
MOVE.B fmInFace(A3),D0 ;get original requested style
|
|
MOVE D0,-(SP) ;push it
|
|
@nextFamWTab
|
|
MOVE (SP),D0 ;get the style word
|
|
ELSE
|
|
@srchFamWTab
|
|
MOVEQ #-1,D4 ;best match found so far
|
|
MOVEQ #0,D0 ;zero high byte of style
|
|
@nextFamWTab
|
|
MOVE.B fmInFace(A3),D0 ;get original requested style
|
|
ENDIF
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
CMP (A1),D0 ;exact match?
|
|
BEQ.S @figureWidthPos ;donÕt worry no more
|
|
NOT D0 ;set all cleared bits
|
|
AND (A1),D0 ;nonzero if style in width is not in request
|
|
BNE.S @wrongFamWidths ;donÕt consider widths with too much info.
|
|
MOVEQ #0,D5 ;accumulated weight
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; more of the same bug fix
|
|
IF bugFix THEN
|
|
MOVE (SP),D0
|
|
ELSE
|
|
MOVE.B fmInFace(A3),D0 ;bits in requested style
|
|
ENDIF
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
AND (A1),D0 ;and in available bits
|
|
MOVEQ #7,D7 ;number of bits in style byte
|
|
@nextBit
|
|
ASL.B #1,D0 ;
|
|
BCC.S @skipWeight ;
|
|
ADD.B widthWeights(D7),D5
|
|
@skipWeight
|
|
DBRA D7,@nextBit ;if no carry and not zero, go to next bit
|
|
CMP D5,D4
|
|
BGE.S @wrongFamWidths
|
|
MOVE D5,D4 ;save best
|
|
MOVE.L A1,D6 ;location of best width found so far
|
|
@wrongFamWidths
|
|
ADD D1,A1 ;advance to next table entry
|
|
DBRA D2,@nextFamWTab
|
|
TST D4
|
|
BMI.S @tossStackSpace ;<1July87>
|
|
MOVE.L D6,A1
|
|
@figureWidthPos
|
|
MOVE (A1)+,fwidStyle(A6) ;keep best found style
|
|
SUB.L (A2),A1
|
|
MOVE.L A1,A4
|
|
@tossStackSpace
|
|
IF bugFix THEN
|
|
ADDQ #2,SP
|
|
ENDIF
|
|
@noFamWidths
|
|
BRA GotTheFont ;dive back in
|
|
|
|
; output registers: (double dashes indicate registers are written before read)
|
|
; D0 = -- D1 = -- D2 = --
|
|
; D3 = actual size (input) D4 = -- D5 = --
|
|
; D6 = -- D7 = -- A0 = handle to font (input)
|
|
; A1 = -- A2 = -- A3 = input record
|
|
; A4 = offset to width table in FOND
|
|
|
|
; end of GotEntry
|
|
|
|
; WidthWeights are used to determine which width table in the FOND is the best approximation of the
|
|
; requested style widths. Styles not provided by the FOND width table are added in from the FOND values
|
|
; in style extra.
|
|
|
|
WidthWeights
|
|
DC.B 1 ;weight for bold
|
|
DC.B 3 ;weight for italic
|
|
DC.B 5 ;weight for underline
|
|
DC.B 4 ;weight for outline
|
|
DC.B 4 ;weight for shadow
|
|
DC.B 2 ;weight for condensed
|
|
DC.B 2 ;weight for extended
|
|
DC.B 0 ;bit 7 unused
|
|
|
|
|
|
FPointOne DC.W 1
|
|
DC.W 0
|
|
|
|
|
|
; PROCEDURE GetFontName(familyID: INTEGER; VAR theName: Str255);
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (GetFontName) (GetFontName)
|
|
;
|
|
; Get the name of the font, given the family ID
|
|
|
|
GetFontName
|
|
|
|
; first check if we have a family definition record
|
|
MOVE.L (SP)+,A1 ;save return address
|
|
MOVE.L (SP)+,D2 ;save pointer to string
|
|
MOVE.W (SP)+,D1 ;get the requested family ID
|
|
MOVE.W #MapFALSE,ROMMapInsert ;set ResLoading False <10 Jul 85>
|
|
BSR.S GetFONDMap ;is there a FOND for this family?
|
|
BNE.S @askForName ;if so, skip
|
|
|
|
; make sure the ID is in range
|
|
|
|
CMP.W #512,D1 ;ID in range?
|
|
BCC.S @returnNilString ;if not, skip
|
|
|
|
; no luck, so try it the old way
|
|
|
|
ASL #7,D1 ;set size field to 0
|
|
BSR GetStrike ;get the fontHandle
|
|
BEQ.S @returnNilString ;if NIL, return empty string
|
|
@askForName
|
|
MOVE.L A0,-(SP) ;push the resource handle
|
|
CLR.L -(SP) ;no place for ID (don't care)
|
|
CLR.L -(SP) ;no place for type (don't care)
|
|
MOVE.L D2,-(SP) ;place for name (where app wants)
|
|
MOVE.W #MapFALSE,ROMMapInsert ;get from ROM if possible <10 Jul 85>
|
|
_GetResInfo ;get it!
|
|
BRA.S @doneGetFName ;all done
|
|
|
|
@returnNilString
|
|
MOVE.L D2,A0 ;get the string pointer
|
|
CLR.B (A0) ;make it NIL
|
|
|
|
@doneGetFName
|
|
JMP (A1) ;return to caller
|
|
|
|
|
|
; Common code used by GetFontName and RealFont. GetFOND entry point is used by TryFOND.
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (GetFONDMap) (GetFONDMap)
|
|
;
|
|
; Need to map D1 into proper ID if 0 or 1
|
|
|
|
GetFONDMap
|
|
TST D1
|
|
BNE.S @notSysFont
|
|
MOVE SysFontFam,D1
|
|
BRA.S GetFOND
|
|
@notSysFont
|
|
CMP #1,D1 ;is it the same as the apFontID?
|
|
BNE.S GetFOND
|
|
MOVE ApFontID,D1
|
|
GetFOND
|
|
SUBQ #4,SP
|
|
MOVE.L #'FOND',-(SP) ;push type "FOND"
|
|
MOVE.W D1,-(SP) ;push the ID
|
|
_GetResource ;look for it
|
|
MOVE.L (SP)+,D0
|
|
MOVE.L D0,A0
|
|
RTS
|
|
|
|
|
|
; FUNCTION RealFont(famID: INTEGER; size: INTEGER): BOOLEAN;
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (RealFont) (RealFont)
|
|
;
|
|
; RealFont is a boolean function that returns true if we have a real bitmap
|
|
; (as opposed to a stretched one) for the requested font
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 26-Aug-86 CRC Use same substitution scheme as SwapFont. Do not play with cache state
|
|
; anymore.
|
|
|
|
RealFont
|
|
MOVE.L (SP)+,A1 ;save return address
|
|
MOVE.W (SP)+,D2 ;get size
|
|
BNE.S @notSizeZero ;if nonzero, no prob with Bob
|
|
TST (SP) ;sysFontFam?
|
|
BNE.S @notSysFont ;if not, use FMDefaultSize
|
|
MOVE SysFontSize,D2 ;must be 0,0
|
|
BNE.S @notSizeZero ;if non zero, it is fine
|
|
@notSysFont
|
|
MOVEQ #0,D2 ;zero high order byte
|
|
MOVE.B FMDefaultSize,D2 ;pick up preset default
|
|
BNE.S @notSizeZero ;take it as long as it is not zero.
|
|
MOVEQ #12,D2 ;hardcode to 12 if low memory is no help
|
|
@notSizeZero
|
|
MOVE.W (SP)+,D1 ;get the font family
|
|
CLR.W (SP) ;assume we don't have it (set result false)
|
|
MOVE.W #MapTRUE,ROMMapInsert ;set ResLoading True
|
|
BSR.S GetFONDMap ;is there a FOND for this family?
|
|
BEQ.S @oldKindOfFont ;if not, try for old
|
|
|
|
; we have a family definition record (handle in D0), so scan it to see
|
|
; if the record contains an entry for that size
|
|
|
|
MOVE.L (A0),A0 ;handle->pointer
|
|
LEA FONDAssoc(A0),A0 ;skip header
|
|
MOVE.W (A0)+,D0 ;pick up the count
|
|
BMI.S @notReal ;if none, skip
|
|
|
|
@nrfLoop
|
|
CMP.W (A0),D2 ;got it?
|
|
BEQ.S @itsReal ;if so, its real
|
|
BLT.S @notReal ;if past it we're done
|
|
ADDQ #FAssocSiz,A0 ;skip to next entry
|
|
DBRA D0,@nrfLoop ;check em all out
|
|
|
|
BRA.S @notReal ;it must not be real...
|
|
|
|
@oldKindOfFont
|
|
; make sure the ID is in range for an old-style font
|
|
|
|
CMP.W #512,D1 ;ID in range?
|
|
BCC.S @notReal ;if not, return false
|
|
|
|
; there's no family definition record so do it the old way
|
|
|
|
ASL #7,D1 ;shift FamID into place
|
|
AND.W #$007F,D2 ;only use low 7 bits of size
|
|
OR D2,D1 ;compute resource ID
|
|
|
|
BSR GetStrike ;do we have it
|
|
BEQ.S @notReal ;good! (branch if we couldn't find it)
|
|
@itsReal
|
|
ADDQ.B #1,(SP) ;return TRUE
|
|
@notReal
|
|
JMP (A1) ;return to caller
|
|
|
|
|
|
; PROCEDURE SetFontLock(lockFlag:Boolean) -- makes the current font purgable
|
|
; or unpurgable.
|
|
|
|
SetFontLock
|
|
MOVE.L FOutFontHandle,A0 ;get the font handle
|
|
MOVE.L (SP)+,A1 ;get return address
|
|
TST.B (SP)+ ;set or clear lock?
|
|
BEQ.S @unlockFont ;if set, go lock it down
|
|
|
|
; we want to lock the font down so make sure its loaded and make it unpurgable
|
|
|
|
MOVE.L A0,-(SP) ;push font handle for release/load
|
|
MOVE.W #MapTrue,ROMMapInsert ;get it from ROM if possible <10 Jul 85>
|
|
_LoadResource ;load it in
|
|
_HNoPurge ;turn off purge bit
|
|
BCLR #purge,FondState
|
|
BRA.S @doneSFL
|
|
|
|
; we no longer need the font so make it purgable
|
|
|
|
@unlockFont
|
|
_HPurge ;make it purgable
|
|
BSET #purge,FondState
|
|
@doneSFL
|
|
JMP (A1) ;return to caller
|
|
|
|
|
|
; PROCEDURE SetFScaleDisable(scaleDis:BOOLEAN);
|
|
;
|
|
; Set to turn ScaleDisable on and off, invalidating the width cache.
|
|
|
|
SetFScaleDisable
|
|
MOVE.L (SP)+,A0
|
|
MOVE.B (SP)+,FScaleDisable
|
|
setFScaleTail
|
|
MOVE.L MinusOne,LastSpExtra ;note that widths are invalid
|
|
JMP (A0)
|
|
|
|
|
|
; PROCEDURE SetFractEnable(fractEnable:BOOLEAN);
|
|
;
|
|
; Set to turn FractEnable on and off, invalidating the width cache.
|
|
|
|
SetFractEnable
|
|
MOVE.L (SP)+,A0 ;return address
|
|
MOVE.B (SP)+,FractEnable
|
|
BRA.S setFScaleTail
|
|
|
|
|
|
; PROCEDURE FontMetrics(VAR theMetrics:FontMetricRec);
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (FontMetrics) (FontMetrics)
|
|
;
|
|
; FontMetrics returns fractional information about the current font
|
|
; as specified in thePort. It returns a Font Metric Record whose format
|
|
; is:
|
|
;
|
|
; ascent: Fixed;
|
|
; descent: Fixed;
|
|
; leading: Fixed;
|
|
; widMax: Fixed;
|
|
; WTabHandle: Handle;
|
|
;
|
|
|
|
; first use CharWidth to force a SwapFont
|
|
|
|
FontMetrics
|
|
SUBQ #2,SP ;make room for result
|
|
MOVE #' ',-(SP) ;push ASCII for blank
|
|
_CharWidth ;run through SwapFont
|
|
ADDQ #2,SP ;we don't really care about result
|
|
|
|
; get the parameter pointer
|
|
|
|
MOVE.L A2,-(SP) ;save work register
|
|
MOVE.L 8(SP),A2 ;point to result record
|
|
|
|
; always derive things from the font itself
|
|
|
|
MOVE.L FOutFontHandle,A1 ;get font handle
|
|
MOVE.L (A1),A1 ;handle->pointer
|
|
LEA FAscent(A1),A0 ;point to ascent field
|
|
PEA FWidMax(A1) ;save pointer to FWidMax for later
|
|
BSR.S ScaleVFVal ;process ascent
|
|
BSR.S ScaleVFVal ;process descent
|
|
BSR.S ScaleVFVal ;process leading
|
|
MOVE.L (SP)+,A0
|
|
MOVE.L FScaleHFact,D1
|
|
LEA fmOutNumer+FOutRec+2,A1 ;point to horizontal numerator.
|
|
BSR.S ScaleFVal ;process widMax
|
|
|
|
; stuff the width table handle
|
|
|
|
MOVE.L WidthTabHandle,A0
|
|
MOVE.L A0,(A2) ;remember width handle
|
|
|
|
; now adjust the results to compensate for style
|
|
|
|
MOVE.L 8(SP),A2 ;get result pointer back.
|
|
MOVEQ #0,D0
|
|
MOVE.B fmOutShadow+FOutRec,D0 ;get shadow count
|
|
BEQ.S @noShadow ;skip if zero
|
|
ADD.W #1,(A2) ;adjust ascent
|
|
ADD.W D0,4(A2) ;adjust descent
|
|
@noShadow
|
|
MOVE.L (A0),A0 ;pointer to widths
|
|
MOVE.L WidthStyle(A0),D0 ;get the style extra.
|
|
ADD.L D0,12(A2) ;add it in to the WidMax field.
|
|
|
|
; now we're done
|
|
|
|
MOVE.L (SP)+,A2 ;restore work register
|
|
MOVE.L (SP)+,(SP) ;strip parameter
|
|
RTS
|
|
|
|
|
|
; ScaleFVal is a code saving utility that fetches the value pointed
|
|
; to by A0, multiplies it by the scale factor and scale disable adjustment,
|
|
; and stuffs the normalized long result where A2 points
|
|
|
|
ScaleVFVal
|
|
MOVE.L FScaleVFact,D1
|
|
LEA fmOutNumer+FOutRec,A1 ;point to vertical numerator.
|
|
ScaleFVal
|
|
MOVE.W (A0)+,D0 ;get ascent
|
|
MOVE.L A0,-(SP)
|
|
TST.B FScaleDisable ;use 1.0 if scaling is enabled.
|
|
BNE.S @2
|
|
MOVE.L FPointOne,D1
|
|
@2
|
|
SUBQ #4,SP ;make space for result
|
|
MOVE.L D1,-(SP) ;FScale adjustment for FixMul
|
|
|
|
SUBQ #4,SP
|
|
CLR.W -(SP) ;push the font's info as a fixed point value.
|
|
MOVE.W D0,-(SP)
|
|
|
|
SUBQ #4,SP
|
|
; reversed next 2 lines <28May86>
|
|
MOVE.W (A1),-(SP) ;push V output numer
|
|
MOVE.W 4(A1),-(SP) ;push V output denom
|
|
_FixRatio ;compute ratio.
|
|
|
|
; multiply by the appropriate FScaleDisable factor in D1
|
|
|
|
_FixMul ;compute FScaleExtra*Value
|
|
_FixMul ;compute FScaleExtra*Value*ScaleFactor
|
|
MOVE.L (SP)+,(A2)+ ;remember it
|
|
MOVE.L (SP)+,A0
|
|
RTS
|
|
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; BuildCharTable operates on the font passed in A0. It makes room for
|
|
; a character height table at the end of the font and then loops from
|
|
; FirstChar to LastChar+1, computing it.
|
|
;
|
|
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
|
;AppleSystemPatch FontMgrPatch.a 01Jan1904 #??? (BuildCharTable) (BuildCharTable)
|
|
;
|
|
; Registers used:
|
|
;
|
|
; D0 = scratch D1 = scratch D2 = scratch D3 = character height
|
|
; D4 = constant (16) D5 = table size D6 = next entry, width D7 = locTable entry
|
|
; A0 = fontHandle (input) A1 = strike pointer A2 = fontPtr, locTable A3 = fontHandle
|
|
; A4 = character height A5 = mask table
|
|
|
|
RightMask EQU $0 ;position of right masks in QuickDrawÕs table.
|
|
LeftMask EQU $20 ;position of left masks in QuickDrawÕs table.
|
|
|
|
|
|
BuildCharTable
|
|
MOVEM.L D3-D7/A2-A5,-(SP) ;save registers
|
|
|
|
MOVE.L A0,A3 ;keep fontHandle in A3
|
|
_GetMaskTable
|
|
MOVE.L A0,A5 ;keep pointer to left masks around
|
|
MOVE.L (A3),A1 ;point to the font
|
|
MOVE.W (A1)+,D0 ;get format word?
|
|
LSR #1,D0 ;already got table?
|
|
BCS.S DoneBCT ;if so, we're done
|
|
|
|
; get firstChar, lastChar and compute size of table
|
|
|
|
MOVE.W (A1)+,D0 ;get firstChar
|
|
MOVEQ #0,D5 ;zero high word
|
|
MOVE.W (A1),D5 ;get lastChar
|
|
SUB.W D0,D5 ;compute lastChar-firstChar
|
|
ADDQ #3,D5 ;# of chars, including missing
|
|
ADD.W D5,D5 ;compute size of table
|
|
|
|
; compute total new size of font: position of OWTable + 2 * D5
|
|
|
|
MOVE.L (A3),A1 ;point to font
|
|
MOVEQ #0,D0
|
|
IF bugFix THEN
|
|
MOVE.W fNDescent(A1),D0 ;possibly the high word of owTLoc
|
|
BLE.S @negative
|
|
SWAP D0 ;put it in the high word
|
|
ENDIF
|
|
@negative
|
|
MOVE.W fOWTLoc(A1),D0 ;get size till owTable
|
|
ADDQ.L #8,D0 ;8 header words in front
|
|
ADD.L D0,D0 ;double for bytes
|
|
MOVE.L D0,D1 ;remember in D1
|
|
SUB.L D5,D1 ;compute offset to LocTable
|
|
ADD.L D5,D0 ;add in owTable
|
|
MOVE.L D0,D2 ;remember offset to height table for later
|
|
ADD.L D5,D0 ;add in newTable
|
|
|
|
; if the font has a built-in width table, make sure we take that into
|
|
; account
|
|
|
|
BTST #1,1(A1) ;built in width table?
|
|
BEQ.S @growTheFont ;if not, skip
|
|
|
|
ADD.L D5,D0 ;increase new size
|
|
ADD.L D5,D2 ;bump where heights go, too
|
|
|
|
; grow it to include the table
|
|
|
|
@growTheFont
|
|
MOVE.L A3,A0 ;get the font handle
|
|
_SetHandleSize ;try to grow it
|
|
BEQ.S MakeCTable ;if we can, good
|
|
|
|
; we couldn't grow the handle so give up.
|
|
|
|
DoneBCT
|
|
MOVEM.L (SP)+,D3-D7/A2-A5
|
|
RTS
|
|
|
|
; OK, D2 has the offset to the beginning of the character offset table,
|
|
; D1 has offset to locTable, D3 has firstChar and D4 has lastChar. Loop
|
|
; for the # of characters, walking down both tables, using locTable to
|
|
; build the mask, counting the rows and filling out the charTable.
|
|
|
|
MakeCTable
|
|
MOVE.L (A3),A2 ;point to font
|
|
OR #1,(A2) ;turn on mode bit
|
|
|
|
MOVE.W fFRectHeight(A2),D3 ;hold total height
|
|
ADD.L D1,A2 ;A2 points to locTable
|
|
MOVE.L (A3),A4 ;point to font
|
|
ADD.L D2,A4 ;point to charTable
|
|
|
|
; here's the start of the loop. D5 has the number of entries *2 to
|
|
; process. From the words that A2 points to, make a mask/offset combo
|
|
; in A1/D0.
|
|
|
|
SUBQ #2,D5 ;don't need extra bounds
|
|
CTabLoop0
|
|
MOVE #$FF00,(A4) ;init top to FF, bot to 0
|
|
|
|
MOVE.W (A2)+,D7 ;get locTable entry
|
|
MOVE.W (A2),D6 ;get next entry, too
|
|
SUB.W D7,D6 ;compute length in pixels
|
|
BEQ.S EmptyChar ;if zero, its easy
|
|
|
|
; Here's where we re-enter the loop for wide characters. Make A1 point
|
|
; into word of font, and start building the mask in D0.
|
|
|
|
CTab1Loop
|
|
MOVE.W D7,D2 ;remember start
|
|
MOVE.W D7,D0 ;get start in D0
|
|
LSR.W #4,D0 ;divide by 16
|
|
ADD.W D0,D0 ;double for byte offset
|
|
|
|
MOVE.L (A3),A1 ;get font pointer
|
|
ADD.W #FRowWords+2,A1 ;point to strike
|
|
ADD.W D0,A1 ;point to proper word
|
|
|
|
; now build the leftMask based on the remainder
|
|
|
|
AND #15,D2 ;compute start mod 16
|
|
MOVE D2,D1 ;copy it
|
|
ADD.W D1,D1 ;double for word index
|
|
|
|
MOVEQ #0,D0 ;clear high part of D0
|
|
MOVE.W LeftMask(A5,D1),D0 ;get leftMask
|
|
SWAP D0 ;keep in high word
|
|
|
|
; now compute how many pixels were used up in the first word, and decrement
|
|
; the width value
|
|
|
|
MOVEQ #16,D4 ;useful constant!
|
|
MOVE D4,D1 ;at most 16 used
|
|
SUB.W D2,D1 ;compute number used
|
|
ADD.W D1,D7 ;bump left index
|
|
|
|
SUB.W D1,D6 ;compute number left
|
|
BEQ.S MaskBuilt ;if none, done building mask
|
|
BPL.S @moreMask ;if >0, turn on more bits
|
|
|
|
; the width remaining is < 0, so we must turn off bits in the mask
|
|
|
|
MOVE D6,D1 ;get the delta
|
|
ADD.W D4,D1 ;compute 16-delta
|
|
ADD.W D1,D1 ;double for word index
|
|
|
|
MOVE.L RightMask(A5,D1),D2 ;get inverse mask in high word
|
|
AND.L D2,D0 ;turn off right bits
|
|
BRA.S MaskBuilt ;OK, we got it
|
|
|
|
|
|
; here we handle the case where there's more in the next word to process,
|
|
; so extend the mask into the low word.
|
|
|
|
@moreMask
|
|
MOVE.W D6,D1 ;get remaining count
|
|
CMP.W D4,D1 ;bigger than 16?
|
|
BLE.S @notTopEnd ;if not, skip
|
|
MOVE.W D4,D1 ;if so, max out at 16
|
|
@notTopEnd
|
|
ADD.W D1,D1 ;double for word index
|
|
MOVE.W RightMask(A5,D1),D2 ;get mask
|
|
OR D2,D0 ;extend the mask
|
|
SUB.W D4,D6 ;decrement remaining width
|
|
ADD.W D4,D7 ;bump index to next word
|
|
|
|
; at this point, A1 points to the top long in the character and D0 has
|
|
; the mask. D3 has the number of scan lines. Loop, fetching a long
|
|
; and masking to find top of character.
|
|
|
|
MaskBuilt
|
|
MOVE.L A1,-(SP) ;remember first pointer
|
|
|
|
MOVE D3,D1 ;init height counter
|
|
SUBQ #1,D1 ;bias for DBRA
|
|
|
|
MOVE.L (A3),A0 ;get font pointer
|
|
MOVE.W fRowWords(A0),A0 ;get rowWords in A0
|
|
ADD.W A0,A0 ;compute rowBytes
|
|
MOVEQ #0,D4 ;D4 is current top
|
|
TopMaskLoop
|
|
MOVE.L (A1),D2 ;get the bits
|
|
AND.L D0,D2 ;any relevant one on?
|
|
BNE.S MergeInTop ;if on, done with top
|
|
|
|
ADDQ #1,D4 ;bump top
|
|
ADD.W A0,A1 ;add in RowBytes
|
|
DBRA D1,TopMaskLoop ;loop for all height
|
|
|
|
; all blank so set up as (0,0)
|
|
|
|
ADDQ.L #4,SP ;strip saved A1
|
|
MOVEQ #0,D6
|
|
EmptyChar
|
|
CLR.W (A4)+ ;stick 0,0 in table
|
|
BRA.S NextChar ;go process next char
|
|
|
|
; OK, so top is in D4. Merge it into the table.
|
|
; (A4) starts at $FF, so any other value is smaller by unsigned <28May86>
|
|
; compare; we're looking for the lowest value possible. <28May86>
|
|
|
|
MergeInTop
|
|
CMP.B (A4),D4 ;is it smaller?
|
|
BHS.S @0 ;if not, skip
|
|
MOVE.B D4,(A4) ;update top
|
|
|
|
; now try the bottom up
|
|
|
|
@0
|
|
MOVE.L (SP)+,A1 ;recover character ptr
|
|
|
|
MOVE D3,D2 ;get height
|
|
SUBQ #1,D2 ;compute height-1
|
|
|
|
MOVE A0,D4 ;get rowBytes
|
|
MULU D4,D2 ;compute offset to bottom
|
|
ADD.L D2,A1 ;start with bottom word
|
|
|
|
MOVE D3,D4 ;start with height
|
|
MOVE D3,D1 ;get # of lines
|
|
SUBQ #1,D1 ;bias for DBRA
|
|
BotMaskLoop
|
|
MOVE.L (A1),D2 ;get the long
|
|
AND.L D0,D2 ;any relevant bits on?
|
|
BNE.S MergeInBot
|
|
|
|
SUBQ #1,D4 ;one less high
|
|
SUB.W A0,A1 ;back up a scan line
|
|
DBRA D1,BotMaskLoop
|
|
BRA.S EmptyChar ;impossible to get here...
|
|
|
|
; compute the height of the character and merge it in
|
|
; Herein lies the bug: until now the delta was computed along the <28May86>
|
|
; way, so information could be lost about characters that slanted <28May86>
|
|
; from lower left to upper right. Nowadays, keep the low point in the <28May86>
|
|
; second byte until the character is finished; then compute the delta <28May86>
|
|
; into the second byte.
|
|
|
|
MergeInBot
|
|
ADDQ.L #1,A4 ;skip top offset <28May86>
|
|
CMP.B (A4)+,D4 ;compare with last height
|
|
BCS.S NextChar ; <28May86>
|
|
|
|
MOVE.B D4,-1(A4) ;its bigger, so use it
|
|
|
|
; we're finally done with this band of the character (at least!) so see
|
|
; if we're really done with it
|
|
|
|
NextChar
|
|
SUBQ.L #2,A4 ;back up
|
|
TST D6 ;done with this character?
|
|
BGT CTab1Loop ;if not, dive in again
|
|
|
|
; Get here when finished with a char. Have high and low pts in (A4), <28May86>
|
|
; so must compute low-high in 1(A4) as incrementing. <28May86>
|
|
MOVE.B (A4)+,D0 ;high pt <28May86>
|
|
SUB.B D0,(A4)+ ;low-high <28May86>
|
|
SUBQ #2,D5 ;more to do?
|
|
BGT CTabLoop0 ;if so, go do it
|
|
BRA DoneBCT ;if not, we're done
|
|
|
|
FMgrEnd
|
|
|
|
;*******************************************************************
|
|
;*******************************************************************
|
|
;*******************************************************************
|