; ; 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): ; ; 7/16/92 CSS Update from Reality: ; <41> 4/24/92 DTY Get rid of hasSplineFonts conditionals. ; 5/11/92 CSS Fixed problem with graying text causing the text to be erased. ; Removed If not forRom conditional in StdText. ; 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> from 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 ; 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