static void readttf_kern(Font *fnt) { register kern *nk; register ttfinfo *ti; TT_Kern_0_Pair* pairs0; TT_Error error; unsigned int i, j; if ((error = TT_Get_Kerning_Directory(face, &directory))) oops("Cannot get kerning directory (error code = 0x%x).", error); if (directory.nTables == 0) return; for (i = 0; i < directory.nTables; i++) { if ((error = TT_Load_Kerning_Table(face, i))) oops("Cannot load kerning table (error code = 0x%x).", error); switch (directory.tables[i].format) { case 0: pairs0 = directory.tables[i].t.kern0.pairs; for (j = 0; j < directory.tables[i].t.kern0.nPairs; j++, pairs0++) { ti = findglyph(pairs0->left, fnt->charlist); if (ti == NULL) warning("kern char not found"); else { nk = newkern(); nk->succ = findglyph(pairs0->right, fnt->charlist)->adobename; nk->delta = transform(pairs0->value * 1000 / fnt->units_per_em, 0, fnt->efactor, fnt->slant); nk->next = ti->kerns; ti->kerns = nk; } } return; /* we stop after the first format 0 kerning table */ default: break; } } return; }
/* output glyph. Use first rune to look up character (hash) * then use stoken UTF string to find correct glyph in linked * list of glyphs in bucket. */ void glyphout(Rune rune, char *stoken, BOOLEAN specialflag) { struct charent **cp; struct troffont *tfp; struct psfent *psfp; int i, t, mi, wid; int fontid; /* this is the troff font table index, not the mounted font table index */ Rune r; mi = 0; settrfont(); /* check current font for the character, special or not */ fontid = curtrofffontid; if (debug) fprint(2, "\tlooking through current font: trying %s\n", troffontab[fontid].trfontid); cp = findglyph(fontid, rune, stoken); if (*cp != 0) goto foundit; if (specialflag) { if (expecthmot) hmot(0); /* check special fonts for the special character */ /* cycle through the (troff) mounted fonts starting at the next font */ for (mi=0; mi<fontmnt; mi++) { if (troffontab[fontid].trfontid==0) error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n", fontid, troffontab[fontid].trfontid); if (fontmtab[mi]==0) { if (debug) fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n", mi, fontmtab[mi], fontmnt); continue; } if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0) break; } if (mi==fontmnt) error(FATAL, "current troff font is not mounted, botch!\n"); for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) { if (fontmtab[i]==0) { if (debug) fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n", i, fontmtab[i], fontmnt); continue; } fontid = findtfn(fontmtab[i], TRUE); if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid); if (troffontab[fontid].special) { cp = findglyph(fontid, rune, stoken); if (*cp != 0) goto foundit; } } /* check font 1 (if current font is not font 1) for the special character */ if (mi != 1) { fontid = findtfn(fontmtab[1], TRUE);; if (debug) fprint(2, " looking through font at position 1: trying %s\n", troffontab[fontid].trfontid); cp = findglyph(fontid, rune, stoken); if (*cp != 0) goto foundit; } } if (*cp == 0) { error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken, troffontab[curtrofffontid].trfontid); expecthmot = 0; } /* use the peter face in lieu of the character that we couldn't find */ rune = 'p'; stoken = "pw"; for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) { if (fontmtab[i]==0) { if (debug) fprint(2, "fontmtab[%d]=%#p\n", i, fontmtab[i]); continue; } fontid = findtfn(fontmtab[i], TRUE); if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid); if (troffontab[fontid].special) { cp = findglyph(fontid, rune, stoken); if (*cp != 0) goto foundit; } } if (*cp == 0) { error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken, troffontab[curtrofffontid].trfontid); expecthmot = 0; return; } foundit: t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff); if (debug) fprint(2, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n", rune, rune, (*cp)->postfontid, (*cp)->postcharid, (*cp)->troffcharwidth); tfp = &troffontab[fontid]; psfp = nil; for (i=0; i<tfp->psfmapsize; i++) { psfp = &(tfp->psfmap[i]); if(t>=psfp->start && t<=psfp->end) break; } if (i >= tfp->psfmapsize) error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune); setpsfont(psfp->psftid, fontsize); if (t == 0x0001) { /* character is in charlib */ endstring(); if (pageon()) { Bprint(Bstdout, "%d %d m ", hpos, vpos); /* if char is unicode character rather than name, clean up for postscript */ wid = chartorune(&r, (*cp)->name); if(' '<r && r<0x7F) Bprint(Bstdout, "%d build_%s\n", (*cp)->troffcharwidth, (*cp)->name); else{ if((*cp)->name[wid] != 0) error(FATAL, "character <%s> badly named\n", (*cp)->name); Bprint(Bstdout, "%d build_X%.4x\n", (*cp)->troffcharwidth, r); } /* * stash charent pointer in a list so that we can * print these character definitions in the prologue. */ for (i=0; i<build_char_cnt; i++) if (*cp == build_char_list[i]) break; if (i == build_char_cnt) { build_char_list = galloc(build_char_list, sizeof(struct charent *)*++build_char_cnt, "build_char_list"); build_char_list[build_char_cnt-1] = *cp; } } expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth; } else if (isinstring() || rune != ' ') { startstring(); if (pageon()) if (rune == ' ') Bprint(Bstdout, " "); else Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str); expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth; } }