📄 t6.c
字号:
/* * t6.c * * width functions, sizes and fonts */#include "tdef.h"#include "fns.h"#include "ext.h"int fontlab[MAXFONTS+1];int cstab[MAXFONTS+1];int ccstab[MAXFONTS+1];int bdtab[MAXFONTS+1];int sbold = 0;t_width(Tchar j){ int i, k; if (iszbit(j)) return 0; if (ismot(j)) { if (isvmot(j)) return(0); k = absmot(j); if (isnmot(j)) k = -k; return(k); } i = cbits(j); if (i < ' ') { if (i == '\b') return(-widthp); if (i == PRESC) i = eschar; else if (i == HX) return(0); } if (i == ohc) return(0); i = trtab[i]; if (i < ' ') return(0); if (sfbits(j) == oldbits) { xfont = pfont; xpts = ppts; } else xbits(j, 0); if (i < nchnames + ALPHABET && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf) k = widcache[i].width; else { k = getcw(i); if (bd) k += (bd - 1) * HOR; if (cs) k = cs; } widthp = k; return(k);}/* * clear width cache-- s means just space */void zapwcache(int s){ int i; if (s) { widcache[' '].fontpts = 0; return; } for (i=0; i<NWIDCACHE; i++) widcache[i].fontpts = 0;}onfont(int n, int f) /* is char n on font f? */{ int i; Font *fp = &fonts[f]; Chwid *cp, *ep; char *np; if (n < ALPHABET) { if (fp->wp[n].num == n) /* ascii at front */ return n; else return -1; } cp = &fp->wp[ALPHABET]; ep = &fp->wp[fp->nchars]; for ( ; cp < ep; cp++) /* search others */ if (cp->num == n) return cp - &fp->wp[0]; /* maybe it was a \N... */ np = chname(n); if (*np == Number) { i = atoi(np+1); /* sscanf(np+1, "%d", &i); */ cp = &fp->wp[0]; ep = &fp->wp[fp->nchars]; for ( ; cp < ep; cp++) { /* search others */ if (cp->code == i) return cp - &fp->wp[0]; } return -2; /* a \N that doesn't have an entry */ } return -1; /* vanilla not found */}getcw(int i){ int k, n, x; Font *fp; int nocache = 0; if (i < ' ') return 0; bd = 0; fp = &fonts[xfont]; if (i == ' ') { /* a blank */ k = (fp->spacewidth * spacesz + 6) / 12; /* this nonsense because .ss cmd uses 1/36 em as its units */ /* and default is 12 */ } else if ((n = onfont(i, xfont)) >= 0) { /* on this font at n */ k = fp->wp[n].wid; if (setwdf) numtabp[CT].val |= fp->wp[n].kern; } else if (n == -2) { /* \N with default width */ k = fp->defaultwidth; } else { /* not on current font */ nocache = 1; k = fp->defaultwidth; /* default-size space */ if (smnt) { int ii, jj; for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) { if ((n = onfont(i, ii)) >= 0) { k = fonts[ii].wp[n].wid; if (xfont == sbold) bd = bdtab[ii]; if (setwdf) numtabp[CT].val |= fonts[ii].wp[n].kern; break; } } } } if (!bd) bd = bdtab[xfont]; if (cs = cstab[xfont]) { nocache = 1; if (ccs = ccstab[xfont]) x = ccs; else x = xpts; cs = (cs * EMPTS(x)) / 36; } /* was (k & BYTEMASK); since .wid is unsigned, should never happen */ if (k < 0) ERROR "can't happen: negative width %d in getcw %d\n", k, i WARN; k = (k * xpts + (Unitwidth / 2)) / Unitwidth; if (nocache|bd) widcache[i].fontpts = 0; else { widcache[i].fontpts = (xfont<<8) + xpts; widcache[i].width = k; } return(k); /* 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. */}void xbits(Tchar i, int bitf){ int k; if(TROFF) { xfont = fbits(i); k = sbits(i); if(k) { xpts = pstab[k-1]; oldbits = sfbits(i); pfont = xfont; ppts = xpts; return; } switch(bitf) { case 0: xfont = font; xpts = pts; break; case 1: xfont = pfont; xpts = ppts; break; case 2: xfont = mfont; xpts = mpts; } }}/* these next two functions ought to be the same in troff and nroff, *//* but the data structures they search are different. *//* silly historical problem. */Tchar t_setch(int c){ int j; char temp[50]; char *s; s = temp; if (c == '(') { /* \(xx */ if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0) return(0); } else { /* \C'...' */ c = getach(); while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1) s++; } *s = '\0';#ifdef UNICODE return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */#else if (NROFF) { j = chadd(temp, Troffchar, Lookup); if ( j == -1) return 0; else return j | chbits; } else return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */ #endif /*UNICODE*/}Tchar t_setabs(void) /* set absolute char from \N'...' */{ int n; char temp[10]; getch(); /* delim */ n = 0; n = inumb(&n); getch(); /* delim */ if (nonumb) return 0; sprintf(temp, "%d", n); /* convert into "#n" */ n = chadd(temp, Number, Install); return n | chbits;}/* * fontlab[] is a cache that contains font information * for each font. * fontlab[] contains the 1- or 2-character name of the * font current associated with that font. * fonts 1..nfonts correspond to the mounted fonts; * the last of these are the special fonts. * If we don't use the (named) font in one of the * standard positions, we install the name in the next * free slot of fontlab[] and font[]. * Whenever we need info about the font, we * read in the data into the next free slot with getfont. * The ptfont() (t10.c) routine will tell * the device filter to put the font always at position * zero if xfont > nfonts, 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 * returns -1 on error */t_findft(int i){ int k; Uchar *p; p = unpair(i); if (isdigit(p[0])) { /* first look for numbers */ k = p[0] - '0'; if (p[1] > 0 && isdigit(p[1])) k = 10 * k + p[1] - '0'; if (k > 0 && k <= nfonts && k < smnt) return(k); /* mounted font: .ft 3 */ if (fontlab[k] && k <= MAXFONTS) { /* translate */ return(k); /*number to a name */ } else { 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) return(-1); /* running out of fontlab space */ if (fontlab[k] == 0) { /* passed all existing names */ if (setfp(k, i, (char *) 0, 1) == -1) return(-1); else { fontlab[k] = i; /* install the name */ return(k); } } } return(k); /* was one of the existing names */}void caseps(void){ int i; if (TROFF) { if(skip()) i = apts1; else { noscale++; i = inumb(&apts); /* this is a disaster for fractional point sizes */ noscale = 0; if(nonumb) i = apts1; } casps1(i); }}void casps1(int i){/* * 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. if (i <= 0) return;*/ apts1 = apts; apts = i; pts1 = pts; pts = findps(i); mchbits();}findps(int i){ int j, k; for (j=k=0 ; pstab[j] != 0 ; j++) if (abs(pstab[j]-i) < abs(pstab[k]-i)) k = j; return(pstab[k]);}void t_mchbits(void){ int i, j, k; i = pts; for (j = 0; i > (k = pstab[j]); j++) if (!k) { j--; break; } chbits = 0; setsbits(chbits, ++j); setfbits(chbits, font); sps = width(' ' | chbits); zapwcache(1);}void t_setps(void){ int i, j; i = cbits(getch()); if (isdigit(i)) { /* \sd or \sdd */ i -= '0'; if (i == 0) /* \s0 */ j = apts1; else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) { /* \sdd */ j = 10 * i + j - '0'; ch = 0; } else /* \sd */ j = i; } else if (i == '(') { /* \s(dd */ j = cbits(getch()) - '0'; j = 10 * j + cbits(getch()) - '0'; if (j == 0) /* \s(00 */ j = apts1; } else if (i == '+' || i == '-') { /* \s+, \s- */ j = cbits(getch()); if (isdigit(j)) { /* \s+d, \s-d */ j -= '0'; } else if (j == '(') { /* \s+(dd, \s-(dd */ j = cbits(getch()) - '0'; j = 10 * j + cbits(getch()) - '0'; } if (i == '-') j = -j; j += apts; } casps1(j);}Tchar t_setht(void) /* set character height from \H'...' */{ int n; Tchar c; getch(); n = inumb(&apts); getch(); if (n == 0 || nonumb) n = apts; /* does this work? */ c = CHARHT; c |= ZBIT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -