; ; File: Text.m.a ; ; Contains: Standard procs for text manipulation. ; ; Copyright: © 1988-1992 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <35> 4/24/92 DTY Get rid of hasSplineFonts conditionals. Also get rid of forROM ; conditionals, since this file is not used for ROM builds. ; <34> 10/23/91 ngk Changed case of PUTPICWORD to PutPicWord so that ROMBinds are ; happy ; <33> 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. ; <32> 8/30/91 DTY Define onMac here now that it’s not an available feature in ; BBSStartup. Defined to be 1 for the System build because onMac ; used to be a feature of the System build. ; <31> 6/12/91 LN added #include 'SysPrivateEqu.a' ; <30> 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. ; <29> 2/21/91 KON DFH: BRC #82863, GrayishTextOr mode should not be saved to ; pictures in System 7. ; <28> 1/15/91 CL (MR)Now safecount must be set to -2 if the pen loc needs to be ; added inside of stdtxmeas. ; <27> 1/14/91 CL (RB) Fixed more problems in long string phenomenom. Style ; variations such as italic when measured did not add in slop when ; checking overflow calculation in stdtxmeas. ; <26> 1/14/91 SMB (jdt) Initializing overflow count to -1. ; <25> 1/10/91 KON If a font name does not exist for a given ID when doing font ; name/ID binding, don't write a $2C opcode to the picture. [SMC] ; <24> 1/9/91 RB (CEL/PKE/GM/DA) Fixing long string overflow bug by truncating ; the count. Duplicated text.a changes. ; <23> 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. Fixed MeasureText for double-byte chars. ; <22> 8/17/90 dvb Add grayish mode slime. ; <21> 8/1/90 MR Fix some Case Sensitivity for the Gaudi INIT ; <20> 8/1/90 KON Add DoPict2 for rom build. ; <19> 7/26/90 KON Non-init (non-gaudi) versions of StdText should always call RAM ; version of CheckPic so Pict2 creation with OpenCPicture ; works. ; <19> 7/25/90 KON Non-init (non-gaudi) versions of StdText should always call RAM ; versions of CheckPic and DoPict2 so PICT2 creation with ; OpenCPicture works. ; <18> 7/20/90 DTY Bass: The Linked Patch. Added conditional Black and White names ; for routines, since Bass is carrying around two versions of this ; file, and the names need to be unique. Conditionalised jumps ; into ROM (CheckPic, PutPicByte, etc.): ROM builds continue to ; use bsr.l, but Bass builds will use jsrROM macro. ; <17> 6/22/90 CL Using the shared GrafTypes.m.a and added new include file ; fontPrivate.a and other include files needed. ; <16> 6/20/90 KON OpenCPicture creates a PICT2, so we need to word align opcodes ; when we are creating PICT2's. ; <15> 6/9/90 JT Need to import the CalcCharExtra routine that we now share with ; Text.a (sorry about that). ; <14> 6/9/90 JT Now scale the character extra by the font size specified in the ; current GrafPort. This is the same treatment normally given to ; chExtra by ColorQuickDraw. Note that these two extra values are ; added together before they are scaled. Also, these routines now ; rely on the CalcCharExtra routine to perform the scaling. ; <13> 6/7/90 PKE Add scaling parameters to MeasureText stack frame, set them from ; new ExpandMem globals, use them to scale results. ; <12> 5/29/90 CL Placed vertical metrics into cache instead of the widthtable. ; <11> 4/24/90 JT Save the Script Manager line-layout information when spooling a ; picture in StdText. Changed some short branches to long branches ; since the destinations are farther away when all of the ; conditional code is included. ; <10> 4/23/90 JT Save the Script Manager line-layout information when spooling a ; picture in StdText. ; <9> 4/17/90 HJR Fix Case OBJ problem. ; <8> 4/16/90 HJR Change SPLINE_FONTS to hasSplineFonts. ; <7> 4/10/90 CL Added support for double byte codes ; <6> 3/26/90 CL Adding measuretext for system build for script manager addition ; of character extra. ; <5> 3/21/90 CL Fixing conditionals for rom build. Script Manager char extra ; addition. ; <4> 3/20/90 CL nothing change ; <3> 3/20/90 CL Adding in Script Managers special charextra for 68000 class ; machines ; <2> 2/27/90 CL The Bass init code working on 6.0.4 systems do not use the pict ; font name matching. ifdefed them out. ; <1.9> 11/7/89 KON Added support for font name/ID binding ; <1.8> 8/28/89 CEL Only need to use word part of ascent, descent, widmax & leading ; <1.7> 7/6/89 GGD Un-Func'd TextWidth so that alignment wouldn't screw up ; StringWidth falling into it. ; <1.6> 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.5> 5/4/89 CEL Cleaned up conditionals for ROM, HcMac works now! Blasting in ; fix… ; <•1.4> 5/3/89 CEL Bass rolled into ROM. NOTE:Spline Fonts are conditionalized out. ; Blasting in correct file ; <•1.2> 5/1/89 cel Rolled in Bass… ; <1.1> 11/11/88 CCH Fixed Header. ; <1.0> 11/9/88 CCH Adding to EASE. ; <1.2> 10/12/88 CCH Changed “m.GrafType.a” to “GrafType.m.a”. ; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE. ; <1.0> 2/11/88 BBM Adding file for the first time into EASE… ; ; To Do: ; BLANKS ON STRING ASIS if (&type('onMac') = 'UNDEFINED') then onMac: equ 1 ; Define as true because this is the way it used to be in for System builds before Dean and Darin messed with BBSStartup endif IF (&TYPE('INITVERSION') = 'UNDEFINED') THEN Gaudi EQU 0 ; No init if not defined. ELSE Gaudi EQU 1 ENDIF IF (&TYPE('hasDoubleByte') = 'UNDEFINED') THEN hasDoubleByte EQU 1 ENDIF IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN ; <5> CEL SCRIPT_CHAR_EXTRA EQU 1 ENDIF IF (&TYPE('hasGlyphState') = 'UNDEFINED') THEN hasGlyphState EQU 1 ENDIF CASE OBJ INCLUDE 'Traps.a' INCLUDE 'sysequ.a' INCLUDE 'GRAFTYPES.m.a' INCLUDE 'fontPrivate.a' INCLUDE 'LinkedPatchMacros.a' INCLUDE 'ToolEqu.a' INCLUDE 'SysPrivateEqu.a' INCLUDE 'SplineDefines.a' ;--------------------------------------------------------- ; ; ; ***** ***** * * ***** ; * * * * * ; * * * * * ; * *** * * ; * * * * * ; * * * * * ; * ***** * * * ; ; ; Routines for measuring and drawing Text. ; ;------------------------------------------- ; ; 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 ASCENT EQU 18 ;WORD DESCENT EQU 20 ;WORD XOFFSET EQU 22 ;WORD RASTER EQU 24 ;WORD BWStdText PROC EXPORT IMPORT BWDrText if not( Gaudi) then IMPORT CHECKPIC,DPUTPICBYTE,PUTPICDATA,PUTPICWORD,PUTPICLONG,DOPICT2 endif ;---------------------------------------------------------- ; ; PROCEDURE StdText(); ; ; This is a check at the head of StdText to support grayish text mode. ; if txMode is 49, then call the old stdtext with text ormode, and ; then stamp bic'ed gray patter over its bounds. ; else, just go on to the real stdText 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 finfo DS.B 8 ; font info record myr DS.B 8 ; rectangle of text to stamp numerCopy DS.B 4 ; copies for stdTxMeas call denomCopy DS.B 4 linkSize DS.B 0 ; size of record ENDR grayishTextOr EQU 49 ; this is in QuickEqu.a, its not icl'd 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 ; join the original ROM code. @itsus ; do text and bic-stamp LINK A6,#linkSize MOVE.L picSave(A0),oldPicSave(A6) ; disable picture saving (a0 still valid) CLR.L picSave(A0) PEA oldPen(A6) ; Save Penstate _GetPenState _PenNormal SUBQ #2,SP ; figure out the width of the text 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 ; leave pen advance on stack PEA finfo(A6) ; did stdTxMeas do that? _GetFontInfo MOVE.L oldPen(A6),D1 ; D1 = previous pen position MOVE D1,myr+left(A6) ; save pen.h ADD (SP)+,D1 ; D1 = pen.h + pen advance MOVE D1,myr+right(A6) ; to get right SWAP D1 ; D1 = pen.v MOVE D1,D2 SUB finfo+0(A6),D2 ; (0=ascent)figger highest point ADD finfo+2(A6),D1 ; (2=descent)and lowest point MOVE D2,myr+top(A6) MOVE D1,myr+bottom(A6) ; myr is now the string's bounds MOVE #srcOr,-(SP) ; draw text in srcOr _TextMode MOVE count(A6),-(SP) MOVE.L string(A6),-(SP) MOVE.L xNumer(A6),-(SP) MOVE.L xDenom(A6),-(SP) JSR ReglarStdText MOVE #grayishTextOr,-(SP) ; restore textmode _TextMode 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 PEA oldPen(A6) ; Restore Penstate _SetPenState MOVE.L (A5),A0 ; restore picture saving MOVE.L (A0),A0 ; MOVE.L oldPicSave(A6),picSave(A0) ; UNLK A6 MOVE.L (SP)+,A0 ADD #result-return-4,SP JMP (A0) reglarstdtext ;-------------------------------------------------------------------------- ; ; 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 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 if Gaudi then jsrROM CheckPic ; <18> DTY else JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE endif 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 ;---------- START OF <03Nov89 KON> ADDITION -------------- 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.s 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 ; move.l sp,-(sp) ; addq.l #2,(sp) ;push var font name pea 2(sp) ;push var font name _GetFName move.b (sp),d1 ;check for empty string beq.s @badID ;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 lsl.w #1,d0 ;changed for 68K <03Nov89 KON> move.w d7,(a1,d0) ;store new ID if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$2C,D0 ;YES, GET Font Name PARAM OPCODE if (Gaudi) then jsrROM DPutPicByte ; <18> DTY else jsr DPUTPICBYTE ;PUT OPCODE endif 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 if not( Gaudi) then jsr PUTPICWORD ; else jsrROM PutPicWord ; <18> DTY endif MOVE D7,-(SP) if not( Gaudi) then jsr PUTPICWORD ;dump font id else jsrROM PutPicWord ; <18> DTY endif 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 if not( Gaudi) then jsr PUTPICDATA ;PUT TEXT DATA else jsrROM PutPicData endif @badID 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 ;---------- END OF <03Nov89 KON> ADDITION -------------- if not( Gaudi) then jsr DOPICT2 endif MOVEQ #3,D0 ;YES, PUSH TXFONT PARAM OPCODE if not( Gaudi) then jsr DPUTPICBYTE ;PUT OPCODE else jsrROM DPutPicByte ; <18> DTY endif MOVE D7,-(SP) if not( Gaudi) then JSR PUTPICWORD ;PUT TXFONT PARAM else jsrROM PutPicWord ; <18> DTY endif 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 if not( Gaudi) then jsr DOPICT2 endif MOVEQ #4,D0 ;YES, PUSH TXFACE PARAM OPCODE if not( Gaudi) then JSR DPUTPICBYTE ;PUT OPCODE else jsrROM DPutPicByte ; <18> DTY endif MOVE.B D7,D0 if not( Gaudi) then JSR DPUTPICBYTE ;PUT TXFACE PARAM else jsrROM DPutPicByte ; <18> DTY endif 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 if not( Gaudi) then jsr DOPICT2 endif MOVEQ #5,D0 ;YES, PUSH TXMODE PARAM OPCODE if not( Gaudi) then JSR DPUTPICBYTE ;PUT OPCODE else jsrROM DPutPicByte endif MOVE D7,-(SP) if not( Gaudi) then JSR PUTPICWORD ;PUT TXMODE PARAM else jsrROM PutPicWord endif MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE MOVE D7,PICTXMODE(A4) ;UPDATE CURRENT STATE ; ; CHECK TXSIZE ; MODEOK MOVE TXSIZE(A3),D7 ;GET THEPORT^.TXSIZE CMP PICTXSIZE(A4),D7 ;HAS IT CHANGED ? BEQ.S SIZEOK;NO, CONTINUE if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$0D,D0 ;YES, PUSH TXSIZE PARAM OPCODE BSR JDPUTPICBYTE ;PUT OPCODE MOVE D7,-(SP) if not( Gaudi) then JSR PUTPICWORD ;PUT TXSIZE PARAM else jsrROM PutPicWord endif 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 if not( Gaudi) then jsr DOPICT2 endif MOVEQ #6,D0 ;YES, PUSH SPEXTRA PARAM OPCODE BSR JDPUTPICBYTE ;PUT OPCODE MOVE.L D7,-(SP) BSR JPUTPICLONG ;PUT SPEXTRA PARAM 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. <23> move.l qdChExtra(a0),d5 ; load character extra amount. <23> move.l qdRunSlop(a0),d7 ; load run slop amount. <23> cmp.l picQdChExtra(a4),d5 ; has extra changed since last time? <23> bne.s @layoutChanged ; yes -> update the layout state. cmp.l picQdRunSlop(a4),d7 ; has slop changed since last time? <23> beq.s @layoutOK ; no -> skip this. @layoutChanged IF Gaudi THEN moveq #$2D,d0 ; load line layout opcode. bsr JDPUTPICBYTE ; put line layout opcode. move.w #8,-(sp) ; push the data length. jsrROM PutPicWord ; put the data length into the picture. move.l d5,-(sp) ; push the character extra amount. jsrROM PutPicLong ; put the character extra into the picture. move.l d7,-(sp) ; push the run slop amount. jsrROM PutPicLong ; put the run slop into the picture. ELSE jsr DOPICT2 ; pad picture data with zero if necessary. moveq #$2D,d0 ; load line layout opcode. bsr JDPUTPICBYTE ; put line layout opcode. move.w #8,-(sp) ; push the data length. jsr PUTPICWORD ; put the data length into the picture. move.l d5,-(sp) ; push the character extra amount. jsr PUTPICLONG ; put the character extra into the picture. move.l d7,-(sp) ; push the run slop amount. jsr PUTPICLONG ; put the run slop into the picture. ENDIF 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. <23> move.l d7,picQdRunSlop(a4) ; update current run slop. <23> @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 IF Gaudi THEN moveq #$2E,d0 ; load glyph state opcode bsr.s JDPUTPICBYTE ; put the opcode into the picture move.w #4,-(sp) ; push the data length jsrROM PutPicWord ; put the data length into the picture <34> fix case move.l d5,-(sp) ; push the glyph state jsrROM PUTPICLONG ; put the glyph state into the picture ELSE jsr DOPICT2 ; pad picture data with zero if necessary moveq #$2E,d0 ; load glyph state opcode bsr.s JDPUTPICBYTE ; put the opcode into the picture move.w #4,-(sp) ; push the data length jsr PUTPICWORD ; put the data length into the picture move.l d5,-(sp) ; push the glyph state jsr PUTPICLONG ; put the glyph state into the picture ENDIF move.l picSave(a3),a4 ; get picSave handle. move.l (a4),a4 ; dereference picSave. 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 if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$10,D0 ;YES, PUSH TXRATIO OPCODE BSR.S JDPUTPICBYTE ;PUT OPCODE MOVE.L D7,-(SP) BSR.S JPUTPICLONG ;PUT NUMER MOVE.L D5,-(SP) BSR.S JPUTPICLONG ;PUT DENOM 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 ;------------------------------------------------------------- ; ; USE DH AND DV TO CHOOSE ONE OF FOUR TEXT OPCODES. ; MOVE.L PNLOC(A3),D5 ;GET CURRENT PNLOC SUB.L PICTXLOC(A4),D5 ;CALC DV.DH 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 if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$28,D0 BSR.S JDPUTPICBYTE ;NO, PUT LONGTEXT OPCODE MOVE.L PNLOC(A3),-(SP) BSR.S JPUTPICLONG ;PUT PNLOC 4 BYTES BRA.S TEXT2 ;AND CONTINUE JDPUTPICBYTE if not( Gaudi ) then JMP DPUTPICBYTE else jmpROM DPutPicByte endif JPUTPICLONG if not( Gaudi ) then JMP PUTPICLONG else jmpROM PutPicLong endif SHORT MOVE.L D5,D0 ;YES, COPY DV.DH AND.L #$00FF0000,D0 ;IS DV = 0 ? BNE.S DV ;NO, CONTINUE if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$29,D0 BSR.S JDPUTPICBYTE ;YES, PUT DHTEXT OPCODE BRA.S SHARE2 ;SHARE COMMON CODE DV TST.B D5 ;IS DH = 0 ? BNE.S DHDV ;NO, CONTINUE if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$2A,D0 BSR.S JDPUTPICBYTE ;YES, PUT DHTEXT OPCODE BRA.S SHARE1 ;SHARE COMMON CODE DHDV if not( Gaudi) then jsr DOPICT2 endif MOVEQ #$2B,D0 BSR.S JDPUTPICBYTE ;PUT DHDVTEXT OPCODE MOVE.B D5,D0 BSR.S JDPUTPICBYTE ;PUT DH 0..255 TO PIC SHARE1 SWAP D5 ;PUT DV IN LO WORD SHARE2 MOVE.B D5,D0 BSR.S JDPUTPICBYTE ;PUT DH OR DV 0..255 TO PIC TEXT2 MOVE.B D6,D0 BSR.S JDPUTPICBYTE ;PUT COUNT BYTE TO PIC MOVE.L TEXTADDR(A6),-(SP) ;PUSH ADDR OF TEXT MOVE D6,-(SP) ;PUSH COUNT if not( Gaudi ) then JSR PUTPICDATA ;PUT TEXT DATA else jsrROM PutPicData ; <18> DTY endif MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE MOVE.L PNLOC(A3),PICTXLOC(A4) ;UPDATE PICTXLOC STATE ; ; DrText(count,textAddr,numer,denom); ; NOTPIC 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 BWDrText ; <18> DTY 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 MOVEM.L (SP)+,D5-D7/A3-A4 ;RESTORE REGS UNLINK PARAMSIZE,'STDTEXT ' BWStdTxMeas FUNC EXPORT IF SCRIPT_CHAR_EXTRA THEN IMPORT CalcCharExtra ENDIF ;------------------------------------------ ; ; 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 'fixTxWid' ; 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 <27-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 <24-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 _SwapFont ;CALL FMSWAPFONT MOVE.L (SP)+,A1 ;POP FMOUTPUT POINTER MOVE.L A1,FONTPTR(A4) ;STASH FMOUTPTR FOR LATER ; determine scaled character extra, if applicable clr.l characterExtra(a6) ; clear the character extra. IF SCRIPT_CHAR_EXTRA THEN move.l grafGlobals(a5),a0 ; load quickDraw globals. <23> move.l qdChExtra(a0),d0 ; load the character extra. <23> beq.s @zeroCharExtra ; yes -> skip call to scale. bsr CalcCharExtra ; scale by point size, etc. move.l d0,characterExtra(a6) ; store scaled character extra. @zeroCharExtra ENDIF 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 <27-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 <27-CEL> ADD.W rightItalic(A1), D1 ;Add in possible italic slop <27-CEL> ADD.W #3, D1 ;Add 3 for grid fitting slop <27-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. <26> MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <26> MOVE.L (A0), A0 ; get pointer to splineKey globals. <26> CMP.W #-2, splineKeyRec.safeCount(A0) ;-2 means add penloc <28-CEL> BNE.S @noPen ;skip penloc add <28-CEL> MOVE.L thePort(A4),A1 ;GET CURRENT GRAFPORT <24-CEL/RWB> MOVE.W PNLOC+H(A1),D0 ;add penlocation <28-CEL> BLE.S @noPen ;skip if negative <28-CEL> ADD.W D0,D1 ;add penlocation <28-CEL> @noPen ADD.W #5, D1 ;ADD one for slop <27-CEL/RWB> SWAP D1 ; <24-CEL/RWB> MOVE.L D1, widthExtra(A6) ;save off width extra value <27-CEL> MOVE.L D1, D3 ;Init to penloc + 1.0 <24-CEL/RWB> MOVE.W #-1, splineKeyRec.safeCount(A0) ; init to -1 for flagging <26> MOVE.L TEXTADDR(A6),A0 ;POINT TO CHARACTERS MOVE.L WidthTabHandle,A1 ;Get the Handle MOVE.L (A1),A1 ;WidthPtr if (hasDoubleByte) then move.l encodingTable(a6),a2 ; load encoding table pointer 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 FIXED POINT WIDTH BVS OverFlow ;CHECK FOR POSSIBLE OVERFLOW <24-CEL/RWB> MOVE.L D1, D3 ;save of safe length <24-CEL/RWB> CMP #$80,D0 ;space character? BEQ.S MORE ;skip character extra ADD.L characterExtra(A6),D1 ;add in character extra BVS OverFlow ;if overflow, set to big positive <24-CEL/RWB> MOVE.L D1, D3 ;save of safe length <24-CEL/RWB> MORE DBRA D2,NEXTCH ;LOOP FOR ALL CHARS BRA.S noOverFlow ;Branch around overflow corrections <24-CEL/RWB> OverFlow ADDQ #1, D2 ;Add back 1 to the remaining count <24-CEL/RWB> NEG D2 ;Negate for addition <24-CEL/RWB> ADD.W Count(A6), D2 ;newCount = OrigCount - remainder <24-CEL/RWB> MOVE.L expandMem,A0 ; get low memory expand pointer. <24-CEL/RWB> MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <24-CEL/RWB> MOVE.L (A0), A0 ; get pointer to splineKey globals. <24-CEL/RWB> MOVE.W D2, splineKeyRec.safeCount(A0) ; new count <24-CEL/RWB> MOVE.L D3, D1 ;restore safe length <24-CEL/RWB> noOverFlow ; <24-CEL/RWB> SUB.L widthExtra(A6), D1 ;sub widthExtra calc from width <27-CEL> MOVE.L D1,fixTxWid(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 <24-CEL/RWB> if (hasDoubleByte) then movem.l (sp)+,d4/a2-a3 ; restore double-byte registers endif UNLINK PARAMSIZE,'STDTXMEA' IF (SCRIPT_CHAR_EXTRA OR hasDoubleByte) THEN ;<1.4-4april89-CEL> <6> CEL PROC EXPORT BWMeasureText IMPORT JStdTxMeas IF SCRIPT_CHAR_EXTRA THEN IMPORT CalcCharExtra 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.) ; 05Nov86 CRC fixed register bug (grafport clobbered) 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 ;LONG IF SCRIPT_CHAR_EXTRA THEN ; <13> pke numer EQU encodingTable-4 ; <13> pke denom EQU numer-4 ; <13> pke VARSIZE EQU denom ; <13> pke ELSE ; <13> pke VARSIZE EQU encodingTable ENDIF ; <13> pke StdTxMeasTrap EQU $ED BWMeasureText LINK A6,#VARSIZE ;ALLOCATE LOCALS move.l #$00010001,numer(a6) ; set numerator to one/one move.l #$00010001,denom(a6) ; set denominator to one/one 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 ; <18> DTY MOVE.L (a1),A1 CMP.L (A1),D0 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 ;Call through the trap if system 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 ; <13> pke move.w numer+h(a6),d3 ; set up for scaling <13> pke move.w denom+h(a6),d4 ; set up for scaling <13> pke bra DoMeasureTextScaling ; go do scaling <13> pke ELSE ; <13> pke BRA NoScale ENDIF ; <13> 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 ; <13> pke MOVE.L numer(a6),(A1)+ ;supply local numer <13> pke MOVE.L denom(a6),(A1)+ ;supply local denom <13> pke ELSE ; <13> pke MOVE.L #$00010001,(A1)+ ;INSTALL INPUT NUMER = 1,1 MOVE.L #$00010001,(A1)+ ;INSTALL INPUT DENOM = 1,1 ENDIF ; <13> pke CLR.L -(SP) ;ROOM FOR FCN RESULT PEA INREC(A6) ;PUSH INPUT RECORD _SwapFont ;CALL FMSWAPFONT ; ; Determine scaled character extra, if applicable: ; clr.l characterExtra(a6) ; clear the character extra. IF SCRIPT_CHAR_EXTRA THEN move.l grafGlobals(a5),a0 ; load quickDraw globals. <23> move.l qdChExtra(a0),d0 ; load the character extra. <23> beq.s @zeroCharExtra ; yes -> skip call to scale. bsr CalcCharExtra ; scale by point size, etc. move.l d0,characterExtra(a6) ; store scaled character extra. @zeroCharExtra ENDIF ; ; Step thru characters, adding up unscaled widths and storing in charLocs: ; MOVE.L WidthTabHandle,A1 ;Get the Handle MOVE.L (A1),A1 ;WidthPtr 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,encodingTable(a6) ; keep a copy for testing @notTrueType @cacheMissing @cachePurged endif NEXTCH SWAP D4 ;GET HI WORD OF WIDTH MOVE.W D4,(A3)+ ;STORE IN CHARLOCS SWAP D4 ;RETURN WIDTH TO FIXED POINT CLR D0 ;GET READY FOR BYTE MOVE.B (A2)+,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 tst.w d3 ; more bytes left in text? ble @remapHighByte ; no -> remap the high byte sub.w #1,d3 ; decrement the text count clr.w d7 ; clear high byte of low word move.b (a2)+,d7 ; grab the low byte and increment the text pointer move.l a4,a0 ; load the high byte mapping table pointer adda #256,a0 ; offset to the low byte mapping table tst.b 0(a0,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),d4 ; add fixed point width add.l characterExtra(a6),d4 ; always add in character extra swap d4 ; get integer portion of accumulated width move.w d4,(a3)+ ; ouch, store integer width into charLocs array swap d4 ; 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),D4 ;ADD FIXED POINT WIDTH CMP #$80,D0 ;is it a space? BEQ.S MORE ;skip character extra if so ADD.L characterExtra(A6),D4 ;add in character extra MORE DBRA D3,NEXTCH ;LOOP FOR COUNT+1 CHARLOCS ; ; if font is horizontally stretched, scale all widths accordingly ; 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 DoMeasureTextScaling ; <13> 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 UNLK A6 MOVE.L (SP)+,A0 ADD #PARAMSIZE,SP JMP (A0) ENDIF CASE OFF END