static char sccsid
[] = "@(#)t6.c 2.2 (CWI) 87/07/10";
* width functions, sizes and fonts
/* fitab[f][c] is 0 if c is not on font f
/* if it's non-zero, c is in fontab[f] at position
extern struct Font
*fontbase
[NFONT
+1];
extern char *codetab
[NFONT
+1];
if (sfbits(j
) == oldbits
) {
if (widcache
[i
-32].fontpts
== (xfont
<<8) + xpts
&& !setwdf
)
k
= widcache
[i
-32].width
;
* clear width cache-- s means just space
for (i
=0; i
<NWIDCACHE
; i
++)
int savxfont
= 0, savsbold
= 0, savulfont
= 0;
* Here comes first part of bug fix
if( xfont
> nfonts
) { /* font is not mounted */
setfp(0, fontlab
[savxfont
], 0);
bdtab
[0] = bdtab
[savxfont
]; /* Save */
cstab
[0] = cstab
[savxfont
]; /* as */
ccstab
[0] = ccstab
[savxfont
]; /* well */
if (i
>= nchtab
+ 128-32) {
j
= abscw(i
+ 32 - (nchtab
+128));
if (i
== 0) { /* a blank */
k
= (fontab
[xfont
][0] * spacesz
+ 6) / 12;
/* this nonsense because .ss cmd uses 1/36 em as its units */
if ((j
= fitab
[xfont
][i
] & BYTEMASK
) == 0) { /* it's not on current font */
/* search through search list of xfont
/* to see what font it ought to be on.
/* searches S, then remaining fonts in wraparound order.
for (ii
=smnt
, jj
=0; jj
< nfonts
; jj
++, ii
=ii
% nfonts
+ 1) {
j
= fitab
[ii
][i
] & BYTEMASK
;
numtab
[CT
].val
|= kerntab
[ii
][j
];
k
= fontab
[xfont
][0]; /* leave a space-size space */
numtab
[CT
].val
|= kerntab
[xfont
][j
];
cs
= (cs
* EMPTS(x
)) / 36;
k
= ((k
&BYTEMASK
) * xpts
+ (Unitwidth
/ 2)) / Unitwidth
;
* H'm, I guess we should not put
* this width in the cache
widcache
[i
].fontpts
= (xfont
<<8) + xpts
;
/* Unitwidth is Units/Point, where
/* Units is the fundamental digitization
/* of the character set widths, and
/* Point is the number of goobies in a point
/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
/* In effect, it's the size at which the widths
/* translate directly into units.
abscw(n
) /* return index of abs char n in fontab[], etc. */
ncf
= fontbase
[xfont
]->nwfont
& BYTEMASK
;
for (i
= 0; i
< ncf
; i
++)
if (codetab
[xfont
][i
] == n
)
if ((*s
++ = getach()) == 0 || (*s
++ = getach()) == 0)
for (j
= 0; j
< nchtab
; j
++)
if (strcmp(&chname
[chtab
[j
]], temp
) == 0)
return(j
+ 128 | chbits
);
tchar
setabs() /* set absolute char from \C'...' */
* I (jaap) expand fontlab to the maximum of fonts troff can
* handle. The maximum number i, due to the two chars
* If we don't use the (named) font in one of the
* standard position, we install the name in the next
* free slot. Whenever we need info about the font, we
* read in the data at position zero, and secretly use
* the data (actually only necessary for the width
* and ligature info). The ptfont() (t10.c) routine will tell
* the device filter to put the font always at position
* zero if xfont > physfonts, so no need to change these filters.
* Yes, this is a bit kludgy.
* This gives the new specs of findft:
* find the font name i, where i also can be a number.
* Installs the font(name) i when not present
/* first look for numbers */
if( isdigit(p
[0]) && (p
[1] == 0 || isdigit(p
[1]))) {
if( p
[1] > 0 && isdigit(p
[1]))
k
= 10 * k
+ ( p
[1] - '0');
fprintf(ptid, "x xxx it's a number: %d\n", k);
if( k
> 0 && k
<= nfonts
&& fontbase
[k
]->specfont
== 0 ) {
fprintf(ptid, "x xxx it's a mounted font\n");
return(k
); /* mounted font */
if( fontlab
[k
] && k
<= MAXFONTS
) { /* translate */
fprintf(ptid, "x xxx font exists\n");
return(k
); /*number to a name */
fprintf(stderr
, "troff: no font at position %d\n", k
);
return(-1); /* wild number */
* Now we look for font names
for (k
= 1; fontlab
[k
] != i
; k
++) {
if (k
> MAXFONTS
+1) /* the +1 is for the ``font cache'' */
return(-1); /* running out of fontlab space */
if ( !fontlab
[k
] ) { /* passed all existing names */
fprintf(ptid, "x xxx installed %s on %d\n", name ,k);
/* now install the name */
* and remember accociated with
* this font, ligature info etc.
return(k
); /* was one of the existing names */
i
= inumb(&apts
); /* this is a disaster for fractional point sizes */
* in olden times, it used to ignore changes to 0 or negative.
* this is meant to allow the requested size to be anything,
* in particular so eqn can generate lots of \s-3's and still
* get back by matching \s+3's.
for (j
=k
=0 ; pstab
[j
] != 0 ; j
++)
if (abs(pstab
[j
]-i
) < abs(pstab
[k
]-i
))
for (j
= 0; i
> (k
= pstab
[j
]); j
++)
sps
= width(' ' | chbits
);
if (isdigit(i
)) { /* \sd or \sdd */
else if (i
<= 3 && isdigit(j
= cbits(ch
=getch()))) { /* \sdd */
} else if (i
== '(') { /* \s(dd */
j
= cbits(getch()) - '0';
j
= 10 * j
+ cbits(getch()) - '0';
} else if (i
== '+' || i
== '-') { /* \s+, \s- */
if (isdigit(j
)) { /* \s+d, \s-d */
} else if (j
== '(') { /* \s+(dd, \s-(dd */
j
= cbits(getch()) - '0';
j
= 10 * j
+ cbits(getch()) - '0';
tchar
setht() /* set character height from \H'...' */
n
= apts
; /* does this work? */
tchar
setslant() /* set slant from \S'...' */
if (i
== 'S' || i
== '0')
if ((j
= findft(i
)) == -1)
/* findft does the setfp if possible */
if ((j
= setfp(0, i
, 0)) == -1) /* try to put it in position 0 */
int savhp
, savapts
, savapts1
, savfont
, savfont1
, savpts
, savpts1
;
base
= numtab
[ST
].val
= numtab
[ST
].val
= wid
= numtab
[CT
].val
= 0;
while (cbits(i
= getch()) != delim
&& !nlflg
) {
if (base
< numtab
[SB
].val
)
if ((k
= base
+ emsz
) > numtab
[ST
].val
)
setn1(wid
, 0, (tchar
) 0);
/* remember to map the font */
if ((lf
= fontbase
[fbits(i
) > nfonts
? 0 : fbits(i
)]->ligfont
) == 0) {
/* font lacks ligatures */
if (cbits(j
) == 'i' && (lf
& LFI
))
else if (cbits(j
) == 'l' && (lf
& LFL
))
else if (cbits(j
) == 'f' && (lf
& LFF
)) {
if ((lf
& (LFFI
|LFFL
)) && lg
!= 2) {
if (cbits(k
)=='i' && (lf
&LFFI
))
else if (cbits(k
)=='l' && (lf
&LFFL
))
/* allow .fp for fonts >nfonts, <NFONTS? */
if ((i
= cbits(getch()) - '0') <= 0 || i
> nfonts
)
errprint("fp: bad font position %d", i
);
else if (skip() || !(j
= getrq()))
errprint("fp: no font name");
else if (skip() || !getname())
else /* 3rd argument = filename */
setfp(pos
, f
, truename
) /* mount font f at position pos[0...NFONTS] */
register struct Font
*ft
;
char longname
[NS
], shortname
[20];
if (fontlab
[pos
] == f
) /* if f already mounted at pos, */
return(pos
); /* don't remount it */
strcpy(shortname
, truename
);
shortname
[0] = f
& BYTEMASK
;
shortname
[1] = f
>> BYTE
;
sprintf(longname
, "%s/dev%s/%s.out", fontfile
, devname
, shortname
);
if ((k
= open(longname
, 0)) < 0) {
errprint("Can't open %s", longname
);
if ((ft
= fontbase
[pos
]) == 0) {
ft
= fontbase
[pos
] = (struct Font
*) malloc(EXTRAFONT
);
fontab
[pos
] = (char *)(ft
+ 1);
read(k
, (char *) ft
, 3*n
+ nchtab
+ 128 - 32 + sizeof(struct Font
));
kerntab
[pos
] = (char *) fontab
[pos
] + k
;
codetab
[pos
] = (char *) fontab
[pos
] + 2 * k
;
/* have to reset the fitab pointer because the width may be different */
fitab
[pos
] = (char *) fontab
[pos
] + 3 * k
;
ft
->nwfont
= n
; /* so can load a larger one again later */
errprint("Font %s too big for position %d", shortname
, pos
);
if ((fontlab
[pos
] = f
) == 'S')
bdtab
[pos
] = cstab
[pos
] = ccstab
[pos
] = 0;
/* if there is a directory, no place to store its name. */
/* if position isn't zero, no place to store its value. */
/* only time a FONTPOS is pushed back is if it's a */
/* standard font on position 0 (i.e., mounted implicitly. */
/* there's a bug here: if there are several input lines */
/* that look like .ft XX in short successtion, the output */
/* will all be in the last one because the "x font ..." */
/* comes out too soon. pushing back FONTPOS doesn't work */
/* with .ft commands because input is flushed after .xx cmds */
* Trying to fix this FONTPOS problem: See findft()
if ( pos
> 0 && pos
<= physfonts
)
if (!(i
= getrq()) || (i
= findft(i
)) < 0)
if (skip() || !(i
= getrq()) || (j
= findft(i
)) == -1) {
dfact
= INCH
; /* default scaling is points! */
/* if(i < VERT)i = VERT; */
sps
= width(' ' | chbits
);
/* two successive tchars.
/* the first contains HX, the second the value,
/* encoded as a vertical motion.
/* decoding is done in n2.c by pchar().
*pbp
++ = MOT
| VMOT
| NMOT
| -i
;