Revamp of the Halibut error handling mechanism.
[sgt/halibut] / in_afm.c
index f771af7..f89a2aa 100644 (file)
--- a/in_afm.c
+++ b/in_afm.c
@@ -13,7 +13,7 @@ char *afm_read_line(input *in) {
        in->pos.line++;
        c = getc(in->currfp);
        if (c == EOF) {
-           error(err_afmeof, &in->pos);
+           err_afmeof(&in->pos);
            return NULL;
        }
        line = snewn(len, char);
@@ -44,33 +44,36 @@ static int afm_require_key(char *line, char const *expected, input *in) {
 
     if (strcmp(key, expected) == 0)
        return TRUE;
-    error(err_afmkey, &in->pos, expected);
+    err_afmkey(&in->pos, expected);
     return FALSE;
 }
 
 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->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))
        goto giveup;
     if (!(val = strtok(NULL, " \t"))) {
-       error(err_afmval, in->pos, "StartFontMetrics", 1);
+       err_afmval(&in->pos, "StartFontMetrics", 1);
        goto giveup;
     }
     if (atof(val) >= 5.0) {
-       error(err_afmvers, &in->pos);
+       err_afmvers(&in->pos);
        goto giveup;
     }
     sfree(line);
@@ -86,7 +89,7 @@ void read_afm_file(input *in) {
            return;
        } else if (strcmp(key, "FontName") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->name = dupstr(val);
@@ -94,73 +97,71 @@ void read_afm_file(input *in) {
            int i;
            for (i = 0; i < 3; i++) {
                if (!(val = strtok(NULL, " \t"))) {
-                   error(err_afmval, &in->pos, key, 4);
+                   err_afmval(&in->pos, key, 4);
                    goto giveup;
                }
                fi->fontbbox[i] = atof(val);
            }
        } else if (strcmp(key, "CapHeight") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->capheight = atof(val);
        } else if (strcmp(key, "XHeight") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->xheight = atof(val);
        } else if (strcmp(key, "Ascender") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->ascent = atof(val);
        } else if (strcmp(key, "Descender") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->descent = atof(val);
        } else if (strcmp(key, "CapHeight") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->capheight = atof(val);
        } else if (strcmp(key, "StdHW") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->stemh = atof(val);
        } else if (strcmp(key, "StdVW") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            fi->stemv = atof(val);
        } else if (strcmp(key, "ItalicAngle") == 0) {
            if (!(val = strtok(NULL, " \t"))) {
-               error(err_afmval, &in->pos, key, 1);
+               err_afmval(&in->pos, key, 1);
                goto giveup;
            }
            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);
+               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;
@@ -169,17 +170,39 @@ void read_afm_file(input *in) {
                    if (strcmp(key, "WX") == 0 || strcmp(key, "W0X") == 0) {
                        if (!(val = strtok(NULL, " \t")) ||
                            !strcmp(val, ";")) {
-                           error(err_afmval, &in->pos, key, 1);
+                           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);
+                           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, ";")) {
+                           err_afmval(&in->pos, key, 1);
+                           goto giveup;
+                       }
+                       succ = glyph_intern(val);
+                       if (!(val = strtok(NULL, " \t")) ||
+                           !strcmp(val, ";")) {
+                           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");
@@ -187,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);
+               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)
@@ -226,11 +248,11 @@ void read_afm_file(input *in) {
                    nr = strtok(NULL, " \t");
                    val = strtok(NULL, " \t");
                    if (!val) {
-                       error(err_afmval, &in->pos, key, 3);
+                       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;