mac-rom/QuickDraw/Text.a

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