X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/44407fea05657f91da34fd83428b67e7100ab62b..944c4044572da20ed1fb9bc01085221856b53c1f:/in_afm.c diff --git a/in_afm.c b/in_afm.c index 6b7a9f3..559bb5d 100644 --- a/in_afm.c +++ b/in_afm.c @@ -51,17 +51,19 @@ static int afm_require_key(char *line, char const *expected, input *in) { void read_afm_file(input *in) { char *line, *key, *val; font_info *fi; + size_t i; fi = snew(font_info); fi->name = NULL; - fi->nglyphs = 0; - fi->glyphs = NULL; - fi->widths = NULL; - fi->fp = NULL; + fi->widths = newtree234(width_cmp); + fi->fontfile = NULL; fi->kerns = newtree234(kern_cmp); + fi->ligs = newtree234(lig_cmp); fi->fontbbox[0] = fi->fontbbox[1] = fi->fontbbox[2] = fi->fontbbox[3] = 0; fi->capheight = fi->xheight = fi->ascent = fi->descent = 0; fi->stemh = fi->stemv = fi->italicangle = 0; + for (i = 0; i < lenof(fi->bmp); i++) + fi->bmp[i] = 0xFFFF; in->pos.line = 0; line = afm_read_line(in); if (!line || !afm_require_key(line, "StartFontMetrics", in)) @@ -149,19 +151,17 @@ void read_afm_file(input *in) { } fi->italicangle = atof(val); } else if (strcmp(key, "StartCharMetrics") == 0) { - char const **glyphs; - int *widths; - int i; + int nglyphs, i; if (!(val = strtok(NULL, " \t"))) { error(err_afmval, &in->pos, key, 1); goto giveup; } - fi->nglyphs = atoi(val); + nglyphs = atoi(val); sfree(line); - glyphs = snewn(fi->nglyphs, char const *); - widths = snewn(fi->nglyphs, int); - for (i = 0; i < fi->nglyphs; i++) { - glyphs[i] = NULL; + for (i = 0; i < nglyphs; i++) { + int width = 0; + glyph g = NOGLYPH; + line = afm_read_line(in); if (line == NULL) goto giveup; @@ -173,14 +173,36 @@ void read_afm_file(input *in) { error(err_afmval, &in->pos, key, 1); goto giveup; } - widths[i] = atoi(val); + width = atoi(val); } else if (strcmp(key, "N") == 0) { if (!(val = strtok(NULL, " \t")) || !strcmp(val, ";")) { error(err_afmval, &in->pos, key, 1); goto giveup; } - glyphs[i] = dupstr(val); + g = glyph_intern(val); + } else if (strcmp(key, "L") == 0) { + glyph succ, lig; + if (!(val = strtok(NULL, " \t")) || + !strcmp(val, ";")) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + succ = glyph_intern(val); + if (!(val = strtok(NULL, " \t")) || + !strcmp(val, ";")) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + lig = glyph_intern(val); + if (g != NOGLYPH && succ != NOGLYPH && + lig != NOGLYPH) { + ligature *l = snew(ligature); + l->left = g; + l->right = succ; + l->lig = lig; + add234(fi->ligs, l); + } } do { key = strtok(NULL, " \t"); @@ -188,32 +210,31 @@ void read_afm_file(input *in) { key = strtok(NULL, " \t"); } sfree(line); + if (width != 0 && g != NOGLYPH) { + wchar_t ucs; + glyph_width *w = snew(glyph_width); + w->glyph = g; + w->width = width; + add234(fi->widths, w); + ucs = ps_glyph_to_unicode(g); + if (ucs < 0xFFFF) + fi->bmp[ucs] = g; + } } line = afm_read_line(in); if (!line || !afm_require_key(line, "EndCharMetrics", in)) goto giveup; sfree(line); - fi->glyphs = glyphs; - fi->widths = widths; - for (i = 0; i < fi->nglyphs; i++) { - wchar_t ucs; - ucs = ps_glyph_to_unicode(fi->glyphs[i]); - if (ucs < 0xFFFF) - fi->bmp[ucs] = i; - } - font_index_glyphs(fi); } else if (strcmp(key, "StartKernPairs") == 0 || strcmp(key, "StartKernPairs0") == 0) { int nkerns, i; - kern_pair *kerns; if (!(val = strtok(NULL, " \t"))) { error(err_afmval, &in->pos, key, 1); goto giveup; } nkerns = atoi(val); sfree(line); - kerns = snewn(nkerns, kern_pair); for (i = 0; i < nkerns; i++) { line = afm_read_line(in); if (line == NULL) @@ -230,8 +251,8 @@ void read_afm_file(input *in) { error(err_afmval, &in->pos, key, 3); goto giveup; } - l = find_glyph(fi, nl); - r = find_glyph(fi, nr); + l = glyph_intern(nl); + r = glyph_intern(nr); if (l == -1 || r == -1) continue; kp = snew(kern_pair); kp->left = l;