diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc')
-rw-r--r-- | Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc | 586 |
1 files changed, 0 insertions, 586 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc deleted file mode 100644 index 2d850c6ef8e..00000000000 --- a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc +++ /dev/null @@ -1,586 +0,0 @@ -// -*- related-file-name: "../include/efont/afm.hh" -*- - -/* afm.{cc,hh} -- Adobe Font Metrics files - * - * Copyright (c) 1998-2019 Eddie Kohler - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <efont/afm.hh> -#include <efont/afmparse.hh> -#include <efont/t1cs.hh> /* for UNKDOUBLE */ -#include <lcdf/error.hh> -#include <ctype.h> -#include <assert.h> -namespace Efont { - -AfmReader::AfmReader(AfmParser &parser, Metrics *afm, AfmMetricsXt *afm_xt, - ErrorHandler *errh) - : _afm(afm), _afm_xt(afm_xt), _l(parser), - _composite_warned(false), _metrics_sets_warned(false), _y_width_warned(0) -{ - _errh = errh ? errh : ErrorHandler::silent_handler(); -} - -Metrics * -AfmReader::read(Slurper &slurp, ErrorHandler *errh) -{ - AfmParser p(slurp); - if (!p.ok()) - return 0; - - Metrics *afm = new Metrics; - AfmMetricsXt *afm_xt = new AfmMetricsXt; - afm->add_xt(afm_xt); - AfmReader reader(p, afm, afm_xt, errh); - - if (!reader.read()) { - delete afm; - return 0; - } else - return afm; -} - -Metrics * -AfmReader::read(const Filename &fn, ErrorHandler *errh) -{ - Slurper slurpy(fn); - return read(slurpy, errh); -} - - -void -AfmReader::lwarning(const char *format, ...) const -{ - va_list val; - va_start(val, format); - _errh->xmessage(_l.landmark(), ErrorHandler::e_warning, format, val); - va_end(val); -} - -void -AfmReader::lerror(const char *format, ...) const -{ - va_list val; - va_start(val, format); - _errh->xmessage(_l.landmark(), ErrorHandler::e_error, format, val); - va_end(val); -} - -GlyphIndex -AfmReader::find_err(PermString name, const char *) const -{ - GlyphIndex gi = _afm->find(name); - if (gi < 0) - lerror("character `%s' doesn't exist", name.c_str()); - return gi; -} - -void -AfmReader::composite_warning() const -{ - if (!_composite_warned) - lwarning("composite fonts not supported"); - _composite_warned = 1; -} - -void -AfmReader::metrics_sets_warning() const -{ - if (!_metrics_sets_warned) - lwarning("only metrics set 0 is supported"); - _metrics_sets_warned = 1; -} - -void -AfmReader::y_width_warning() const -{ - if (_y_width_warned < 40) { - lwarning("character has a nonzero Y width"); - _y_width_warned++; - if (_y_width_warned == 40) - lwarning("I won't warn you again."); - } -} - -void -AfmReader::no_match_warning(const char *context) const -{ - // keyword() will fail (and a warning won't get printed) only if the string - // is all whitespace, which the spec allows - PermString keyword = _l.keyword(); - if (!keyword) return; - if (_l.key_matched()) { - lwarning(context ? "bad `%s' command in %s:" - : "bad `%s' command:", keyword.c_str(), context); - lwarning("field %d %s", _l.fail_field(), _l.message().c_str()); - } else - lwarning(context ? "unknown command `%s' in %s" - : "unknown command `%s'", keyword.c_str(), context); - _l.clear_message(); -} - - -bool -AfmReader::read() -{ - AfmParser &l = _l; - assert(_afm && _afm_xt); - - // First, read all opening comments into an array so we can print them out - // later. - PermString comment; - while (l.next_line()) { - if (l.isall("Comment %+s", &comment)) - _afm_xt->opening_comments.push_back(comment); - else if (l.isall("StartFontMetrics %g", (double *)0)) - ; - else { - l.save_line(); - break; - } - } - - _afm->set_scale(1000); - unsigned invalid_lines = 0; - PermString s; - bool isbasefont; - int metrics_sets; - int direction; - - while (l.next_line()) - switch (l.first()) { - - case 'A': - if (l.isall("Ascender %g", &fd( fdAscender ))) - break; - goto invalid; - - case 'C': - if (l.isall("Characters %d", (int *)0)) - break; - if (l.isall("CapHeight %g", &fd( fdCapHeight ))) - break; - if (l.isall("CharacterSet %+s", (PermString *) 0)) - break; - if (l.isall("CharWidth %g %g", (double *)0, (double *)0)) - break; - if (l.isall("Comment %+s", (PermString *) 0)) - break; - goto invalid; - - case 'D': - if (l.isall("Descender %g", &fd( fdDescender ))) - break; - goto invalid; - - case 'E': - if (l.isall("EncodingScheme %+s", &_afm_xt->encoding_scheme)) - break; - if (l.isall("EndDirection")) - break; - if (l.isall("EndFontMetrics")) - goto done; - if (l.isall("EscChar %d", (int *)0)) { - composite_warning(); - break; - } - goto invalid; - - case 'F': - if (l.isall("FontName %+s", &s)) { - _afm->set_font_name(s); - break; - } - if (l.isall("FullName %+s", &s)) { - _afm->set_full_name(s); - break; - } - if (l.isall("FamilyName %+s", &s)) { - _afm->set_family(s); - break; - } - if (l.isall("FontBBox %g %g %g %g", - &fd( fdFontBBllx ), &fd( fdFontBBlly ), - &fd( fdFontBBurx ), &fd( fdFontBBury ))) - break; - goto invalid; - - case 'I': - if (l.isall("ItalicAngle %g", &fd( fdItalicAngle ))) - break; - if (l.isall("IsBaseFont %b", &isbasefont)) { - if (isbasefont == 0) - composite_warning(); - break; - } - if (l.isall("IsFixedV %b", (bool *)0)) { - metrics_sets_warning(); - break; - } - if (l.isall("IsFixedPitch %b", (bool *)0)) - break; - goto invalid; - - case 'M': - if (l.isall("MappingScheme %d", (int *)0)) { - composite_warning(); - break; - } - if (l.isall("MetricsSets %d", &metrics_sets)) { - if (metrics_sets != 0) - metrics_sets_warning(); - break; - } - goto invalid; - - case 'N': - if (l.isall("Notice %+s", &_afm_xt->notice)) - break; - goto invalid; - - case 'S': - if (l.isall("StartDirection %d", &direction)) { - if (direction != 0) - metrics_sets_warning(); - break; - } - if (l.isall("StartCharMetrics %d", (int *)0)) { - read_char_metrics(); - break; - } - if (l.isall("StartKernData")) { - read_kerns(); - break; - } - if (l.isall("StartComposites %d", (int *)0)) { - read_composites(); - break; - } - if (l.isall("StdHW %g", &fd( fdStdHW ))) - break; - if (l.isall("StdVW %g", &fd( fdStdVW ))) - break; - if (l.isall("StartFontMetrics %g", (double *)0)) - break; - goto invalid; - - case 'U': - if (l.isall("UnderlinePosition %g", &fd( fdUnderlinePosition ))) - break; - if (l.isall("UnderlineThickness %g", &fd( fdUnderlineThickness ))) - break; - goto invalid; - - case 'V': - if (l.isall("Version %+s", &s)) { - _afm->set_version(s); - break; - } - if (l.isall("VVector %g %g", (double *)0, (double *)0)) { - metrics_sets_warning(); - break; - } - goto invalid; - - case 'W': - if (l.isall("Weight %+s", &s)) { - _afm->set_weight(s); - break; - } - goto invalid; - - case 'X': - if (l.isall("XHeight %g", &fd( fdXHeight ))) - break; - goto invalid; - - default: - invalid: - invalid_lines++; - no_match_warning(); - - } - - done: - if (invalid_lines >= l.lineno() - 10) - return false; - else - return true; -} - - -static Vector<PermString> ligature_left; -static Vector<PermString> ligature_right; -static Vector<PermString> ligature_result; - -void -AfmReader::read_char_metric_data() const -{ - int c = -1; - double wx = UNKDOUBLE; - double bllx = UNKDOUBLE, blly = 0, burx = 0, bury = 0; - PermString n; - PermString ligright, ligresult; - - AfmParser &l = _l; - - l.is("C %d ; WX %g ; N %/s ; B %g %g %g %g ;", - &c, &wx, &n, &bllx, &blly, &burx, &bury); - - while (l.left()) { - - switch (l.first()) { - - case 'B': - if (l.is("B %g %g %g %g", &bllx, &blly, &burx, &bury)) - break; - goto invalid; - - case 'C': - if (l.is("C %d", &c)) - break; - if (l.is("CH <%x>", &c)) - break; - goto invalid; - - case 'E': - if (l.isall("EndCharMetrics")) - return; - goto invalid; - - case 'L': - if (l.is("L %/s %/s", &ligright, &ligresult)) { - if (!n) - lerror("ligature given, but character has no name"); - else { - ligature_left.push_back(n); - ligature_right.push_back(ligright); - ligature_result.push_back(ligresult); - } - break; - } - goto invalid; - - case 'N': - if (l.is("N %/s", &n)) - break; - goto invalid; - - case 'W': - if (l.is("WX %g", &wx) || - l.is("W0X %g", &wx)) - break; - if (l.is("W %g %g", &wx, (double *)0) || - l.is("W0 %g %g", &wx, (double *)0) || - l.is("W0Y %g", (double *)0)) { - y_width_warning(); - break; - } - if (l.is("W1X %g", (double *)0) || - l.is("W1Y %g", (double *)0) || - l.is("W1 %g %g", (double *)0, (double *)0)) { - metrics_sets_warning(); - break; - } - goto invalid; - - default: - invalid: - // always warn about unknown directives here! - no_match_warning("character metrics"); - l.skip_until(';'); - break; - - } - - l.is(";"); // get rid of any possible semicolon - } - - // create the character - if (!n) - lwarning("character without a name ignored"); - else { - if (_afm->find(n) != -1) - lwarning("character %s defined twice", n.c_str()); - - GlyphIndex gi = _afm->add_glyph(n); - - _afm->wd(gi) = wx; - _afm->lf(gi) = bllx; - _afm->rt(gi) = burx; - _afm->tp(gi) = bury; - _afm->bt(gi) = blly; - - if (c != -1) - _afm->set_code(gi, c); - } -} - - -void -AfmReader::read_char_metrics() const -{ - assert(!ligature_left.size()); - - while (_l.next_line()) - // Grok the whole line. Are we on a character metric data line? - switch (_l.first()) { - - case 'C': - if (isspace(_l[1]) || (_l[1] == 'H' && isspace(_l[2]))) { - read_char_metric_data(); - break; - } - if (_l.is("Comment")) - break; - goto invalid; - - case 'E': - if (_l.isall("EndCharMetrics")) - goto end_char_metrics; - goto invalid; - - default: - invalid: - no_match_warning(); - - } - - end_char_metrics: - - for (int i = 0; i < ligature_left.size(); i++) { - GlyphIndex leftgi = find_err(ligature_left[i], "ligature"); - GlyphIndex rightgi = find_err(ligature_right[i], "ligature"); - GlyphIndex resultgi = find_err(ligature_result[i], "ligature"); - if (leftgi >= 0 && rightgi >= 0 && resultgi >= 0) - if (_afm->add_lig(leftgi, rightgi, resultgi)) - lwarning("duplicate ligature; first ignored"); - } - ligature_left.clear(); - ligature_right.clear(); - ligature_result.clear(); -} - - -void -AfmReader::read_kerns() const -{ - double kx; - PermString left, right; - GlyphIndex leftgi, rightgi; - - AfmParser &l = _l; - // AFM files have reversed pair programs when read. - _afm->pair_program()->set_reversed(true); - - while (l.next_line()) - switch (l.first()) { - - case 'C': - if (l.is("Comment")) - break; - goto invalid; - - case 'E': - if (l.isall("EndKernPairs")) - break; - if (l.isall("EndKernData")) - return; - if (l.isall("EndTrackKern")) - break; - goto invalid; - - case 'K': - if (l.isall("KPX %/s %/s %g", &left, &right, &kx)) { - goto validkern; - } - if (l.isall("KP %/s %/s %g %g", &left, &right, &kx, (double *)0)) { - y_width_warning(); - goto validkern; - } - if (l.isall("KPY %/s %/s %g", &left, &right, (double *)0)) { - y_width_warning(); - break; - } - if (l.isall("KPH <%x> <%x> %g %g", (int *)0, (int *)0, - (double *)0, (double *)0)) { - lwarning("KPH not supported"); - break; - } - goto invalid; - - validkern: - leftgi = find_err(left, "kern"); - rightgi = find_err(right, "kern"); - if (leftgi >= 0 && rightgi >= 0) - // A kern with 0 amount is NOT useless! - // (Because of multiple masters.) - if (_afm->add_kern(leftgi, rightgi, _afm->add_kv(kx))) - lwarning("duplicate kern; first pair ignored"); - break; - - case 'S': - if (l.isall("StartKernPairs %d", (int *)0) || - l.isall("StartKernPairs0 %d", (int *)0)) - break; - if (l.isall("StartKernPairs1 %d", (int *)0)) { - metrics_sets_warning(); - break; - } - if (l.isall("StartTrackKern %d", (int *)0)) - break; - goto invalid; - - case 'T': - if (l.isall("TrackKern %g %g %g %g %g", (double *)0, (double *)0, - (double *)0, (double *)0, (double *)0)) - break; // FIXME: implement TrackKern - goto invalid; - - default: - invalid: - no_match_warning(); - break; - - } -} - - -void -AfmReader::read_composites() const -{ - while (_l.next_line()) - switch (_l.first()) { - - case 'C': - if (_l.is("Comment")) - break; - if (_l.is("CC")) - break; - goto invalid; - - case 'E': - if (_l.isall("EndComposites")) - return; - goto invalid; - - default: - invalid: - no_match_warning(); - break; - - } -} - -} |