This repository has been archived by the owner on Nov 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathText.a
740 lines (655 loc) · 32.1 KB
/
Text.a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
.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