mirror of
https://github.com/jrk/QuickDraw.git
synced 2025-03-17 05:30:40 +00:00
741 lines
32 KiB
Plaintext
Executable File
741 lines
32 KiB
Plaintext
Executable File
.INCLUDE GRAFTYPES.TEXT
|
|
;---------------------------------------------------------
|
|
;
|
|
;
|
|
; ***** ***** * * *****
|
|
; * * * * *
|
|
; * * * * *
|
|
; * *** * *
|
|
; * * * * *
|
|
; * * * * *
|
|
; * ***** * * *
|
|
;
|
|
;
|
|
; 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
|
|
|
|
|
|
|
|
|
|
.PROC StdText,4
|
|
.REF CheckPic,DPutPicByte,PutPicData,PutPicWord,PutPicLong
|
|
.REF 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 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 JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
|
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.S FONTOK ;NO, CONTINUE
|
|
MOVEQ #3,D0 ;YES, PUSH TXFONT PARAM OPCODE
|
|
JSR DPutPicByte ;PUT OPCODE
|
|
MOVE D7,-(SP)
|
|
JSR PutPicWord ;PUT TXFONT PARAM
|
|
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 #4,D0 ;YES, PUSH TXFACE PARAM OPCODE
|
|
JSR DPutPicByte ;PUT OPCODE
|
|
MOVE.B D7,D0
|
|
JSR DPutPicByte ;PUT TXFACE PARAM
|
|
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
|
|
MOVEQ #5,D0 ;YES, PUSH TXMODE PARAM OPCODE
|
|
JSR DPutPicByte ;PUT OPCODE
|
|
MOVE D7,-(SP)
|
|
JSR PutPicWord ;PUT TXMODE PARAM
|
|
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
|
|
MOVEQ #$0D,D0 ;YES, PUSH TXSIZE PARAM OPCODE
|
|
BSR.S JDPutPicByte ;PUT OPCODE
|
|
MOVE D7,-(SP)
|
|
JSR PutPicWord ;PUT TXSIZE PARAM
|
|
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 #6,D0 ;YES, PUSH SPEXTRA PARAM OPCODE
|
|
BSR.S JDPutPicByte ;PUT OPCODE
|
|
MOVE.L D7,-(SP)
|
|
BSR.S 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
|
|
;
|
|
; CHECK NUMER, DENOM
|
|
;
|
|
SPOK 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 #$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
|
|
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
|
|
JMP DPutPicByte
|
|
JPutPicLong
|
|
JMP PutPicLong
|
|
|
|
SHORT MOVE.L D5,D0 ;YES, COPY DV.DH
|
|
AND.L #$00FF0000,D0 ;IS DV = 0 ?
|
|
BNE.S DV ;NO, CONTINUE
|
|
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
|
|
MOVEQ #$2A,D0
|
|
BSR.S JDPutPicByte ;YES, PUT DVTEXT OPCODE
|
|
BRA.S SHARE1 ;SHARE COMMON CODE
|
|
|
|
DHDV 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
|
|
JSR PutPicData ;PUT TEXT DATA
|
|
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 DrText ;DRAW THE TEXT
|
|
|
|
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 '
|
|
|
|
|
|
|
|
.PROC CallText,2
|
|
.REF STDTEXT
|
|
;---------------------------------------------------------------
|
|
;
|
|
; 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 ?
|
|
LEA STDTEXT,A0
|
|
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
|
|
|
|
|
|
|
|
.PROC TextFace,1
|
|
.DEF DrawChar,CharWidth
|
|
.REF 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
|
|
JSR 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
|
|
|
|
|
|
|
|
.PROC TextFont,1
|
|
.DEF TextSize
|
|
.DEF TextMode
|
|
.REF 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
|
|
MOVEQ #TXSIZE,D0 ;PUT PORT OFFSET IN D0
|
|
SHARE JMP PORTWORD ;INSTALL PARAM INTO THEPORT
|
|
|
|
|
|
.PROC SpaceExtra,1
|
|
.DEF DrawString,DrawText
|
|
.REF 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
|
|
|
|
|
|
.FUNC StringWidth,1
|
|
.REF TextWidth
|
|
;---------------------------------------------
|
|
;
|
|
; 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
|
|
;
|
|
.FUNC TextWidth,3
|
|
.REF StdTxMeas
|
|
;------------------------------------------
|
|
;
|
|
; 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 ?
|
|
BEQ.S STD ;YES, USE STDTXMEAS
|
|
MOVE.L D0,A0 ;NO, GET GRAFPROCS
|
|
MOVE.L TXMEASPROC(A0),A0 ;GET TXMEAS CAPTURE PROC
|
|
JSR (A0) ;CALL IT
|
|
BRA.S NOTSTD ;AND CONTINUE
|
|
STD JSR STDTXMEAS
|
|
NOTSTD 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
|
|
MOVE D2,D0 ;COPY DENOM
|
|
LSR #1,D0 ;CALC DENOM DIV 2
|
|
ADD D0,D1 ;ADD DENOM DIV 2
|
|
DIVU D2,D1 ;DIV BY DENOM
|
|
DONE MOVE D1,RESULT(A6) ;RETURN SCALED WIDTH
|
|
GOHOME UNLINK PARAMSIZE,'TEXTWIDT'
|
|
|
|
|
|
|
|
|
|
.FUNC StdTxMeas,5
|
|
;------------------------------------------
|
|
;
|
|
; 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
|
|
VARSIZE .EQU INREC
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCALS
|
|
MOVE.L A4,-(SP) ;SAVE REG
|
|
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
|
|
|
|
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
|
|
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
|
|
;
|
|
; 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 TEXTADDR(A6),A0 ;POINT TO CHARACTERS
|
|
MOVE.L WidthPtr,A1 ;POINT TO WIDTH TABLE
|
|
CLR.L D1 ;INIT WIDTH TO 0.0
|
|
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
|
|
LSL #2,D0 ;QUAD FOR TABLE OFFSET
|
|
ADD.L 0(A1,D0),D1 ;ADD FIXED POINT WIDTH
|
|
MORE DBRA D2,NEXTCH ;LOOP FOR ALL CHARS
|
|
MOVE.L D1,fixTxWid(A4) ;STASH FIXED POINT WIDTH
|
|
SWAP D1 ;GET HI WORD = INTEGER PORTION
|
|
MOVE D1,RESULT(A6) ;UPDATE FUNCTION RESULT
|
|
MOVE.L (SP)+,A4 ;RESTORE REG
|
|
UNLINK PARAMSIZE,'STDTXMEA'
|
|
|
|
|
|
|
|
|
|
.PROC MeasureText
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; 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.
|
|
;
|
|
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
|
|
VARSIZE .EQU INREC
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCALS
|
|
MOVEM.L D3-D4/A2,-(SP) ;SAVE REGS
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
|
;
|
|
; 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
|
|
MOVE.L #$00010001,(A1)+ ;INSTALL INPUT NUMER = 1,1
|
|
MOVE.L #$00010001,(A1)+ ;INSTALL INPUT DENOM = 1,1
|
|
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
|
PEA INREC(A6) ;PUSH INPUT RECORD
|
|
_SwapFont ;CALL FMSWAPFONT
|
|
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
|
|
|
|
;
|
|
; Step thru characters, adding up unscaled widths and storing in charLocs:
|
|
;
|
|
MOVE.L TEXTADDR(A6),A0 ;POINT TO CHARACTERS
|
|
MOVE.L WidthPtr,A1 ;POINT TO WIDTH TABLE
|
|
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
|
|
LSL #2,D0 ;QUAD FOR TABLE OFFSET
|
|
ADD.L 0(A1,D0),D1 ;ADD FIXED POINT WIDTH
|
|
MORE DBRA D2,NEXTCH ;LOOP FOR COUNT+1 CHARLOCS
|
|
|
|
;
|
|
; if font is horizontally stretched, scale all widths accordingly
|
|
;
|
|
CMP D3,D4 ;IS NUMER.H = DENOM.H ?
|
|
BEQ.S NOSCALE ;YES, SKIP SCALING
|
|
MOVE D4,D1 ;COPY DENOM
|
|
LSR #1,D1 ;CALC DENOM DIV 2
|
|
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
|
|
ADD D1,D0 ;ADD DENOM DIV 2
|
|
DIVU D4,D0 ;DIV BY DENOM
|
|
MOVE D0,(A2)+ ;UPDATE CHARLOC
|
|
DBRA D2,NEXTCH2 ;LOOP FOR COUNT+1 CHARLOCS
|
|
NOSCALE
|
|
|
|
MOVEM.L(SP)+,D3-D4/A2 ;RESTORE REGS
|
|
UNLINK PARAMSIZE,'MEASURET'
|
|
|
|
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; 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;
|
|
;
|
|
;
|
|
;
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
|
.PROC GetFontInfo,1
|
|
.REF StdTxMeas
|
|
;------------------------------------------
|
|
;
|
|
; 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 STDTXMEAS,A0
|
|
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
|
|
SUB #1,D1 ;calc denom-1
|
|
EXT.L D1 ;extend to long
|
|
ADD.L D1,D0 ;add denom-1 to round up
|
|
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
|
|
SUB #1,D1 ;calc denom-1
|
|
EXT.L D1 ;extend to long
|
|
ADD.L D1,D0 ;add denom-1 to round up
|
|
DIVU DENOM+V(A6),D0 ;divide by denom
|
|
MOVE D0,(A1)+ ;UPDATE IT
|
|
RTS
|
|
|
|
|
|
.END
|