/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * 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){ 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) { int j; 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()); j = i; /* make compiler happy */ 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; setsbits(c, n); setfbits(c, pts); /* sneaky, CHARHT font bits are size bits */ return(c);} Tchar t_setslant(void) /* set slant from \S'...' */{ int n; Tchar c; getch(); n = 0; n = inumb(&n); getch(); if (nonumb) n = 0; c = SLANT; c |= ZBIT; setsfbits(c, n+180); return(c);} void caseft(void){ if (!TROFF) { n_caseft(); return; } skip(); setfont(1);} void t_setfont(int a){ int i, j; if (a) i = getrq(); else i = getsn(); if (!i || i == 'P') { j = font1; goto s0; } if (/* i == 'S' || */ i == '0') /* an experiment -- why can't we change to it? */ return;Lines 1–500 of 892. Load more
/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * 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) { 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) { int j; 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()); j = i; /* make compiler happy */ 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; setsbits(c, n); setfbits(c, pts); /* sneaky, CHARHT font bits are size bits */ return(c); } Tchar t_setslant(void) /* set slant from \S'...' */ { int n; Tchar c; getch(); n = 0; n = inumb(&n); getch(); if (nonumb) n = 0; c = SLANT; c |= ZBIT; setsfbits(c, n+180); return(c); } void caseft(void) { if (!TROFF) { n_caseft(); return; } skip(); setfont(1); } void t_setfont(int a) { int i, j; if (a) i = getrq(); else i = getsn(); if (!i || i == 'P') { j = font1; goto s0; } if (/* i == 'S' || */ i == '0') /* an experiment -- why can't we change to it? */ return;