diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/libefont/afmw.cc')
-rw-r--r-- | Build/source/texk/lcdf-typetools/libefont/afmw.cc | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/Build/source/texk/lcdf-typetools/libefont/afmw.cc b/Build/source/texk/lcdf-typetools/libefont/afmw.cc new file mode 100644 index 00000000000..6044b001551 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/libefont/afmw.cc @@ -0,0 +1,190 @@ +// -*- related-file-name: "../include/efont/afmw.hh" -*- + +/* afmw.{cc,hh} -- Adobe Font Metrics writing + * + * Copyright (c) 1998-2006 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/afmw.hh> +#include <efont/t1cs.hh> /* for KNOWN() */ +namespace Efont { + +AfmWriter::AfmWriter(Metrics *m, FILE *f) + : _m(m), _afm_xt((AfmMetricsXt *)m->find_xt("AFM")), _f(f) +{ +} + +void +AfmWriter::write(Metrics *m, FILE *f) +{ + AfmWriter w(m, f); + w.write(); +} + + +void +AfmWriter::write() +{ + _m->pair_program()->unreverse(); + _m->pair_program()->optimize(); + + fprintf(_f, "StartFontMetrics 4.1\n"); + if (_afm_xt) + for (int i = 0; i < _afm_xt->opening_comments.size(); i++) + fprintf(_f, "Comment %s\n", _afm_xt->opening_comments[i].c_str()); + + write_prologue(); + + fprintf(_f, "StartCharMetrics %d\n", _m->nglyphs()); + + GlyphIndex gi; + for (int i = 0; i < 256; i++) //FIXME + if ((gi = _m->find_code(i)) >= 0) + write_char_metric_data(gi, i); + for (gi = 0; gi < _m->nglyphs(); gi++) + if (_m->code(gi) == -1) + write_char_metric_data(gi, -1); + + fprintf(_f, "EndCharMetrics\n"); + + write_kerns(); + + fprintf(_f, "EndFontMetrics\n"); +} + + +void +AfmWriter::write_prologue() const +{ + if (_m->font_name()) + fprintf(_f, "FontName %s\n", _m->font_name().c_str()); + else + fprintf(_f, "FontName No-Font-Name-Given\n"); + + if (_m->full_name()) + fprintf(_f, "FullName %s\n", _m->full_name().c_str()); + if (_m->family()) + fprintf(_f, "FamilyName %s\n", _m->family().c_str()); + if (_m->weight()) + fprintf(_f, "Weight %s\n", _m->weight().c_str()); + + if (KNOWN(fd( fdItalicAngle ))) + fprintf(_f, "ItalicAngle %.8g\n", fd( fdItalicAngle )); + + fprintf(_f, "FontBBox %.8g %.8g %.8g %.8g\n", + fd( fdFontBBllx ), fd( fdFontBBlly ), + fd( fdFontBBurx ), fd( fdFontBBury )); + + if (KNOWN(fd( fdUnderlinePosition ))) + fprintf(_f, "UnderlinePosition %.8g\n", fd( fdUnderlinePosition )); + if (KNOWN(fd( fdUnderlineThickness ))) + fprintf(_f, "UnderlineThickness %.8g\n", fd( fdUnderlineThickness )); + + if (_m->version()) + fprintf(_f, "Version %s\n", _m->version().c_str()); + if (_afm_xt && _afm_xt->notice) + fprintf(_f, "Notice %s\n", _afm_xt->notice.c_str()); + + if (_afm_xt && _afm_xt->encoding_scheme) + fprintf(_f, "EncodingScheme %s\n", _afm_xt->encoding_scheme.c_str()); + + if (KNOWN(fd( fdCapHeight ))) + fprintf(_f, "CapHeight %.8g\n", fd( fdCapHeight )); + if (KNOWN(fd( fdXHeight ))) + fprintf(_f, "XHeight %.8g\n", fd( fdXHeight )); + if (KNOWN(fd( fdAscender ))) + fprintf(_f, "Ascender %.8g\n", fd( fdAscender )); + if (KNOWN(fd( fdDescender ))) + fprintf(_f, "Descender %.8g\n", fd( fdDescender )); + if (KNOWN(fd( fdStdHW ))) + fprintf(_f, "StdHW %.8g\n", fd( fdStdHW )); + if (KNOWN(fd( fdStdVW ))) + fprintf(_f, "StdVW %.8g\n", fd( fdStdVW )); +} + + +void +AfmWriter::write_char_metric_data(GlyphIndex gi, int e) const +{ + if (e >= -1 && e < 256) + fprintf(_f, "C %d ;", e); + else + fprintf(_f, "CH <%04X> ;", e); + + double w = _m->wd(gi); + if (KNOWN(w)) + fprintf(_f, " WX %.8g ;", w); + else + w = 0; + + fprintf(_f, " N %s ;", _m->name(gi).c_str()); + + if (KNOWN(_m->lf(gi))) + fprintf(_f, " B %.8g %.8g %.8g %.8g ;", + _m->lf(gi), _m->bt(gi), _m->rt(gi), _m->tp(gi)); + + // Run through the ligature/kern program to find ligatures. + PairProgram &pairp = *_m->pair_program(); + PairOpIndex opi = pairp.find_left(gi); + while (opi >= 0) { + const PairOp &op = pairp.op(opi); + if (op.is_lig()) { + if (op.lig_kind() == opLigSimple) + fprintf(_f, " L %s %s ;", + _m->name( op.right() ).c_str(), + _m->name( op.result() ).c_str()); + //else + //warning("strange ligature combination not supported by AFM"); + } + opi = op.next_left(); + } + + fputc('\n', _f); +} + + +void +AfmWriter::write_kerns() const +{ + PairProgram &pairp = *_m->pair_program(); + + // Damn. First we have to count how many kerning pairs there are. + int numkerns = 0; + for (PairOpIndex opi = 0; opi < pairp.op_count(); opi++) { + const PairOp &op = pairp.op(opi); + if (op.is_kern() && _m->kv( op.value() )) + numkerns++; + } + + if (numkerns == 0) return; + + fprintf(_f, "StartKernData\n"); + fprintf(_f, "StartKernPairs %d\n", numkerns); + for (GlyphIndex gi = 0; gi < _m->nglyphs(); gi++) { + PairOpIndex opi = pairp.find_left(gi); + while (opi >= 0) { + const PairOp &op = pairp.op(opi); + if (op.is_kern() && _m->kv( op.value() )) + fprintf(_f, "KPX %s %s %.8g\n", + _m->name( gi ).c_str(), + _m->name( op.right() ).c_str(), + _m->kv( op.value() )); + opi = op.next_left(); + } + } + fprintf(_f, "EndKernPairs\n"); + fprintf(_f, "EndKernData\n"); +} + +} |