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

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

1781 lines
62 KiB
Plaintext

;
; File: Text.a
;
; Contains: QuickDraw routines for measuring and drawing text
;
; Copyright: © 1981-1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM4> 7/16/92 CSS Update from Reality:
; <41> 4/24/92 DTY Get rid of hasSplineFonts conditionals.
; <SM3> 5/11/92 CSS Fixed problem with graying text causing the text to be erased.
; Removed If not forRom conditional in StdText.
; <SM2> 4/16/92 PN Change the conditioning to include all the routines into ROM
; <40> 11/21/91 JH Rolling in Kon's changes from Sakura project. This particular
; change is: The double byte code in measure text attempts to
; measure 1 too many characters. This is ok in Roman systems, but
; if that n+1st character is a double byte Konji character, the
; heap will be trashed.
; <39> 9/25/91 jlf Conditionalized hasDoubleByte so that it won't be rolled into
; rom builds. Conditionalized numer and denom assignments in
; MeasureText to repair rom builds.
; <38> 9/25/91 jlf Rolled in Pacific TrueType modifications (aka: doublebyte support).
; Removed DOUBLE_BYTE conditional code and inserted hasDoubleByte
; code. Removed enNumer/enDenom stuff to fix divide-by-zero bug in TrueType.
; Peter Edberg says that emNumer/emDenom is no longer supported.
; <37> 7/10/91 JSM Remove obsolete SysVers conditionals.
; <36> 6/12/91 LN added #include 'SysPrivateEqu.a'
; <35> 4/30/91 dba change Gaudi equate to avoid warning when building the ROM
; <34> 3/13/91 JT Added the glyph state opcode support to text drawing under old
; QuickDraw. This opcode records the state of the Font Manager and
; TrueType so text will be drawn the same on picture playback as
; it was during picture recording. Also prevented font naming,
; line layout, and glyph state opcodes from being recorded in old
; pictures. Code checked by KON and BAL. BRC numbers 82651 and
; 79185. Worksheet number KON-022.
; <33> 1/15/91 CL (MR)Now safecount must be set to -2 if the pen loc needs to be
; added inside of stdtxmeas.
; <32> 1/14/91 CL (RB) Fixing sister bug of long string phenomenom. This is
; due when style variations such as italic is being measured. We
; can get an overflow problem when adding in the slop. This is
; now being added into the overflow calculations.
; <31> 1/14/91 SMB (jdt) Initializing overflow count to -1 in StdTxMeas.
; <30> 1/9/91 RB (CEL/PKE/GM/DA) Fixing long string overflow bug by truncating
; the count.
; <29> 9/24/90 PKE (BBM) (Same change that CL & BAL made to DrawText.a) Fixed bug
; in charextra code with chExtra being treated as unsigned.
; <28> 9/15/90 DC Made Grayish text code use GetGray
; <27> 9/14/90 csd Removed the definition of _DeviceLoop.
; <26> 9/11/90 SMB (CEL) Fixing a bug introduced in <20> that broke HyperCard,
; TeachText, AppleLink, etc: It wiped out the grafport address in
; a0 that was used to set up the Inrec for FMSwapFont.
; <25> 9/1/90 dvb Generally improve grayish text, and make sure that
; picture-recording is disabled during grayish text drawing.
; <24> 8/24/90 PKE (per JT) Use new Script Mgr line layout values in GrafGlobals
; instead of soon-to-be-obsolete values in Script Mgr globals. Use
; new names picQdChExtra and picQdRunSlop instead of picSMgrChar
; and picSMgrSlop.
; <23> 8/21/90 dvb Change biasing on grayish text dither, to prefer dithering
; unless there is a really great match.
; <22> 8/17/90 dvb Fix grayish stuff
; <21> 7/24/90 DVB Disable grayish slime mode for rom.
; <20> 7/20/90 DTY Bass: The Linked Patch. Large majority of changes are jsrROMs
; for calls to ROM. Also added Gaudi conditional for code that
; compiles when hasSplineFonts is defined, since hasSplineFonts
; isnÕt defined for System 6 builds.
; <19> 7/17/90 DVB Add GrayishTextCopy mode to StdText; the slimy version.
; <18> 6/25/90 CL fontPrivate should only be included in this file when it is a
; splinefont build.
; <17> 6/22/90 CL Fixed up include files to use new fontPrivate.a, toolEqu.a and
; qdhooks.
; <16> 6/9/90 JT Now scale the character extra by the font size specified in the
; current grafPort. This is the same treatment that Color
; QuickDraw normally gives to the chExtra field. Note that the two
; extra values are added together before they are scaled.
; <15> 6/7/90 PKE Add scaling parameters to MeasureText stack frame, set them from
; new ExpandMem globals, use them to scale results.
; <14> 5/29/90 CL Took out references from the width table to caches. Added
; support for a global current cache.
; <13> 4/23/90 JT Save the Script Manager line-layout state when spooling a
; picture in StdText.
; <12> 4/16/90 HJR Change SPLINE_FONT to hasSplineFonts.
; <11> 4/16/90 KON Make it build (equate problems).
; <10> 4/13/90 HJR Really fix case sensitivity so that other build work.
; <9> 4/10/90 CL Fixing case sensitivity for bass build
; <8> 3/26/90 CL Adding in MeasureText routine for Script Manager charextra
; addition.
; <7> 3/21/90 CL Fixing conditionals for ROM builds. Script Manager char extra
; addition.
; <6> 3/20/90 CL no change
; <5> 2/15/90 CEL Adding in Script Managers special charextra field
; <4> 2/15/90 KON Fixed GetRect so that when scaled fonts are measured (via
; StdTxMeas) they are multiplied by the scaling factor.
; <3> 1/16/90 KON Fix font name recording: PutPicOp destroys D1, so the length was
; not calculated right.
; <2> 1/15/90 BAL Changed Fontname recording code in stdText to better handle null
; strings returned by getFName (as are found when Microsoft Word
; patches getFName).
; <2.4> 11/28/89 CEL The Bass init code working on 6.0.4 systems do not use the pict
; font name matching. ifdefed them out.
; <2.3> 11/1/89 BAL Altered StdText to record font names into pictures.
; <2.2> 9/25/89 CEL An old sign extend bug in CalcCharExtra was fixed a while ago.
; Was using the CalcCharExtra routine but thought I could be
; clever and jump back into rom and save code. Bad move! Needed
; bug fix so now it is included for spline fonts.
; <2.1> 8/31/89 CEL Took out PatchMacs include. Does not use it.
; <2.0> 8/28/89 CEL Only need to use word part of ascent, descent, widmax & leading
; in widthtable for Outline Fonts. Caching code already rounds the
; values properly.
; <1.9> 7/6/89 GGD Un-Func'd TextWidth so that alignment wouldn't screw up
; StringWidth falling into it.
; <1.8> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
; fixed up necessary filesÉ
; <¥1.7> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
; <¥1.6> 5/3/89 CEL Bass rolled into ROM. NOTE:Spline Fonts are conditionalized out.
; Blasting in correct file
; <¥1.4> 5/1/89 cel Rolled in BassÉ
; <¥1.2> 2/14/89 CCH Rolling in 32-Bit color quickdraw sources from Bruce Leak and
; Dave Fung.
; 1/8/89 BAL Vectorized CheckPic
; 6/4/87 CRC reset hilite if text count < 0 in StdText; sign extend input to CalcCharExtra
; translate zero into something meaningful in CharExtra
; 1/26/87 CRC cause text to be measured only first time in loop drawing case
; 12/12/86 CRC Added charExtra support
; 9/29/86 CRC Changed WidthPtr to WidthTabHandle
; 7/2/86 EHB Changed FixTxWid to FontAdj (because someone changed equates)
;
IF (&TYPE('Gaudi') = 'UNDEFINED') THEN
IF (&TYPE('INITVERSION') = 'UNDEFINED') THEN
Gaudi EQU 0 ; No init if not defined.
ELSE
Gaudi EQU 1
ENDIF
ENDIF
IF (&TYPE('hasDoubleByte') = 'UNDEFINED') THEN
IF forROM THEN
hasDoubleByte EQU 0
ELSE
hasDoubleByte EQU 1
ENDIF
ENDIF
if not(forROM) then
CASE OBJ
endif
STRING ASIS
IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN ;<7> CEL
IF forROM THEN
SCRIPT_CHAR_EXTRA EQU 0
ELSE
SCRIPT_CHAR_EXTRA EQU 1
ENDIF
ENDIF
IF (&TYPE('hasGlyphState') = 'UNDEFINED') THEN
IF forROM THEN
hasGlyphState EQU 0
ELSE
hasGlyphState EQU 1
ENDIF
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Include filesÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
IF (NOT forROM) THEN ;<8> CEL, <24>
INCLUDE 'Traps.a'
INCLUDE 'Quickequ.a'
INCLUDE 'ColorEqu.a'
INCLUDE 'SysEqu.a'
INCLUDE 'FixMath.a'
INCLUDE 'ToolEqu.a'
INCLUDE 'qdHooks.a'
INCLUDE 'SplineDefines.a'
INCLUDE 'FontPrivate.a'
EndIf
INCLUDE 'SysPrivateEqu.a'
INCLUDE 'LinkedPatchMacros.a'
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MACHINE MC68020
;-------------------------------------------
;
; KERNED STRIKE FONT FORMAT OFFSETS:
;
FORMAT EQU 0 ;WORD
MINCHAR EQU 2 ;WORD
MAXCHAR EQU 4 ;WORD
MAXWD EQU 6 ;WORD
FBBOX EQU 8 ;WORD
FBBOY EQU 10 ;WORD
FBBDX EQU 12 ;WORD
FBBDY EQU 14 ;WORD
LENGTH EQU 16 ;WORD
xASCENT EQU 18 ;WORD
xDESCENT EQU 20 ;WORD
xOFFSET EQU 22 ;WORD
RASTER EQU 24 ;WORD
;---------------------------------------------------
;
; PROCEDURE MyStdText(short count,char *string,Point numer,Point denom); AAA2/25;
;
; Depending on the device depth, draw the string in the
; avg of the fore and back rgb, or dither between
; foreground and background.
;
; We will lose the fore/back color if they were
; palette references.
;
; Note that this is a fairly inelegant head patch to the
; real StdText, hereafter referred to as "ReglarStdText"
StdText PROC EXPORT
IMPORT ReglarStdText
DGVars RECORD {A6Link},DECREMENT
result DS.B 0 ; none
count DS.B 2 ; input: number of characters
string DS.B 4 ; input: pointer to string
xNumer DS.B 4 ; input: numer scaler
xDenom DS.B 4 ; input: denom scaler
return DS.B 4 ; return address on stack
A6Link DS.B 4 ; link
oldPen DS.B 18 ; PenState record
oldPicSave DS.B 4 ; We turn off picture recording
oldForeRGB DS.B 6
oldBackRGB DS.B 6
gotForeRGB DS.B 6 ; the color that will actually be drawn
gotBackRGB DS.B 6
avgRGB DS.B 6
gotAvgRGB DS.B 6 ; closest color we could get
finfo DS.B 8 ; font info record
myr DS.B 8
myRgn DS.B 4 ; region, for deviceLoop call
numerCopy DS.B 4 ; copies for stdTxMeas call
denomCopy DS.B 4
tempGD DS.B 4
noLoop DS.B 2 ; Boolean: set if old port (old machine?)
linkSize DS.B 0 ; size of record
ENDR
WITH DGVars
MOVE.L (A5),A0
MOVE.L (A0),A0 ; A0->the port
CMPI #grayishTextOr,txMode(A0) ; is it the secret mode?
BEQ.S @itsus
JMP reglarStdText
@itsus
LINK A6,#linkSize
TST portVersion(A0) ; is it a new port
SPL noLoop(A6)
MOVE.L picSave(A0),oldPicSave(A6) ; disable picture saving (a0 still valid)
CLR.L picSave(A0)
MOVEM.L A2/D3,-(SP)
PEA oldPen(A6) ; Save Penstate
_GetPenState
MOVE #srcOr,-(SP) ; any text will be normal, here
_TextMode
TST.B noLoop(A6) ; Don't avg fore and back on old port
BNE.S @noColor1
PEA oldForeRGB(A6) ; Save ForeColor
_GetForeColor
PEA oldBackRGB(A6) ; Save BackColor
_GetBackColor
@noColor1
_PenNormal
SUBQ #2,SP
MOVE count(A6),-(SP)
MOVE.L string(A6),-(SP)
MOVE.L xNumer(A6),numerCopy(A6)
PEA numerCopy(A6)
MOVE.L xDenom(A6),denomCopy(A6)
PEA denomCopy(A6)
PEA finfo(A6)
_StdTxMeas
PEA finfo(A6) ; did stdTxMeas do that?
_GetFontInfo
MOVE.L oldPen(A6),D1 ; D1 = previous pen position
MOVE D1,myr+left(A6)
MOVE (SP)+,D3 ; D3 = pen advance for string
ADD D3,D1 ; Add width to left edge
MOVE D1,myr+right(A6) ; to get right
SWAP D1
MOVE D1,D2
SUB finfo+ascent(A6),D2 ; figger highest point
ADD finfo+descent(A6),D1 ; and lowest point
MOVE D2,myr+top(A6)
MOVE D1,myr+bottom(A6) ; myr is now the string's bounds
SUBQ #4,SP
_NewRgn
MOVE.L (SP),myRgn(A6)
PEA myr(A6)
_RectRgn
TST.B noLoop(A6) ; An old port?
BEQ.S @doLoop ; No => call deviceloop
JSR txtAndStamp ; Yes => just draw and bic
BRA.S @cleanup
@doLoop ; (doLoops, brkfst of prgmmrs)
MOVE.L myRgn(A6),-(SP)
PEA GrayTextDLoop
CLR.L -(SP)
CLR.L -(SP)
_DeviceLoop
PEA oldForeRGB(A6) ; Restore ForeColor
_RGBForeColor
PEA oldBackRGB(A6) ; Restore BackColor
_RGBBackColor
MOVE.L (A5),A0
MOVE.L (A0),A0
ADD D3,pnLoc+2(A0) ; Bump the pen a little
@cleanup
MOVE.L myRgn(A6),-(SP)
_DisposRgn
MOVE #grayishTextOr,-(SP) ; restore textmode
_TextMode
MOVE.L (A5),A0
MOVE.L (A0),A0
MOVE.L oldPicSave(A6),picSave(A0) ; restore picture saving
MOVEM.L (SP)+,A2/D3
UNLK A6
CLR.L D0 ; No PMgr Dispatch Error
RTD #result-return-4
GTDVars RECORD {ret},DECREMENT ; All relative to SP on entry
depth DS.B 2
devFlags DS.B 2
devHan DS.B 4
userData DS.B 4
ret DS.B 4
ENDR
WITH GTDVars
GrayTextDLoop ; I get called for each device
LEA avgRGB(A6), A0
LEA oldForeRGB(A6), A1
MOVE.L (A1)+, (A0)+
MOVE.W (A1)+, (A0)+
MOVE.L devHan(SP), A0
SUBQ #2, SP
MOVE.L A0, -(SP)
PEA oldBackRGB(A6)
PEA avgRGB(A6)
_GetGray
TST.B (SP)+
BNE.S @oneColor
; MOVE.L TheGDevice,tempGD(A6)
; MOVE.L devHan(SP),TheGDevice
; SUBQ #4,SP ; figure the foreground drawn on this device
; PEA oldForeRGB(A6)
; _Color2Index
; PEA gotForeRGB(A6)
; _Index2Color
; SUBQ #4,SP ; figure the background drawn on this device
; PEA oldBackRGB(A6)
; _Color2Index
; PEA gotBackRGB(A6)
; _Index2Color
;
; Average the foreground and background colors for the device
; we're on as actually drawn
;
; LEA oldForeRGB(A6),A0 ; A0->forecolor.red
; MOVEQ #2,D0
;@a
; MOVE (A0),D1 ; D1 = fore component
; ADD oldBackRGB-oldForeRGB(A0),D1 ; D1 = fore component + back component
; ROXR #1,D1 ; Ö2, and recover lost high bit
; BMI.S @m
; ADDQ #2,D1 ; bump over halfway pt
; so that in the
; 2-bit 0-33-67-100 clut
; we map to the lighter
; gray!
;@m
; MOVE D1,avgRGB-oldForeRGB(A0) ; save avg component
; ADDQ #2,A0 ; Bump to next component
; DBRA D0,@a ; loop for all three components
; SUBQ #4,SP ; figure out the average actually drawable
; PEA avgRGB(A6)
; _Color2Index
; PEA gotAvgRGB(A6)
; _Index2Color
; MOVE.L tempGD(A6),TheGDevice
; SUBQ #2,SP
; PEA gotForeRGB(A6)
; PEA gotAvgRGB(A6)
; _DeltaRGB
; SUBQ #2,SP
; PEA gotBackRGB(A6)
; PEA gotAvgRGB(A6)
; _DeltaRGB
; SUBQ #2,SP
; PEA avgRGB(A6)
; PEA gotAvgRGB(A6)
; _DeltaRGB
; MOVE (SP)+,D0 ; D0 = delta to self
; MOVE (SP)+,D1 ; D1 = delta to back
; MOVE (SP)+,D2 ; D2 = delta to fore
; LSR #1,D1 ; bias to prefer pattern
; LSR #1,D2 ; unless there's a good match
; CMP D1,D0 ; Are we closer to back?
; BHS.S @twoColor ; yes => dither
; CMP D2,D0 ; Are we closer to fore?
; BLO.S @oneColor ; No => don't dither
;@twoColor
BSR.S txtAndStamp
BRA.S @e
@oneColor
PEA avgRGB(A6)
_RGBForeColor
MOVE count(A6),-(SP)
MOVE.L string(A6),-(SP)
MOVE.L xNumer(A6),-(SP)
MOVE.L xDenom(A6),-(SP)
jsr reglarStdText
@e
PEA oldPen(A6) ; Restore Penstate
_SetPenState
RTD #12
txtAndStamp
; little code fold with the call to stdText, and the stamp to gray
MOVE count(A6),-(SP)
MOVE.L string(A6),-(SP)
MOVE.L xNumer(A6),-(SP)
MOVE.L xDenom(A6),-(SP)
jsr reglarStdText
MOVE.L (A5),A0 ; get QuickDraw globals
PEA Gray(A0) ; push gray
_PenPat ; set pen to it
MOVE #PatBIC,-(SP) ; push patBIC penMode
_PenMode ; set penMode
PEA myr(A6)
_PaintRect
RTS
ReglarStdText PROC EXPORT
IMPORT DrText
;--------------------------------------------------------------------------
;
; PROCEDURE StdText(count: INTEGER; textAddr: Ptr; numer,denom: Point);
;
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
;
PARAMSIZE EQU 14
COUNT EQU PARAMSIZE+8-2 ;WORD
TEXTADDR EQU COUNT-4 ;LONG
NUMER EQU TEXTADDR-4 ;POINT
DENOM EQU NUMER-4 ;POINT
TXLOC EQU -4 ;POINT
VARSIZE EQU TXLOC ;TOTAL SIZE OF LOCALS
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
MOVEM.L D5-D7/A3-A4,-(SP) ;SAVE REGS
TXTLOOP MOVE COUNT(A6),D6 ;GET CHARACTER COUNT
BLE GOHOME ;QUIT IF COUNT <= 0
CMP #255,D6 ;is count > 255 ?
BLE.S COUNTOK ;no, continue
MOVE #255,D6 ;yes, pin at 255
COUNTOK
jsrROM CheckPic ;SET UP A4,A3 AND CHECK PICSAVE <20> DTY Changed from BSR.L
SLE -(SP) ;SET FLAG IF NOT PIC
BLE NOTPIC
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
;
; CHECK TXFONT
;
MOVE TXFONT(A3),D7 ;GET THEPORT^.TXFONT
CMP PICTXFONT(A4),D7 ;HAS IT CHANGED ?
BEQ FONTOK ;NO, CONTINUE
IF (NOT Gaudi) THEN
tst.w picVersion(a4) ; is this a new picture?
beq notNewName ; no, skip this opcode
move.l picFontList(a4),a0 ;get fontList handle
move.l a0,d0 ;check for nil
beq notNewName ;drop down the id only
move.l (a0),a0
addq.w #4,a0 ;skip handle size
move.w (a0)+,d1 ;get entry count
@2 cmp.w (a0)+,d7 ;have we seen this fond before?
@1 dbeq d1,@2 ;no, keep looking
beq.s notNewName ;yes, we found it
;
; At this point we have found a non-zero fond ID which we have not seen previously
; so we must add it to the fontList handle. If the handle needs to be resized we do that
; here as well.
fontChunk equ 50*2
exg.l d0,a0 ;get fontList handle in a0, end in d0
move.l (a0),a1 ;
sub.l a1,d0 ;get amnt of handle in use
cmp.l (a1),d0 ;same as size of handle?
blt.s addFontName ;no need to grow list
add.w #fontChunk,d0 ;bump handleSize enough for 25 more fonts
move.l d0,(a1) ;save the new size
_SetHandleSize ;grow list
move.l picFontList(a4),a1 ;get fontList handle
move.l (a1),a1 ;get fontList handle
tst.w d0 ;did we get it?
beq.s addFontName ;yes, continue
sub.w #fontChunk,(a1) ;couldn't grow it.
bra.s notNewName ;skip name stuff
addFontName
sub.w #256,sp ;alloc space for font name
move d7,-(sp) ;push font id
pea 2(sp) ;push var font name
_GetFName
move.b (sp),d1 ;check for empty string
beq.s @badName ;don't record this name
move.l picFontList(a4),a1 ;get fontList handle
move.l (a1),a1 ;get fontList handle
addq.w #4,a1 ;point to number of entries in use - 1
addq.w #1,(a1) ;bump the entry count
move.w (a1)+,d0 ;get new entry count and point to entry array
move.w d7,(a1,d0*2) ;store new ID
MOVEQ #opFontName,D0 ;YES, GET Font Name PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
moveq #3,d0 ;prime data size (word length + byte length)
add.b (sp),d0 ;add in length of string <16Jan90 KON>
move.w d0,-(sp) ;dump out data length
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP)
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
moveq #1,d0 ;prime string size
add.b (sp),d0 ;add in length of string
MOVE.L sp,-(SP) ;PUSH ADDR OF TEXT
MOVE D0,-(SP) ;PUSH COUNT
jsrROM PutPicData ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
@badName
add.w #256,sp ;de-alloc space for font name
ENDIF ;Leaving out pict font name matching for init
;Matching does not exist in 6.0.4
notNewName
MOVEQ #opTxFont,D0 ;YES, GET TXFONT PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP)
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D7,PICTXFONT(A4) ;UPDATE CURRENT STATE
;
; CHECK TXFACE
;
FONTOK MOVE.B TXFACE(A3),D7 ;GET THEPORT^.TXFACE
CMP.B PICTXFACE(A4),D7 ;HAS IT CHANGED ?
BEQ.S FACEOK ;NO, CONTINUE
MOVEQ #opTxFace,D0 ;YES, GET TXFACE PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.B D7,D0 ;GET TXFACE PARAM
jsrROM DPutPicByte ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.B D7,PICTXFACE(A4) ;UPDATE CURRENT STATE
;
; CHECK TXMODE
;
FACEOK MOVE TXMODE(A3),D7 ;GET THEPORT^.TXMODE
CMP PICTXMODE(A4),D7 ;HAS IT CHANGED ?
BEQ.S MODEOK ;NO, CONTINUE
CMP #PICTVERSION,PicVersion(A4) ;IS IT A NEW PICTURE?
BNE.S @DOMODE ;=>YES, NEW MODES OK
BTST #5,D7 ;AN ARITHMETIC MODE?
BEQ.S @DOMODE ;=>NO, MODE IS FINE
AND #$07,D7 ;ELSE STRIP MODE TO BOTTOM 3 BITS
MOVE.B ARITHMODE(D7),D7 ;AND REMAP IT
CMP PICTXMODE(A4),D7 ;HAS IT CHANGED ?
BEQ.S MODEOK ;NO, CONTINUE
@DOMODE MOVEQ #opTxMode,D0 ;ELSE GET TXMODE PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP)
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D7,PICTXMODE(A4) ;UPDATE CURRENT STATE
BRA.S MODEOK ;=>JUMP AROUND TABLE
ARITHMODE ;avg addPin addOver subPin trans max subOver min
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
;
; CHECK TXSIZE
;
MODEOK MOVE TXSIZE(A3),D7 ;GET THEPORT^.TXSIZE
CMP PICTXSIZE(A4),D7 ;HAS IT CHANGED ?
BEQ.S SIZEOK ;NO, CONTINUE
MOVEQ #opTxSize,D0 ;YES, GET TXSIZE PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP)
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D7,PICTXSIZE(A4) ;UPDATE CURRENT STATE
;
; CHECK SPEXTRA
;
SIZEOK MOVE.L SPEXTRA(A3),D7 ;GET THEPORT^.SPEXTRA
CMP.L PICSPEXTRA(A4),D7 ;HAS IT CHANGED ?
BEQ.S SPOK ;NO, CONTINUE
MOVEQ #opSpExtra,D0 ;YES, PUSH SPEXTRA PARAM OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L D7,-(SP)
jsrROM PutPicLong ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICSPEXTRA(A4) ;UPDATE CURRENT STATE
SPOK
;
; CHECK SMGRCHAREXTRA AND SMGRSLOP
;
IF SCRIPT_CHAR_EXTRA THEN
tst.w picVersion(a4) ; is this a new picture?
beq.s @layoutOK ; no, skip this opcode.
move.l grafGlobals(a5),a0 ; load quickDraw globals. <24>
move.l qdChExtra(a0),d5 ; load character extra amount. <24>
move.l qdRunSlop(a0),d7 ; load run slop amount. <24>
cmp.l picQdChExtra(a4),d5 ; has extra changed since last time? <24>
bne.s @layoutChanged ; yes -> update the layout state.
cmp.l picQdRunSlop(a4),d7 ; has slop changed since last time? <24>
beq.s @layoutOK ; no -> skip this.
@layoutChanged
moveq #opLineLayout,d0 ; load line layout opcode.
jsrROM DPutPicOp ; put the opcode into the picture. <20>
move.w #8,-(sp) ; push the data length.
jsrROM PutPicWord ; put the data length into the picture. <20>
move.l d5,-(sp) ; push the character extra amount.
jsrROM PutPicLong ; put the character extra into the picture. <20>
move.l d7,-(sp) ; push the run slop amount.
jsrROM PutPicLong ; put the run slop into the picture. <20>
move.l picSave(a3),a4 ; load the picSave handle.
move.l (a4),a4 ; load the picSave pointer.
move.l d5,picQdChExtra(a4) ; update current character extra. <24>
move.l d7,picQdRunSlop(a4) ; update current run slop. <24>
@layoutOK
ENDIF
;
; CHECK GLYPH STATE
;
IF hasGlyphState THEN
tst.w picVersion(a4) ; is this a new picture?
beq.s @glyphStateOK ; no, skip this opcode
btst.b #splinePreferred,HiliteMode ; bit flag set in HiliteMode?
sne.b d5 ; yes, set outline preferred flag
lsl.l #8,d5 ; make room for preserve glyph flag
btst.b #preserveGlyph,HiliteMode ; bit flag set in HiliteMode?
sne.b d5 ; yes, set preserve glyph flag
lsl.l #8,d5 ; make room for fractional widths flag
move.b FractEnable,d5 ; save fractional widths flag
lsl.l #8,d5 ; make room for scale disable flag
move.b FScaleDisable,d5 ; save scale disable flag
cmp.l picGlyphState(a4),d5 ; glyph state has changed?
beq.s @glyphStateOK ; no, skip all this
moveq #opGlyphState,d0 ; load glyph state opcode
jsrROM DPutPicOp ; put the opcode into the picture
move.w #4,-(sp) ; push the data length
jsrROM PutPicWord ; put the data length into the picture
move.l d5,-(sp) ; push the glyph state
jsrROM PutPicLong ; put the glyph state into the picture
move.l picSave(a3),a4 ; load the picSave handle.
move.l (a4),a4 ; load the picSave pointer.
move.l d5,picGlyphState(a4) ; update current glyph state
@glyphStateOK
ENDIF
;
; CHECK NUMER, DENOM
;
MOVE.L NUMER(A6),D7 ;GET NUMER
MOVE.L DENOM(A6),D5 ;GET DENOM
CMP.L PICTXNUMER(A4),D7 ;HAS IT CHANGED ?
BNE.S NOTSAME ;YES, RECORD CHANGE
CMP.L PICTXDENOM(A4),D5 ;HAS IT CHANGED ?
BEQ.S NUMEROK ;NO, CONTINUE
NOTSAME MOVEQ #opTxRatio,D0 ;YES, PUSH TXRATIO OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L D7,-(SP)
jsrROM PutPicLong ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L D5,-(SP)
jsrROM PutPicLong ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L D7,PICTXNUMER(A4) ;UPDATE CURRENT STATE
MOVE.L D5,PICTXDENOM(A4) ;UPDATE CURRENT STATE
NUMEROK
;-------------------------------------------------------------
;
; IF NPIC OR LATER, PUT FRACTIONAL PEN POSITION TO PICTURE IF USED
;
CMP #PICTVERSION,PicVersion(A4) ;IS IT AN OLD PICTURE?
BEQ.S CHOOSEOP ;=>YES, NO FRACTIONAL WIDTH, NO CHEXTRA
MOVE pnLocHFrac(A3),D7 ;GET NEW HORIZONTAL POSITION
CMP #$8000,D7 ;IS IT 1/2?
BEQ.S CHECKXTRA ;=>YES, DON'T SEND IT
MOVEQ #opPnLocHFrac,D0 ;GET OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP) ;PUSH HORIZONTAL FRACTION
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
CheckXtra
;-------------------------------------------------------------
;
; IF NPIC OR LATER, PUT CHEXTRA TO PICTURE IF CHANGED
;
MOVE chExtra(A3),D7 ;GET CURRENT CHEXTRA
CMP picChExtra(A4),D7 ;COMPARE TO LAST ONE
BEQ.S CHOOSEOP ;=>NO CHANGE
MOVEQ #opChExtra,D0 ;ELSE GET OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE D7,-(SP) ;PUSH CHEXTRA
jsrROM PutPicWord ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE D7,picChExtra(A4) ;UPDATE CURRENT STATE
CHOOSEOP
;-------------------------------------------------------------
;
; USE DH AND DV TO CHOOSE ONE OF FOUR TEXT OPCODES.
;
MOVE.L PNLOC(A3),D5 ;GET CURRENT PNLOC
SUB PICTXLOC+H(A4),D5 ;CALC DH
SWAP D5
SUB PICTXLOC+V(A4),D5 ;CALC CV
SWAP D5
MOVE.L D5,D0 ;COPY DV.DH
AND.L #$FF00FF00,D0 ;ARE DH AND DV BOTH 0..255 ?
BEQ.S SHORT ;YES, USE SHORT FORM
MOVEQ #opLongText,D0
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PNLOC(A3),-(SP)
jsrROM PutPicLong ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
BRA.S TEXT2 ;AND CONTINUE
SHORT MOVE.L D5,D0 ;YES, COPY DV.DH
AND.L #$00FF0000,D0 ;IS DV = 0 ?
BNE.S DV ;NO, CONTINUE
MOVEQ #opDHText,D0 ;GET DHTEXT OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
BRA.S SHARE2 ;SHARE COMMON CODE
DV TST.B D5 ;IS DH = 0 ?
BNE.S DHDV ;NO, CONTINUE
MOVEQ #opDVText,D0 ;GET DVTEXT OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
BRA.S SHARE1 ;SHARE COMMON CODE
DHDV MOVEQ #opDHDVText,D0 ;GET DHDVTEXT OPCODE
jsrROM DPutPicOp ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.B D5,D0
jsrROM DPutPicByte ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
SHARE1 SWAP D5 ;PUT DV IN LO WORD
SHARE2 MOVE.B D5,D0
jsrROM DPutPicByte ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
TEXT2 MOVE.B D6,D0
jsrROM DPutPicByte ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L TEXTADDR(A6),-(SP) ;PUSH ADDR OF TEXT
MOVE D6,-(SP) ;PUSH COUNT
jsrROM PutPicData ; <20> DTY Use jsrROM to jump to ROMBind address defined in BassPatches.a
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE.L PNLOC(A3),PICTXLOC(A4) ;UPDATE PICTXLOC STATE
; CALL STANDARD LOOP TO DRAW TO ALL DEVICES
NOTPIC PEA StdDraw ;PUSH ADDRESS OF DRAW ROUTINE
PEA GetRect ;PUSH ADDRESS OF RECT ROUTINE
_StdDevLoop ;DRAW TO ALL DEVICES
TST.B (SP)+ ;was it a picture?
BNE.S NOTAPIC ;=>no, not a picture
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
MOVE pnLocHFrac(A3),picLocHFrac(A4) ;save updated text fraction
NOTAPIC SUB D6,COUNT(A6) ;was count > 255 ?
BLE.S GOHOME ;no, quit
MOVE.L TEXTADDR(A6),A0 ;yes, get old textaddr
ADD D6,A0 ;offset for characters done
MOVE.L A0,TEXTADDR(A6) ;update textAddr
BRA TXTLOOP ;and loop for more
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite bit in case count < 0
MOVEM.L (SP)+,D5-D7/A3-A4 ;RESTORE REGS
UNLINK PARAMSIZE,'STDTEXT '
;---------------------------------------------------------------
;
; PROCEDURE GetRect(VAR theRect: rect);
;
; RETURN THE OBJECT'S RECTANGLE
;
GetRect MOVE.L (SP)+,D0 ;GET RETURN ADDRESS
MOVE.L (SP)+,A1 ;GET DST RECT
MOVE.L D0,-(SP) ;REPLACE RETURN ADDRESS
MOVE.L TheGDevice,-(SP) ;save the current device
MOVE.L LastTxGDevice,TheGDevice ;use the last device where text appeared
MOVE.L PNLOC(A3),D0 ;GET PEN LOC
MOVE.L D0,TOPLEFT(A1) ;SAVE AS TOPLEFT
MOVE.L D0,BOTRIGHT(A1) ;AND BOTRIGHT OF RECT
MOVE.L NUMER(A6),-(SP) ;PUSH VAR NUMER
MOVE.L DENOM(A6),-(SP) ;PUSH VAR DENOM
SUBQ #8,SP ;ALLOCATE VAR FONT INFO RECORD
MOVE.L SP,A0 ;POINT TO FONTINFO, DENOM, NUMER
MOVE.L A1,-(SP) ;SAVE RECT ON STACK
CLR -(SP) ;MAKE ROOM FOR WIDTH
MOVE D6,-(SP) ;PUSH BYTECOUNT
MOVE.L TEXTADDR(A6),-(SP) ;PUSH TEXTADDR
PEA 12(A0) ;PUSH VAR NUMER
PEA 8(A0) ;PUSH VAR DENOM
MOVE.L A0,-(SP) ;PUSH VAR FONT INFO RECORD
_StdTxMeas ;MEASURE THE TEXT
move.w 6+12+2(sp),d0 ;get numer.h <15Feb90 KON>
cmp.w 6+8+2(sp),d0 ; <15Feb90 KON>
beq.s @NotScaled ;same as denom.h go back to rom <15Feb90 KON>
mulu.w (sp),d0 ;d0 = numer.h * result <15Feb90 KON>
divu.w 6+8+2(sp),d0 ;d0 = numer.h * result/denom.h <15Feb90 KON>
move.w d0,(sp) ;return result <15Feb90 KON>
@NotScaled
MOVE (SP)+,D0 ;GET THE WIDTH
MOVE.L (SP)+,A1 ;GET THE RECT
ADD D0,RIGHT(A1) ;AND BUMP RIGHT OF RECT
MOVE (SP)+,D0 ;GET ASCENT
SUB D0,TOP(A1) ;BUMP TOP OF RECT
MOVE (SP)+,D0 ;GET DESCENT
ADD D0,BOTTOM(A1) ;BUMP BOTTOM OF RECT
ADD #12,SP ;STRIP WIDMAX, LEADING, DENOM, NUMER
MOVE.L (SP)+,TheGDevice ;restore the graf device
RTS ;AND RETURN
;---------------------------------------------------------------
;
; PROCEDURE StdDraw;
;
; DRAW THE OBJECT
;
StdDraw MOVE D6,-(SP) ;PUSH COUNT
MOVE.L TEXTADDR(A6),-(SP) ;PUSH TEXTADDR
MOVE.L NUMER(A6),-(SP) ;PUSH NUMER
MOVE.L DENOM(A6),-(SP) ;PUSH DENOM
JSR DrText ;DRAW THE TEXT
RTS
IF (forROM) THEN ;<1.6-4april89-CEL>
CallText PROC EXPORT
;---------------------------------------------------------------
;
; PROCEDURE CallText(count: INTEGER; textAddr: Ptr);
;
MOVE.L (SP)+,A0 ;POP RETURN ADDR
MOVE.L #$00010001,-(SP) ;PUSH NUMER = (1,1)
MOVE.L (SP),-(SP) ;PUSH DENOM = (1,1)
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
MOVE.L JStdTEXT,A0 ;get piece of trap table
BEQ.S USESTD ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L TEXTPROC(A0),A0 ;NO, GET PROC PTR
USESTD JMP (A0) ;GO TO IT
TextFace PROC EXPORT
EXPORT DrawChar,CharWidth
IMPORT CallText,TextWidth
;-------------------------------------------------------
;
; PROCEDURE TextFace(face: Style);
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
MOVE.B 5(SP),TXFACE(A0) ;INSTALL TXFACE
BRA.S SHARE ;STRIP PARAM AND RETURN
;----------------------------------------------------
;
; PROCEDURE DrawChar(ch: CHAR);
;
DrawChar
MOVE #1,-(SP) ;PUSH COUNT=1
PEA 7(SP) ;PUSH TEXTADDR
JSR CallText ;CALL TEXT ROUTINE
BRA.S SHARE ;STRIP PARAM AND RETURN
;---------------------------------------------
;
; FUNCTION CharWidth(ch: CHAR): INTEGER;
;
CharWidth
CLR -(SP) ;ROOM FOR FCN RESULT
MOVE.L SP,-(SP) ;PUSH TEXTBUF
MOVE.L #$00010007,-(SP) ;PUSH OFFSET = 7 & COUNT = 1
_TEXTWIDTH
MOVE (SP)+,6(SP) ;MOVE UP RESULT
SHARE MOVE.L (SP)+,A0 ;POP RETURN ADDR
ADD #2,SP ;STRIP CHAR PARAM
JMP (A0) ;AND RETURN
TextFont PROC EXPORT
EXPORT TextSize
EXPORT TextMode
IMPORT PortWord
;-------------------------------------------------------
;
; PROCEDURE TextFont(font: INTEGER);
;
MOVEQ #TXFONT,D0 ;PUT PORT OFFSET IN D0
BRA.S SHARE
;-------------------------------------------------------
;
; PROCEDURE TextMode(mode: INTEGER);
;
TextMode
MOVEQ #TXMODE,D0 ;PUT PORT OFFSET IN D0
BRA.S SHARE
;-------------------------------------------------------
;
; PROCEDURE TextSize(mode: INTEGER);
;
TextSize
; if the port is a new port, then the charExtra field should be zeroed (since charExtra is
; calculated using the current text size)
MOVE.L ([grafGlobals,A5],thePort),A0 ;get the port
TST portBits+rowBytes(A0) ;is it an old one?
BPL.S @doOld
CLR chExtra(A0) ;clean the char extra field
@doOld
MOVEQ #TXSIZE,D0 ;PUT PORT OFFSET IN D0
SHARE JMP PORTWORD ;INSTALL PARAM INTO THEPORT
SpaceExtra PROC EXPORT
EXPORT DrawString,DrawText
IMPORT CallText
;-------------------------------------------------------
;
; PROCEDURE SpaceExtra(extra: LongInt);
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
MOVE.L 4(SP),SPEXTRA(A0) ;INSTALL FIXED POINT SPEXTRA
BRA.S SHARE
;----------------------------------------------------
;
; PROCEDURE DrawString(s: Str255);
;
DrawString
MOVE.L 4(SP),A0 ;POINT TO STRING
CLR D0 ;GET READY FOR BYTE
MOVE.B (A0)+,D0 ;GET STRING LENGTH
MOVE D0,-(SP) ;PUSH COUNT
MOVE.L A0,-(SP) ;PUSH TEXTADDR
JSR CallText ;CALL TEXT ROUTINE
BRA.S SHARE
;----------------------------------------------------
;
; PROCEDURE DrawText(textBuf: WordPtr; start,count: INTEGER);
;
DrawText
MOVE.L 8(SP),A0 ;POINT TO TEXTBUF
ADD 6(SP),A0 ;ADD STARTING OFFSET
MOVE 4(SP),-(SP) ;PUSH COUNT
MOVE.L A0,-(SP) ;PUSH TEXTADDR
JSR CallText ;CALL TEXT ROUTINE
MOVE.L (SP)+,(SP)
SHARE MOVE.L (SP)+,(SP) ;STRIP PARAMS
RTS ;AND RETURN
StringWidth FUNC EXPORT
EXPORT TextWidth ; <1.79>
;---------------------------------------------
;
; FUNCTION StringWidth(s: Str255): INTEGER;
;
MOVE.L (SP)+,A1 ;POP RETURN ADDR
MOVE.L (SP)+,A0 ;POP ADDR OF STRING
CLR D0
MOVE.B (A0)+,D0 ;GET UNSIGNED BYTE
MOVE.L A0,-(SP) ;PUSH TEXTADDR
CLR -(SP) ;FIRSTBYTE := 0
MOVE D0,-(SP) ;PUSH BYTECOUNT
MOVE.L A1,-(SP) ;PUT BACK RETURN ADDR
;
; FALL THRU INTO TEXTWIDTH
;
TextWidth ; <1.9>
;------------------------------------------
;
; FUNCTION TEXTWIDTH(TEXTBUF: WordPtr; firstbyte,byteCount: INTEGER): INTEGER;
;
PARAMSIZE EQU 8
RESULT EQU PARAMSIZE+8
TEXTBUF EQU RESULT-4 ;LONG
FIRSTBYTE EQU TEXTBUF-2 ;WORD
BYTECOUNT EQU FIRSTBYTE-2 ;WORD
INFO EQU -8 ;4 WORDS
NUMER EQU INFO-4 ;POINT
DENOM EQU NUMER-4 ;POINT
VARSIZE EQU DENOM ;TOTAL BYTES OF LOCALS
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
CLR RESULT(A6) ;INIT RESULT TO 0
CLR -(SP) ;MAKE ROOM FOR FCN CALL BELOW
MOVE BYTECOUNT(A6),-(SP) ;PUSH BYTE COUNT
BLE.S GOHOME ;QUIT IF COUNT <= 0
;UNLK TAKES CARE OF SP
MOVE.L TEXTBUF(A6),A0 ;GET ADDR OF BUFFER
ADD FIRSTBYTE(A6),A0 ;ADD STARTING INDEX
MOVE.L A0,-(SP) ;PUSH TEXTADDR
MOVE.L #$00010001,D0
MOVE.L D0,NUMER(A6) ;NUMER := (1,1)
MOVE.L D0,DENOM(A6) ;DENOM := (1,1)
PEA NUMER(A6) ;PUSH VAR NUMER
PEA DENOM(A6) ;PUSH VAR DENOM
PEA INFO(A6) ;PUSH VAR INFO
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
lea JStdTxMeas,a0 ; <20> DTY Changed from move.l JStdTxMeas,a0
MOVE.L (a0),A0 ;get piece of trap table
BEQ.S USESTD ;YES, USE STDTXMEAS
MOVE.L D0,A0 ;NO, GET GRAFPROCS
MOVE.L TXMEASPROC(A0),A0 ;GET TXMEAS CAPTURE PROC
USESTD JSR (A0) ;CALL IT
MOVE (SP)+,D1 ;POP UNSCALED WIDTH
MOVE NUMER+H(A6),D0 ;get numer
MOVE DENOM+H(A6),D2 ;get denom
CMP D2,D0 ;is numer same as denom ?
BEQ.S DONE ;yes, skip muldiv
MULU D0,D1 ;MUL BY NUMER
DIVU D2,D1 ;DIV BY DENOM
DONE MOVE D1,RESULT(A6) ;RETURN SCALED WIDTH
GOHOME UNLINK PARAMSIZE,'TEXTWIDT'
ENDIF ; NOT hasSplineFonts <1.6-4april89-CEL>
StdTxMeas FUNC EXPORT
IMPORT CalcCharExtra
;------------------------------------------
;
; FUNCTION StdTxMeas(count: INTEGER; textAddr: Ptr;
; VAR numer,denom: Point;
; VAR info: FontInfo): INTEGER;
;
; Measure some text, returning unscaled values plus updated scale factor.
; Fills info record with unscaled ascent, descent, widMax, and leading,
; and returns unscaled integer width as the function value.
;
; Also leaves unscaled fixed point width in QD global 'FontAdj'
; and stashes FMOutPtr in QD global 'fontPtr' for DrawText.
;
PARAMSIZE EQU 18
RESULT EQU PARAMSIZE+8 ;FCN RESULT IS A WORD
COUNT EQU RESULT-2 ;WORD
TEXTADDR EQU COUNT-4 ;LONG
NUMER EQU TEXTADDR-4 ;LONG, VAR ADDR
DENOM EQU NUMER-4 ;LONG, VAR ADDR
INFO EQU DENOM-4 ;LONG, ADDR OF FONTINFO
INREC EQU -16 ;FMInput record
characterExtra EQU INREC-4 ;LONG
widthExtra EQU characterExtra-4 ;LONG <31-CEL>
encodingTable EQU widthExtra-4 ;LONG
VARSIZE EQU encodingTable
LINK A6,#VARSIZE ;ALLOCATE LOCALS
if (hasDoubleByte) then
movem.l d4/a2-a3,-(sp) ; save double-byte registers
clr.l encodingTable(a6) ; assume no encoding table
endif
MOVEM.L D3/A4,-(SP) ;SAVE REG <30-CEL/RWB>
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A0 ;GET CURRENT GRAFPORT
LEA INREC(A6),A1 ;POINT TO FMINPUT RECORD
MOVE TXFONT(A0),(A1)+ ;GET TXFONT FROM THEPORT
MOVE TXSIZE(A0),(A1)+ ;GET TXSIZE FROM THEPORT
MOVE.B TXFACE(A0),(A1)+ ;GET TXFACE FROM THEPORT
ST (A1)+ ;ALWAYS SET NEEDBITS TRUE
MOVE DEVICE(A0),(A1)+ ;GET DEVICE FROM THEPORT
MOVE.L NUMER(A6),A0 ;POINT TO NUMER
MOVE.L (A0),(A1)+ ;INSTALL INPUT NUMER
MOVE.L DENOM(A6),A0 ;POINT TO DENOM
MOVE.L (A0),(A1)+ ;INSTALL INPUT DENOM
CLR.L -(SP) ;ROOM FOR FCN RESULT
PEA INREC(A6) ;PUSH INPUT RECORD
_FMSwapFont ;CALL FMSwapFont trap
MOVE.L (SP)+,A1 ;POP FMOUTPUT POINTER
MOVE.L A1,FONTPTR(A4) ;STASH FMOUTPTR FOR LATER
; determine scaled character extra, if applicable
clr.l d0 ; clear the character extra.
move.l thePort(a4),a0 ; load the current grafPtr.
tst.b portBits+rowBytes(a0) ; is this an old grafPort?
bpl.s @oldGrafPort ; yes -> skip this.
move.w chExtra(a0),d0 ; load the character extra.
ext.l d0 ; for sign bits <29>
asl.l #4,d0 ; convert to 16.16 format.
@oldGrafPort
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <24>
add.l qdChExtra(a0),d0 ; add in the character extra. <24>
ENDIF
tst.l d0 ; have zero character extra?
beq.s @zeroCharExtra ; yes -> skip call to scale.
bsr CalcCharExtra ; scale by point size, etc.
@zeroCharExtra
move.l d0,characterExtra(a6) ; store scaled character extra.
MOVE.L INFO(A6),A0 ;POINT TO VAR INFO RECORD
CLR.L (A0) ;INIT TO (0,0,0,0)
CLR.L 4(A0) ;ALL 4 WORDS
CLR.L D1 ;INIT WIDTH TO 0.0 <32-CEL>
MOVE.L A1, -(SP) ;Save off A1 to use for WidthTabHandle
MOVE.L WidthTabHandle, A1 ;Get the Width Table
MOVE.L (A1), A1 ;get the pointer
TST.B WidthIsSpline(A1) ;Is it a spline font
BEQ.S @doNormal ;No then branch normal
MOVE.L expandMem, A1 ; get low mem expand
MOVE.L ExpandMemRec.emSplineKey(A1), A1 ; Handle to splineKey
MOVE.L (A1), A1 ; pointer to splinekey
MOVE.L splineKeyRec.cacheHand(A1), D0 ; is there a cache
BEQ.S @bailForZeros
MOVE.L D0, A1 ; get Handle in addr reg
TST.L (A1) ; Is it purged
BEQ.S @bailForZeros ; bail since we have no cache
MOVE.L (A1), A1 ;get the pointer
WITH cache ;<13>
MOVE.W ascent(A1), (A0)+ ;Assign the Ascent value
MOVE.W descent(A1), (A0)+ ;Assign sfnt Descent
MOVE.W widMax(A1), (A0)+ ;Assign WidMax
MOVE.W leading(A1), (A0) ;Assign Leading
MOVE.W rOverHMax(A1), D1 ;get rExtraHang value <32-CEL>
ADD.W rightItalic(A1), D1 ;Add in possible italic slop <32-CEL>
ADD.W #3, D1 ;Add 3 for grid fitting slop <32-CEL>
if (hasDoubleByte) then
move.l fEncodingTablePointer(a1),encodingTable(a6) ; load encoding table pointer
endif
ENDWITH ;<13>
MOVE.L (SP)+, A1 ;Restore A1
BRA.S @cont ;Skip past byte assignments
@bailForZeros
CLR.L (A0)+ ;Zero out ascent and descent
CLR.L (A0)+ ;Zero out widMax and leading
MOVE.L (SP)+, A1 ;Restore A1
BRA.S @cont ;Skip past byte assignments
@doNormal ;<1.6-4april89-CEL>
MOVE.L (SP)+, A1 ;Restore A1
MOVE.B 13(A1),1(A0) ;FILL IN UNSIGNED ASCENT
MOVE.B 14(A1),3(A0) ;FILL IN UNSIGNED DESCENT
MOVE.B 15(A1),5(A0) ;FILL IN UNSIGNED WIDMAX
MOVE.B 16(A1),D0 ;GET SIGNED LEADING
EXT.W D0 ;SIGN EXTEND TO WORD
MOVE.W D0,6(A0) ;FILL IN LEADING
@cont ;Label to skip byte assignment
;
; UPDATE NUMER AND DENOM
;
MOVE.L NUMER(A6),A0 ;GET VAR ADDR
MOVE.L 18(A1),(A0) ;UPDATE NUMER
MOVE.L DENOM(A6),A0 ;GET VAR ADDR
MOVE.L 22(A1),(A0) ;UPDATE DENOM
MOVE.L expandMem,A0 ; get low memory expand pointer. <31>
MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <31>
MOVE.L (A0), A0 ; get pointer to splineKey globals. <31>
CMP.W #-2, splineKeyRec.safeCount(A0) ;-2 means add penloc <33-CEL>
BNE.S @noPen ;skip penloc add <33-CEL>
MOVE.L thePort(A4),A1 ;GET CURRENT GRAFPORT <30-CEL/RWB>
MOVE.W PNLOC+H(A1),D0 ;add penlocation <33-CEL>
BLE.S @noPen ;skip if negative <33-CEL>
ADD.W D0,D1 ;add penlocation <33-CEL>
@noPen ADD.W #5, D1 ;ADD 5 for style slop and round <32-CEL/RWB>
SWAP D1 ; <30-CEL/RWB>
MOVE.L D1, widthExtra(A6) ;save off width extra value <32-CEL>
MOVE.L D1, D3 ;Init to penloc + 1.0 <30-CEL/RWB>
MOVE.W #-1, splineKeyRec.safeCount(A0) ; init to -1 for flagging <31>
MOVE.L TEXTADDR(A6),A0 ;POINT TO CHARACTERS
MOVE.L WidthTabHandle,A1 ;POINT TO WIDTH TABLE
MOVE.L (A1),A1
if (hasDoubleByte) then
move.l encodingTable(a6),a2 ; load pointer to high byte mapping table
move.l a2,a3 ; copy pointer
adda #256,a3 ; offset pointer to low byte mapping table
endif
MOVE COUNT(A6),D2 ;GET CHARACTER COUNT
BRA.S MORE ;GO TO LOOP START
NEXTCH CLR D0 ;GET READY FOR BYTE
MOVE.B (A0)+,D0 ;GET A CHARACTER
if (hasDoubleByte) then
tst.l encodingTable(a6) ; have encoding table?
beq @singleByteFont ; no -> skip this
tst.b 0(a2,d0.w) ; high byte of double byte character?
beq @singleByteCharacter ; no -> skip this
tst.w d2 ; more bytes left in text?
ble @remapHighByte ; no -> remap the high byte
sub.w #1,d2 ; decrement the text count
clr.w d4 ; clear high byte of low word
move.b (a0)+,d4 ; grab the low byte and increment the text pointer
tst.b 0(a3,d4.w) ; is the low byte valid?
bne @measureHighByte ; yes -> use the high byte for the width
@remapHighByte
move.b #1,d0 ; remap the high byte to the missing character
@singleByteFont
@singleByteCharacter
@measureHighByte
endif
LSL #2,D0 ;QUAD FOR TABLE OFFSET
ADD.L 0(A1,D0),D1 ;add the width fixed point value
BVS OverFlow ;CHECK FOR POSSIBLE OVERFLOW <30-CEL/RWB>
MOVE.L D1, D3 ;save of safe length <30-CEL/RWB>
CMP #$80,D0 ;space?
BEQ.S MORE ;skip character extra
ADD.L characterExtra(A6),D1 ;add in character extra, if any, for others
BVS OverFlow ;if overflow, set to big positive <30-CEL/RWB>
MOVE.L D1, D3 ;save of safe length <30-CEL/RWB>
MORE DBRA D2,NEXTCH ;LOOP FOR ALL CHARS
BRA.S noOverFlow ;Branch around overflow corrections <30-CEL/RWB>
OverFlow
ADDQ #1, D2 ;Add back 1 to the remaining count <30-CEL/RWB>
NEG D2 ;Negate for addition <30-CEL/RWB>
ADD.W Count(A6), D2 ;newCount = OrigCount - remainder <30-CEL/RWB>
MOVE.L expandMem,A0 ; get low memory expand pointer. <30-CEL/RWB>
MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <30-CEL/RWB>
MOVE.L (A0), A0 ; get pointer to splineKey globals. <30-CEL/RWB>
MOVE.W D2, splineKeyRec.safeCount(A0) ; new count <30-CEL/RWB>
MOVE.L D3, D1 ;restore safe length <30-CEL/RWB>
noOverFlow ; <30-CEL/RWB>
SUB.L widthExtra(A6), D1 ;sub widthExtra calc from width <32-CEL>
MOVE.L D1,FontAdj(A4) ;STASH FIXED POINT WIDTH
SWAP D1 ;GET HI WORD = INTEGER PORTION
MOVE D1,RESULT(A6) ;UPDATE FUNCTION RESULT
MOVEM.L (SP)+,D3/A4 ;RESTORE REG <30-CEL/RWB>
if (hasDoubleByte) then
movem.l (sp)+,d4/a2-a3 ; restore double-byte registers
endif
UNLINK PARAMSIZE,'STDTXMEA'
IF (forROM OR SCRIPT_CHAR_EXTRA OR hasDoubleByte) THEN ;<1.6-4april89-CEL> <8> CEL
PROC
EXPORT MeasureText
IMPORT CalcCharExtra
IF (forROM) THEN
IMPORT TextWidth
ENDIF
;--------------------------------------------------------------------
;
; PROCEDURE MeasureText(count: INTEGER; textAddr,charLocs: Ptr);
;
; Measure some text, returning (scaled) screen widths in charlocs.
;
; Charlocs points to an array of count+1 integers.
;
; Modification History
; 29Oct86 CRC Call textMeasProc via TextWidth for the benefit of
; ThinkÕs Macintosh Pascal. (Margie TextEdit used to use
; TextWidth but changed to MeasureText for efficiency;
; Think added styles to TextEdit inside the bottleneck
; procs that no longer got called. This calls the bottleneck
; proc only if it is different from StdTxMeas, since the
; speed hit is appreciable.)
PARAMSIZE EQU 10
COUNT EQU PARAMSIZE+8-2 ;WORD
TEXTADDR EQU COUNT-4 ;LONG, Ptr to ASCII
CHARLOCS EQU TEXTADDR-4 ;LONG, Ptr to output array
INREC EQU -16 ;FMInput record
characterExtra EQU INREC-4 ;Long
encodingTable EQU characterExtra-4 ;double byte encoding table
IF SCRIPT_CHAR_EXTRA THEN ; <15> pke
numer EQU encodingTable-4 ; <15> pke
denom EQU numer-4 ; <15> pke
VARSIZE EQU denom ; <15> pke
ELSE ; <15> pke
VARSIZE EQU encodingTable
ENDIF ; <15> pke
StdTxMeasTrap EQU $ED
MeasureText
LINK A6,#VARSIZE ;ALLOCATE LOCALS
IF SCRIPT_CHAR_EXTRA THEN
move.l #$00010001,numer(a6) ; set numerator to one/one
move.l #$00010001,denom(a6) ; set denominator to one/one
ENDIF
if (hasDoubleByte) then
move.l d7,-(sp) ; save low byte scratch register
endif
MOVEM.L D3-D6/A2-A4,-(SP) ;SAVE REGS
MOVE.L TextAddr(A6),A2
MOVE.L CharLocs(A6),A3
MOVE Count(A6),D3
MOVEQ #0,D4 ;INIT WIDTH TO 0.0
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A0 ;GET CURRENT GRAFPORT
; if there is a txMeasProc not equal to StdTxMeas, call CharWidth instead
MOVE.L grafProcs(A0),D0 ;are there overridden graf procs?
BEQ.S useSwapFont
MOVE.L D0,A1
MOVE.L txMeasProc(A1),D0
lea JStdTxMeas,a1 ; <20> DTY Changed from cmp.l JStdTxMeas,d0; changed from a0 to a1 <26>
CMP.L (a1),D0 ; changed from a0 to a1 <26>
BEQ.S useSwapFont
MOVEQ #0,D6 ;furthest character right so far
MOVEQ #0,D5 ;sum to add in to fix text width
SUBQ #2,SP ;make room for the returned width
nextChar
MOVE.L A2,-(SP)
CLR -(SP)
MOVE D4,-(SP)
_TextWidth
MOVE (SP),D0 ;get the width
CMP D6,D0 ;is it smaller than the last measurement?
BGE.S @notSmaller ;if this is equal to or larger than last, no prob.
ADD D6,D5 ;if smaller, add last measurement to sum
@notSmaller
ADD D5,D0 ;add sum to character position
MOVE D0,(A3)+
MOVE (SP),D6 ;make this measure into last measure (for next time)
ADDQ #1,D4
CMP D3,D4
BLE.S nextChar ;LOOP FOR COUNT+1 CHARLOCS
ADDQ #2,SP ;toss character width
IF SCRIPT_CHAR_EXTRA THEN ; <15> pke
move.w numer+h(a6),d3 ; set up for scaling <15> pke
move.w denom+h(a6),d4 ; set up for scaling <15> pke
bra DoMeasureTextScaling ; go do scaling <15> pke
ELSE ; <15> pke
BRA NoScale
ENDIF ; <15> pke
useSwapFont
;
; Call swapfont to set up width table and return numer,denom:
;
LEA INREC(A6),A1 ;POINT TO FMINPUT RECORD
MOVE TXFONT(A0),(A1)+ ;GET TXFONT FROM THEPORT
MOVE TXSIZE(A0),(A1)+ ;GET TXSIZE FROM THEPORT
MOVE.B TXFACE(A0),(A1)+ ;GET TXFACE FROM THEPORT
ST (A1)+ ;ALWAYS SET NEEDBITS TRUE
MOVE DEVICE(A0),(A1)+ ;GET DEVICE FROM THEPORT
IF SCRIPT_CHAR_EXTRA THEN ; <15> pke
MOVE.L numer(a6),(A1)+ ;supply local numer <15> pke
MOVE.L denom(a6),(A1)+ ;supply local denom <15> pke
ELSE ; <15> pke
MOVE.L #$00010001,(A1)+ ;INSTALL INPUT NUMER = 1,1
MOVE.L #$00010001,(A1)+ ;INSTALL INPUT DENOM = 1,1
ENDIF ; <15> pke
CLR.L -(SP) ;ROOM FOR FCN RESULT
PEA INREC(A6) ;PUSH INPUT RECORD
_FMSwapFont ;CALL FMSwapFont trap
MOVE.L (SP)+,A0 ;POP FMOUTPUT POINTER
MOVE.W 18+H(A0),D3 ;GET NUMER.H
MOVE.W 22+H(A0),D4 ;GET DENOM.H
; determine scaled character extra, if applicable
clr.l d0 ; clear the character extra.
move.l thePort(a4),a0 ; load the current grafPtr.
tst.b portBits+rowBytes(a0) ; is this an old grafPort?
bpl.s @oldGrafPort ; yes -> skip this.
move.w chExtra(a0),d0 ; load the character extra.
ext.l d0 ; for sign bits <29>
asl.l #4,d0 ; convert to 16.16 format.
@oldGrafPort
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <24>
add.l qdChExtra(a0),d0 ; add in the character extra. <24>
ENDIF
tst.l d0 ; have zero character extra?
beq.s @zeroCharExtra ; yes -> skip call to scale.
bsr CalcCharExtra ; scale by point size, etc.
@zeroCharExtra
move.l d0,characterExtra(a6) ; store scaled character extra.
;
; Step thru characters, adding up unscaled widths and storing in charLocs:
;
MOVE.L WidthTabHandle,A1 ;POINT TO WIDTH TABLE
MOVE.L (A1),A1
if (hasDoubleByte) then
clr.l encodingTable(a6) ; assume no encoding table
tst.b WidthIsSpline(a1) ; have TrueType cache?
beq.s @notTrueType ; no, skip this
move.l expandMem,a0 ; load expanded memory pointer
move.l ExpandMemRec.emSplineKey(a0),a0 ; load TrueType globals handle
move.l (a0),a0 ; load TrueType globals pointer
move.l splineKeyRec.cacheHand(a0),d0 ; do we have a cache?
beq.s @cacheMissing ; no, skip this
move.l d0,a0 ; load current cache handle
move.l (a0),d0 ; cache purged from memory?
beq.s @cachePurged ; yes, skip this
move.l d0,a0 ; load current cache pointer
move.l cache.fEncodingTablePointer(a0),a4 ; load encoding table pointer
move.l a4,a3 ; copy pointer
adda #256,a3 ; offset pointer to low byte mapping table
move.l a4,encodingTable(a6) ; keep a copy for testing
@notTrueType
@cacheMissing
@cachePurged
endif
MOVE.L TEXTADDR(A6),A0 ;POINT TO CHARACTERS
MOVE.L CHARLOCS(A6),A2 ;POINT TO CHARLOCS
CLR.L D1 ;INIT WIDTH TO 0.0
MOVE COUNT(A6),D2 ;GET CHARACTER COUNT
NEXTCH SWAP D1 ;GET HI WORD OF WIDTH
MOVE.W D1,(A2)+ ;STORE IN CHARLOCS
SWAP D1 ;RETURN WIDTH TO FIXED POINT
CLR D0 ;GET READY FOR BYTE
MOVE.B (A0)+,D0 ;GET A CHARACTER
if (hasDoubleByte) then
tst.l encodingTable(a6) ; have encoding table?
beq @singleByteFont ; no -> skip this
tst.b 0(a4,d0.w) ; high byte of double byte character?
beq @singleByteCharacter ; no -> skip this
;cmpi.w #1,d2 ; more bytes left in text?
tst.w d2 ; more bytes left in text? <40> <JH 11/21/91> from <KON 11/20/91>
beq @remapHighByte ; no -> remap the high byte
sub.w #1,d2 ; decrement the text count
clr.w d7 ; clear high byte of low word
move.b (a0)+,d7 ; grab the low byte and increment the text pointer
tst.b 0(a3,d7.w) ; is the low byte valid?
beq @remapHighByte ; no -> remap the high byte
lsl #2,d0 ; convert to fixed width table offset
add.l 0(a1,d0),d1 ; add fixed point width
add.l characterExtra(a6),d1 ; always add in character extra
swap d1 ; get integer portion of accumulated width
move.w d1,(a2)+ ; ouch, store integer width into charLocs array
swap d1 ; restore d1 to fixed point
bra MORE ; restart the loop
@remapHighByte
move.b #1,d0 ; remap the high byte to the missing character
@singleByteFont
@singleByteCharacter
endif
LSL #2,D0 ;QUAD FOR TABLE OFFSET
ADD.L 0(A1,D0),D1 ;ADD FIXED POINT WIDTH
CMP #$80,D0 ;is it a space?
BEQ.S MORE ;skip character extra if so
ADD.L characterExtra(A6),D1 ;add in character extra
MORE DBRA D2,NEXTCH ;LOOP FOR COUNT+1 CHARLOCS
;
; if font is horizontally stretched, scale all widths accordingly
;
DoMeasureTextScaling ; <15> pke
CMP D3,D4 ;IS NUMER.H = DENOM.H ?
BEQ.S NOSCALE ;YES, SKIP SCALING
MOVE.L CHARLOCS(A6),A2 ;NO, POINT TO CHARLOCS
MOVE COUNT(A6),D2 ;GET CHARACTER COUNT
NEXTCH2 MOVE (A2),D0 ;GET CHARLOC
MULU D3,D0 ;MUL BY NUMER
DIVU D4,D0 ;DIV BY DENOM
MOVE D0,(A2)+ ;UPDATE CHARLOC
DBRA D2,NEXTCH2 ;LOOP FOR COUNT+1 CHARLOCS
NOSCALE
MOVEM.L (SP)+,D3-D6/A2-A4 ;RESTORE REGS
if (hasDoubleByte) then
move.l (sp)+,d7 ; restore low byte scratch register
endif
UNLINK PARAMSIZE,'MEASURET'
ENDIF
;--------------------------------------------------------------------
;
; FUNCTION FMSwapFont(inRec: FMInput): FMOutPtr;
;
; FMSwapFont is the only contact between QuickDraw and the Font Manager.
; It swaps in the requested font and returns a pointer to an output record
; telling how to use the font. FMSwapFont is called from StdTxMeas
; in response to DrawChar, DrawString, DrawText, CharWidth, StringWidth,
; TextWidth, and GetFontInfo.
;
; IF fontHandle returns as Nil (can't find the font), then:
; 1. The output record will be undefined except for errNum and fontHandle.
; 2. DrawString will neither draw the text nor bump the pen.
; 3. StringWidth will return 0.
; 4. GetFontInfo will return 0,0,0,0.
;
;
; FMInput = PACKED RECORD
; family: INTEGER; { i.e. Century }
; size: INTEGER; { i.e. 12 point }
; face: Style; { i.e. [bold,underlined] }
; needBits: BOOLEAN; { do we need the bitmaps ? }
; device: INTEGER; { i.e. 0 for screen }
; numer: Point; { current drawing scale }
; denom: Point; { current drawing scale }
; END;
;
;
; FMOutPtr = ^FMOutPut;
; FMOutput = PACKED RECORD
; errNum: INTEGER; { not used }
; fontHandle: Handle; { handle to font }
; bold: Byte; { how much to smear horiz }
; italic: Byte; { how much to shear }
; ulOffset: Byte; { pixels below baseline }
; ulShadow: Byte; { how big is the halo }
; ulThick: Byte; { how thick is the underline }
; shadow: Byte; { 0,1,2,or 3 only }
; extra: SignedByte; { extra white dots each char }
; ascent: Byte; { ascent measure for font }
; descent: Byte; { descent measure for font }
; widMax: Byte; { width of widest char }
; leading: SignedByte; { leading between lines }
; unused: Byte;
; numer: Point; { use this modified scale to }
; denom: Point; { draw or measure text with }
; END;
;
;
;
;--------------------------------------------------------------------------
IF (forROM) THEN ;<SMxx> CSS <8> CEL
GetFontInfo PROC EXPORT
;------------------------------------------
;
; PROCEDURE GetFontInfo(VAR info: FontInfo);
;
; Calls StdTxMeas thru capture proc, then adjusts and scales the result.
;
; 13 MAY 85, changed so that all 4 values round UP in the case of scaling.
;
PARAMSIZE EQU 4
INFO EQU PARAMSIZE+8-4 ;LONG, ADDR OF INFO
NUMER EQU -4 ;POINT
DENOM EQU NUMER-4 ;POINT
VARSIZE EQU DENOM ;TOTAL LOCALS
LINK A6,#VARSIZE ;ALLOCATE LOCALS
MOVE.L #$00010001,NUMER(A6) ;NUMER := (1,1)
MOVE.L #$00010001,DENOM(A6) ;DENOM := (1,1)
CLR.L -(SP) ;ROOM FOR FCN, COUNT = 0
CLR.L -(SP) ;TEXTADDR := NIL
PEA NUMER(A6) ;PUSH VAR NUMER
PEA DENOM(A6) ;PUSH VAR DENOM
MOVE.L INFO(A6),-(SP) ;PUSH VAR INFO
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ?
lea JStdTxMeas,a0 ; <20> DTY Changed from move.l JStdTxMeas,a0
MOVE.L (a0),A0 ;get piece of trap table
BEQ.S USESTD ;YES, USE STD PROC
MOVE.L D0,A0
MOVE.L TXMEASPROC(A0),A0 ;NO, GET TXMEAS CAPTURE PROC
USESTD JSR (A0) ;CALL IT
TST (SP)+ ;DISCARD WIDTH FCN RSLT
;
; ADJUST WIDMAX FOR EXTRA
;
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L FONTPTR(A0),A0 ;GET FMOUTPUT RECORD
MOVE.L INFO(A6),A1 ;POINT TO RESULT INFO
MOVE.B 12(A0),D0 ;GET SIGNED EXTRA
EXT.W D0 ;EXTEND TO WORD
ADD D0,4(A1) ;ADD TO WIDMAX
;
; ADJUST ASCENT & DESCENT FOR SHADOW
;
CLR D0 ;GET READY FOR BYTE
MOVE.B 11(A0),D0 ;GET SHADOW COUNT
BEQ.S NOTSHAD ;SKIP IF ZERO
ADD #1,0(A1) ;ADJUST ASCENT
ADD D0,2(A1) ;ADJUST DESCENT
NOTSHAD
;
; SCALE RESULT IF NUMER <> DENOM
;
MOVE.L NUMER(A6),D0
CMP.L DENOM(A6),D0 ;IS NUMER SAME AS DENOM ?
BEQ.S NOSCALE ;YES, SKIP SCALING
BSR.S SCALE ;SCALE ASCENT
BSR.S SCALE ;SCALE DESCENT
MOVE (A1),D0 ;GET MAXWID
MULU NUMER+H(A6),D0 ;SCALE MAXWID
MOVE DENOM+H(A6),D1 ;get denom
LSR #1,D1 ;calc denom div 2
EXT.L D1 ;extend to long
ADD.L D1,D0 ;add denom div 2 to round
DIVU DENOM+H(A6),D0 ;divide by denom
MOVE D0,(A1)+ ;UPDATE MAXWID
BSR.S SCALE ;SCALE LEADING
NOSCALE UNLINK PARAMSIZE,'GETFONTI'
SCALE MOVE (A1),D0 ;GET IT
MULU NUMER+V(A6),D0 ;SCALE IT
MOVE DENOM+V(A6),D1 ;get denom
LSR #1,D1 ;calc denom div 2
EXT.L D1 ;extend to long
ADD.L D1,D0 ;add denom div to round up
DIVU DENOM+V(A6),D0 ;divide by denom
MOVE D0,(A1)+ ;UPDATE IT
RTS
ENDIF
IF (forROM) THEN ;<1.6-4april89-CEL>
CharExtra PROC EXPORT
;------------------------------------------
;
; PROCEDURE CharExtra(extra: Fixed);
;
; An external routine that sets the extra space for each character other than the
; space character. The txSize of the port must be set properly prior to this call,
; since currently the long extra is condensed to a 4.12 format word. Worse, it is
; thrown away altogether if the port is an old port.
MOVE.L ([grafGlobals,A5],thePort),A0 ;get the port
TST PORTBITS+ROWBYTES(A0) ;is it a new port?
BPL.S @noHelp ;no, donÕt set up characterExtra
SUBQ #4,SP ;make room for result
MOVE.L 8(SP),-(SP) ;pass input parameter
MOVE txSize(A0),D0 ;get the text size
BNE.S @notZero ;not FMDefault
TST txFont(A0) ;system font?
BNE.S @apFont ;if not, use default
MOVE SysFontSize,D0 ;if family is zero, use system font size
BNE.S @notZero
@apFont
MOVE.B FMDefaultSize,D0 ;if family nonzero or system font size zero,
BNE.S @notZero ; use the default size
MOVEQ #12,D0 ;if the default is zero, hardcode to 12
@notZero
SWAP D0 ;make it a fixed number
CLR D0 ;zero the fraction
MOVE.L D0,-(SP)
_FixDiv ;reduce it down to word size, hopefully
MOVE.L (SP)+,D0 ;get result
ASR.L #4,D0 ;get 4 bits of integer + 12 bits frac in lo word
MOVE.L ([grafGlobals,A5],thePort),A0 ;get the port again
MOVE D0,chExtra(A0) ;save the character extra
@noHelp
RTD #4 ;throw away the input parameter and go home
ENDPROC
ENDIF ;NOT hasSplineFonts
CASE OFF