diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont')
30 files changed, 4622 insertions, 0 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afm.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afm.hh new file mode 100644 index 00000000000..5c37d1e942e --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afm.hh @@ -0,0 +1,59 @@ +// -*- related-file-name: "../../libefont/afm.cc" -*- +#ifndef EFONT_AFM_HH +#define EFONT_AFM_HH +#include <efont/metrics.hh> +class Slurper; +class Filename; +class ErrorHandler; +namespace Efont { +class AfmParser; + +struct AfmMetricsXt: public MetricsXt { + + Vector<PermString> opening_comments; + PermString notice; + PermString encoding_scheme; + + PermString kind() const { return "AFM"; } + +}; + +class AfmReader { public: + + static Metrics *read(const Filename &, ErrorHandler *); + static Metrics *read(Slurper &, ErrorHandler *); + + private: + + Metrics *_afm; + AfmMetricsXt *_afm_xt; + AfmParser &_l; + ErrorHandler *_errh; + + mutable bool _composite_warned; + mutable bool _metrics_sets_warned; + mutable int _y_width_warned; + + void lwarning(const char *, ...) const; + void lerror(const char *, ...) const; + void composite_warning() const; + void metrics_sets_warning() const; + void y_width_warning() const; + void no_match_warning(const char *context = 0) const; + + double &fd(int i) { return _afm->fd(i); } + GlyphIndex find_err(PermString, const char *) const; + + void read_char_metric_data() const; + void read_char_metrics() const; + void read_kerns() const; + void read_composites() const; + + bool read(); + + AfmReader(AfmParser &, Metrics *, AfmMetricsXt *, ErrorHandler *); + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmparse.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmparse.hh new file mode 100644 index 00000000000..c97c4949b0c --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmparse.hh @@ -0,0 +1,64 @@ +// -*- related-file-name: "../../libefont/afmparse.cc" -*- +#ifndef EFONT_AFMPARSE_HH +#define EFONT_AFMPARSE_HH +#include <lcdf/slurper.hh> +#include <lcdf/permstr.hh> +#include <stdarg.h> +namespace Efont { + +class AfmParser { public: + + AfmParser(Slurper &); + + bool ok() const { return _slurper.ok(); } + operator Landmark() const { return _slurper.landmark(); } + Landmark landmark() const { return _slurper.landmark(); } + unsigned lineno() const { return _slurper.lineno(); } + const Filename &filename() const { return _slurper.filename(); } + + bool key_matched() const { return _fail_field >= 0; } + int fail_field() const { return _fail_field; } + PermString message() const { return _message; } + void clear_message() { _message = PermString(); } + + PermString keyword() const; + bool is(const char *, ...); + bool isall(const char *, ...); + + inline bool next_line(); + void save_line() { _slurper.save_line(); } + void skip_until(unsigned char); + + unsigned char *cur_line() const { return _pos; } + unsigned char first() const { return _pos[0]; } + unsigned char operator[](int i) const { return _pos[i]; } + bool left() const { return *_pos != 0; } + + private: + + Slurper &_slurper; + bool _save_line; + + unsigned char *_line; + unsigned char *_pos; + int _length; + + PermString _message; + int _fail_field; + + void static_initialize(); + void trim_end(); + unsigned char *vis(const char *, va_list); + +}; + + +inline bool AfmParser::next_line() +{ + _pos = _line = (unsigned char *)_slurper.next_line(); + _length = _slurper.cur_line_length(); + return _line != 0; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmw.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmw.hh new file mode 100644 index 00000000000..d901b3cd3c2 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/afmw.hh @@ -0,0 +1,29 @@ +#ifndef EFONT_AFMW_HH +#define EFONT_AFMW_HH +#include <efont/afm.hh> +#include <stdio.h> +namespace Efont { + +class AfmWriter { public: + + static void write(Metrics *, FILE *); + + private: + + Metrics *_m; + AfmMetricsXt *_afm_xt; + FILE *_f; + + void write_prologue() const; + void write_char_metric_data(GlyphIndex, int) const; + void write_kerns() const; + void write(); + + double fd(int i) const { return _m->fd(i); } + + AfmWriter(Metrics *, FILE *); + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/amfm.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/amfm.hh new file mode 100644 index 00000000000..55cf1909546 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/amfm.hh @@ -0,0 +1,153 @@ +// -*- related-file-name: "../../libefont/amfm.cc" -*- +#ifndef EFONT_AMFM_HH +#define EFONT_AMFM_HH +#include <efont/metrics.hh> +#include <efont/t1mm.hh> +#include <lcdf/hashmap.hh> +class Slurper; +class Filename; +class ErrorHandler; +namespace Efont { +class AfmParser; +class MetricsFinder; +class Type1Charstring; + + +struct AmfmMaster { + + PermString font_name; + PermString family; + PermString full_name; + PermString version; + Vector<double> weight_vector; + + bool loaded; + Metrics *afm; + + AmfmMaster() : loaded(0), afm(0) { } + +}; + + +struct AmfmPrimaryFont { + + Vector<int> design_vector; + Vector<PermString> labels; + PermString name; + AmfmPrimaryFont *next; + +}; + + +class AmfmMetrics { public: + + AmfmMetrics(MetricsFinder *); + ~AmfmMetrics(); + + void use() { _uses++; } + void unuse() { if (--_uses == 0) delete this; } + + bool sanity(ErrorHandler *) const; + + double fd(int i) const { return _fdv[i]; } + double &fd(int i) { return _fdv[i]; } + + PermString font_name() const { return _font_name; } + PermString directory() const { return _directory; } + + int naxes() const { return _naxes; } + int nmasters() const { return _nmasters; } + MultipleMasterSpace *mmspace() const { return _mmspace; } + + int primary_label_value(int, PermString) const; + + Metrics *interpolate(const Vector<double> &design, + const Vector<double> &weight, ErrorHandler *); + + private: + + MetricsFinder *_finder; + PermString _directory; + + Vector<double> _fdv; + + PermString _font_name; + PermString _family; + PermString _full_name; + PermString _weight; + + PermString _version; + PermString _notice; + Vector<PermString> _opening_comments; + + PermString _encoding_scheme; + Vector<double> _weight_vector; + + int _nmasters; + int _naxes; + AmfmMaster *_masters; + MultipleMasterSpace *_mmspace; + + AmfmPrimaryFont *_primary_fonts; + + Metrics *_sanity_afm; + + unsigned _uses; + + friend class AmfmReader; + + AmfmMetrics(const AmfmMetrics &) { assert(0); } + AmfmMetrics &operator=(const AmfmMetrics &) { assert(0); return *this; } + + AmfmPrimaryFont *find_primary_font(const Vector<double> &design) const; + + Metrics *master(int, ErrorHandler *); + +}; + + +class AmfmReader { public: + + static AmfmMetrics *read(const Filename &, MetricsFinder *, ErrorHandler*); + static AmfmMetrics *read(Slurper &, MetricsFinder *, ErrorHandler *); + static void add_amcp_file(Slurper &, AmfmMetrics *, ErrorHandler *); + + private: + + typedef Vector<double> NumVector; + + AmfmMetrics *_amfm; + MetricsFinder *_finder; + AfmParser &_l; + MultipleMasterSpace *_mmspace; + ErrorHandler *_errh; + + double &fd(int i) const { return _amfm->fd(i); } + int naxes() const { return _amfm->_naxes; } + int nmasters() const { return _amfm->_nmasters; } + + void check_mmspace(); + + void lwarning(const char *, ...) const; + void lerror(const char *, ...) const; + void no_match_warning(const char *context = 0) const; + + bool read_simple_array(Vector<double> &) const; + void read_positions() const; + void read_normalize() const; + void read_axis_types() const; + void read_axis(int axis) const; + void read_master(int master) const; + void read_primary_fonts() const; + void read_one_primary_font() const; + void read_conversion_programs() const; + bool read(); + + void read_amcp_file(); + + AmfmReader(AfmParser &, AmfmMetrics *, ErrorHandler *); + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh new file mode 100644 index 00000000000..e33c74abf00 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh @@ -0,0 +1,460 @@ +// -*- related-file-name: "../../libefont/cff.cc" -*- +#ifndef EFONT_CFF_HH +#define EFONT_CFF_HH +#include <lcdf/hashmap.hh> +#include <efont/t1cs.hh> +class ErrorHandler; +namespace Efont { +class Type1Encoding; + +class Cff { public: + + class Dict; + class IndexIterator; + class Charset; + class FDSelect; + class FontParent; + class Font; + class CIDFont; + class ChildFont; + + explicit Cff(const String& str, unsigned units_per_em, + ErrorHandler* errh = 0); + ~Cff(); + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + const String &data_string() const { return _data_string; } + const uint8_t *data() const { return _data; } + int length() const { return _len; } + + int nfonts() const { return _name_index.size(); } + PermString font_name(int i) const { return _name_index[i]; } + FontParent *font(PermString = PermString(), ErrorHandler * = 0); + + enum { NSTANDARD_STRINGS = 391, MAX_SID = 64999 }; + int max_sid() const { return NSTANDARD_STRINGS - 1 + _strings.size(); } + int sid(PermString); + String sid_string(int sid) const; + PermString sid_permstring(int sid) const; + + int ngsubrs() const { return _gsubrs_index.nitems(); } + Charstring *gsubr(int i); + + unsigned units_per_em() const { return _units_per_em; } + + enum DictOperator { + oVersion = 0, oNotice = 1, oFullName = 2, oFamilyName = 3, + oWeight = 4, oFontBBox = 5, oBlueValues = 6, oOtherBlues = 7, + oFamilyBlues = 8, oFamilyOtherBlues = 9, oStdHW = 10, oStdVW = 11, + oUniqueID = 13, oXUID = 14, oCharset = 15, oEncoding = 16, + oCharStrings = 17, oPrivate = 18, oSubrs = 19, oDefaultWidthX = 20, + oNominalWidthX = 21, + oCopyright = 32 + 0, oIsFixedPitch = 32 + 1, oItalicAngle = 32 + 2, + oUnderlinePosition = 32 + 3, oUnderlineThickness = 32 + 4, + oPaintType = 32 + 5, oCharstringType = 32 + 6, oFontMatrix = 32 + 7, + oStrokeWidth = 32 + 8, oBlueScale = 32 + 9, oBlueShift = 32 + 10, + oBlueFuzz = 32 + 11, oStemSnapH = 32 + 12, oStemSnapV = 32 + 13, + oForceBold = 32 + 14, oLanguageGroup = 32 + 17, + oExpansionFactor = 32 + 18, oInitialRandomSeed = 32 + 19, + oSyntheticBase = 32 + 20, oPostScript = 32 + 21, + oBaseFontName = 32 + 22, oBaseFontBlend = 32 + 23, + oROS = 32 + 30, oCIDFontVersion = 32 + 31, oCIDFontRevision = 32 + 32, + oCIDFontType = 32 + 33, oCIDCount = 32 + 34, oUIDBase = 32 + 35, + oFDArray = 32 + 36, oFDSelect = 32 + 37, oFontName = 32 + 38, + oLastOperator = oFontName + }; + + enum DictType { + tNone = 0, tSID, tFontNumber, tBoolean, tNumber, tOffset, tLocalOffset, + tArray, tArray2, tArray3, tArray4, tArray5, tArray6, tPrivateType, + tTypeMask = 0x7F, tPrivate = 0x80, tP = tPrivate + }; + + static const char * const operator_names[]; + static const int operator_types[]; + + + class IndexIterator { public: + + IndexIterator() : _offset(0), _last_offset(0), _offsize(-1) { } + IndexIterator(const uint8_t *, int, int, ErrorHandler * = 0, const char *index_name = "INDEX"); + + int error() const { return (_offsize < 0 ? _offsize : 0); } + + typedef bool (IndexIterator::*unspecified_bool_type)() const; + bool live() const { return _offset < _last_offset; } + operator unspecified_bool_type() const { + return live() ? &IndexIterator::live : 0; + } + int nitems() const; + + inline const uint8_t *operator*() const; + inline const uint8_t *operator[](int) const; + const uint8_t *index_end() const; + + void operator++() { _offset += _offsize; } + void operator++(int) { ++(*this); } + + private: + + const uint8_t *_contents; + const uint8_t *_offset; + const uint8_t *_last_offset; + int _offsize; + + inline uint32_t offset_at(const uint8_t *) const; + + }; + + private: + + String _data_string; + const uint8_t *_data; + int _len; + + int _error; + + Vector<PermString> _name_index; + + IndexIterator _top_dict_index; + + IndexIterator _strings_index; + mutable Vector<PermString> _strings; + mutable HashMap<PermString, int> _strings_map; + + IndexIterator _gsubrs_index; + Vector<Charstring *> _gsubrs_cs; + + unsigned _units_per_em; + + int parse_header(ErrorHandler *); + int font_offset(int, int &, int &) const; + int font_offset(PermString, int &, int &) const; + + enum { HEADER_SIZE = 4 }; + +}; + + +class Cff::Dict { public: + + Dict(); + Dict(Cff *, int pos, int dict_len, ErrorHandler * = 0, const char *dict_name = "DICT"); + int assign(Cff *, int pos, int dict_len, ErrorHandler * = 0, const char *dict_name = "DICT"); + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + int check(bool is_private, ErrorHandler * = 0, const char *dict_name = "DICT") const; + + bool has(DictOperator) const; + inline bool has_first(DictOperator) const; + bool xvalue(DictOperator, Vector<double> &) const; + bool xvalue(DictOperator, int *) const; + bool xvalue(DictOperator, double *) const; + bool value(DictOperator, Vector<double> &) const; + bool value(DictOperator, int *) const; + bool value(DictOperator, double *) const; + + void unparse(ErrorHandler *, const char *) const; + + private: + + Cff *_cff; + int _pos; + Vector<int> _operators; + Vector<int> _pointers; + Vector<double> _operands; + int _error; + +}; + +class Cff::Charset { public: + + Charset() : _error(-1) { } + Charset(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler * = 0); + void assign(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler * = 0); + + int error() const { return _error; } + + int nglyphs() const { return _sids.size(); } + int nsids() const { return _gids.size(); } + + inline int gid_to_sid(int gid) const; + inline int sid_to_gid(int sid) const; + + private: + + Vector<int> _sids; + Vector<int> _gids; + int _error; + + void assign(const int *, int, int); + int parse(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler *); + +}; + +class Cff::FDSelect { public: + + FDSelect() : _fds(0), _my_fds(false), _nglyphs(0), _error(-1) { } + ~FDSelect(); + void assign(const Cff *, int pos, int nglyphs, ErrorHandler * = 0); + + int error() const { return _error; } + + int nglyphs() const { return _nglyphs; } + inline int gid_to_fd(int gid) const; + + private: + + const uint8_t *_fds; + bool _my_fds; + int _nglyphs; + int _error; + + FDSelect(const FDSelect &); + FDSelect &operator=(const FDSelect &); + int parse(const Cff *, int pos, int nglyphs, ErrorHandler *); + +}; + + +class Cff::FontParent : public CharstringProgram { public: + + FontParent(Cff* cff); + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + int ngsubrs_x() const { return _cff->ngsubrs(); } + int ngsubrs() const { return ngsubrs_x(); } + Charstring *gsubr(int) const; + int gsubr_bias() const; + + private: + + Cff* _cff; + int _charstring_type; + int _error; + + FontParent(const FontParent &); + FontParent &operator=(const FontParent &); + + Charstring *charstring(const IndexIterator &, int) const; + + friend class Cff::Font; + friend class Cff::CIDFont; + friend class Cff::ChildFont; + +}; + +class Cff::CIDFont : public Cff::FontParent { public: + + CIDFont(Cff* cff, PermString, const Dict &, ErrorHandler *); + ~CIDFont(); + + PermString font_name() const { return _font_name; } + void font_matrix(double[6]) const; + + int nglyphs() const { return _charstrings_index.nitems(); } + PermString glyph_name(int) const; + void glyph_names(Vector<PermString> &) const; + Charstring *glyph(int) const; + Charstring *glyph(PermString) const; + int glyphid(PermString) const; + const CharstringProgram *child_program(int) const; + + bool dict_has(DictOperator) const; + String dict_string(DictOperator) const; + bool dict_value(DictOperator, double *) const; + bool dict_xvalue(DictOperator, double, double *) const; + bool dict_value(DictOperator, Vector<double> &) const; + + private: + + PermString _font_name; + + Dict _top_dict; + Dict _private_dict; + + Cff::Charset _charset; + + IndexIterator _charstrings_index; + mutable Vector<Charstring *> _charstrings_cs; + + Vector<ChildFont *> _child_fonts; + Cff::FDSelect _fdselect; + + const Dict &dict_of(DictOperator) const; + +}; + +class Cff::ChildFont : public Cff::FontParent { public: + + ChildFont(Cff* cff, Cff::CIDFont *, int charstring_type, const Dict &, ErrorHandler * = 0); + ~ChildFont(); + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + PermString font_name() const { return _parent->font_name(); } + void font_matrix(double m[6]) const { _parent->font_matrix(m); } + + inline bool cid() const; + + int nsubrs_x() const { return _subrs_index.nitems(); } + int nsubrs() const { return nsubrs_x(); } + Charstring *subr(int) const; + int subr_bias() const; + + int nglyphs() const { return _parent->nglyphs(); } + PermString glyph_name(int gi) const { return _parent->glyph_name(gi); } + void glyph_names(Vector<PermString> &v) const { _parent->glyph_names(v); } + Charstring *glyph(int gi) const { return _parent->glyph(gi); } + Charstring *glyph(PermString n) const { return _parent->glyph(n); } + + double global_width_x(bool) const; + + private: + + Cff::CIDFont *_parent; + + Dict _top_dict; + Dict _private_dict; + + IndexIterator _subrs_index; + mutable Vector<Charstring *> _subrs_cs; + + double _default_width_x; + double _nominal_width_x; + + ChildFont(const ChildFont &); // does not exist + ChildFont &operator=(const ChildFont &); // does not exist + + Charstring *charstring(const IndexIterator &, int) const; + + friend class Cff::Font; + +}; + +class Cff::Font : public Cff::ChildFont { public: + + Font(Cff* cff, PermString, const Dict &, ErrorHandler *); + ~Font(); + + PermString font_name() const { return _font_name; } + void font_matrix(double[6]) const; + + int nglyphs() const { return _charstrings_index.nitems(); } + PermString glyph_name(int) const; + void glyph_names(Vector<PermString> &) const; + Charstring *glyph(int) const; + Charstring *glyph(PermString) const; + int glyphid(PermString) const; + + Type1Encoding *type1_encoding() const; + Type1Encoding *type1_encoding_copy() const; + + bool dict_has(DictOperator) const; + String dict_string(DictOperator) const; + inline bool dict_value(DictOperator, double *) const; + inline bool dict_value(DictOperator, Vector<double> &) const; + const Dict &top_dict() const { return _top_dict; } + + private: + + PermString _font_name; + + Cff::Charset _charset; + + IndexIterator _charstrings_index; + mutable Vector<Charstring *> _charstrings_cs; + + int _encoding_pos; + int _encoding[256]; + mutable Type1Encoding *_t1encoding; + + int parse_encoding(int pos, ErrorHandler *); + int assign_standard_encoding(const int *standard_encoding); + + inline const Dict &dict_of(DictOperator) const; + +}; + + +inline uint32_t Cff::IndexIterator::offset_at(const uint8_t *x) const +{ + switch (_offsize) { + case 0: + return 0; + case 1: + return x[0]; + case 2: + return (x[0] << 8) | x[1]; + case 3: + return (x[0] << 16) | (x[1] << 8) | x[2]; + default: + return (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]; + } +} + +inline const uint8_t *Cff::IndexIterator::operator*() const +{ + assert(live()); + return _contents + offset_at(_offset); +} + +inline const uint8_t *Cff::IndexIterator::operator[](int which) const +{ + assert(live() && _offset + which * _offsize <= _last_offset); + return _contents + offset_at(_offset + which * _offsize); +} + +inline int Cff::Charset::gid_to_sid(int gid) const +{ + if (gid >= 0 && gid < _sids.size()) + return _sids[gid]; + else + return -1; +} + +inline int Cff::Charset::sid_to_gid(int sid) const +{ + if (sid >= 0 && sid < _gids.size()) + return _gids[sid]; + else + return -1; +} + +inline int Cff::FDSelect::gid_to_fd(int gid) const +{ + if (gid >= 0 && gid < _nglyphs) + return _fds[gid]; + else + return -1; +} + +inline bool Cff::Dict::has_first(DictOperator op) const +{ + return _operators.size() && _operators[0] == op; +} + +inline const Cff::Dict &Cff::Font::dict_of(DictOperator op) const +{ + return (op >= 0 && op <= oLastOperator && (operator_types[op] & tP) ? _private_dict : _top_dict); +} + +inline bool Cff::Font::dict_value(DictOperator op, double *val) const +{ + return dict_of(op).value(op, val); +} + +inline bool Cff::Font::dict_value(DictOperator op, Vector<double> &val) const +{ + return dict_of(op).value(op, val); +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/encoding.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/encoding.hh new file mode 100644 index 00000000000..eb7aa004f28 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/encoding.hh @@ -0,0 +1,27 @@ +// -*- related-file-name: "../../libefont/encoding.cc" -*- +#ifndef EFONT_ENCODING_HH +#define EFONT_ENCODING_HH +#include <lcdf/vector.hh> +namespace Efont { +typedef int GlyphIndex; + +class Encoding8 { + + Vector<GlyphIndex> _codes; + Vector<int> _code_map; + + public: + + Encoding8() : _code_map(256, -1) { } + + void reserve_glyphs(int); + + int code(GlyphIndex gi) const { return _codes[gi]; } + GlyphIndex find_code(int c) const { return _code_map[c]; } + + void set_code(GlyphIndex gi, int c) { _codes[gi] = c; _code_map[c] = gi; } + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/findmet.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/findmet.hh new file mode 100644 index 00000000000..542ed6dddc6 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/findmet.hh @@ -0,0 +1,114 @@ +// -*- related-file-name: "../../libefont/findmet.cc" -*- +#ifndef EFONT_FINDMET_HH +#define EFONT_FINDMET_HH +#include <lcdf/hashmap.hh> +#include <lcdf/vector.hh> +#include <lcdf/permstr.hh> +class Filename; +class ErrorHandler; +namespace Efont { +class Metrics; +class AmfmMetrics; +class PsresDatabase; + +class MetricsFinder { public: + + MetricsFinder() : _next(0), _prev(0) { } + virtual ~MetricsFinder(); + + MetricsFinder *next() const { return _next; } + + void add_finder(MetricsFinder *); + + Metrics *find_metrics(PermString, ErrorHandler * = 0); + AmfmMetrics *find_amfm(PermString, ErrorHandler * = 0); + + virtual Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); + virtual AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); + + void record(Metrics *m); + virtual void record(Metrics *, PermString); + virtual void record(AmfmMetrics *); + + private: + + MetricsFinder *_next; + MetricsFinder *_prev; + + MetricsFinder(const MetricsFinder &) { } + MetricsFinder &operator=(const MetricsFinder &) { return *this; } + + protected: + + Metrics *try_metrics_file(const Filename &, MetricsFinder *, ErrorHandler *); + AmfmMetrics *try_amfm_file(const Filename &, MetricsFinder *, ErrorHandler *); + +}; + + +class CacheMetricsFinder: public MetricsFinder { public: + + CacheMetricsFinder(); + ~CacheMetricsFinder(); + + Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); + AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); + void record(Metrics *, PermString); + void record(AmfmMetrics *); + + void clear(); + + private: + + HashMap<PermString, int> _metrics_map; + Vector<Metrics *> _metrics; + HashMap<PermString, int> _amfm_map; + Vector<AmfmMetrics *> _amfm; + +}; + + +class InstanceMetricsFinder: public MetricsFinder { public: + + InstanceMetricsFinder(bool call_mmpfb = true); + + Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); + + private: + + bool _call_mmpfb; + + Metrics *find_metrics_instance(PermString, MetricsFinder *, ErrorHandler *); + +}; + + +class PsresMetricsFinder: public MetricsFinder { public: + + PsresMetricsFinder(PsresDatabase *); + + Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); + AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); + + private: + + PsresDatabase *_psres; + +}; + + +class DirectoryMetricsFinder: public MetricsFinder { public: + + DirectoryMetricsFinder(PermString); + + Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); + AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); + + private: + + PermString _directory; + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/metrics.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/metrics.hh new file mode 100644 index 00000000000..82c5eb0d26f --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/metrics.hh @@ -0,0 +1,177 @@ +// -*- related-file-name: "../../libefont/metrics.cc" -*- +#ifndef EFONT_METRICS_HH +#define EFONT_METRICS_HH +#include <lcdf/permstr.hh> +#include <lcdf/vector.hh> +#include <lcdf/hashmap.hh> +#include <efont/encoding.hh> +#include <efont/pairop.hh> +namespace Efont { +class MetricsXt; + +class Metrics { public: + + Metrics(); + Metrics(PermString font_name, PermString full_name, const Metrics &); + ~Metrics(); + + void use() { _uses++; } + void unuse() { if (--_uses == 0) delete this; } + + // GLOBALS + + PermString font_name() const { return _font_name; } + PermString family() const { return _family; } + PermString full_name() const { return _full_name; } + PermString weight() const { return _weight; } + PermString version() const { return _version; } + + void set_font_name(PermString); + void set_family(PermString s) { _family = s; } + void set_full_name(PermString s) { _full_name = s; } + void set_weight(PermString s) { _weight = s; } + void set_version(PermString s) { _version = s; } + + // GLYPHS + + int nglyphs() const { return _names.size(); } + PermString name(GlyphIndex gi) const { return _names[gi]; } + GlyphIndex find(PermString n) const { return _name_map[n]; } + + int code(GlyphIndex gi) const { return _encoding.code(gi); } + GlyphIndex find_code(int c) const { return _encoding.find_code(c); } + void set_code(GlyphIndex gi, int c) { _encoding.set_code(gi, c); } + + GlyphIndex add_glyph(PermString); + void reserve_glyphs(int); + + // DIMENSIONS + + double scale() const { return _scale; } + void set_scale(double d) { _scale = d; } + + int nfd() const { return _fdv.size(); } + int nkv() const { return _kernv.size(); } + + double fd(int i) const { return _fdv[i]; } + double wd(int i) const { return _wdv[i]; } + double lf(int i) const { return _lfv[i]; } + double rt(int i) const { return _rtv[i]; } + double tp(int i) const { return _tpv[i]; } + double bt(int i) const { return _btv[i]; } + double kv(int i) const { return _kernv[i]; } + + double &fd(int i) { return _fdv[i]; } + double &wd(int i) { return _wdv[i]; } + double &lf(int i) { return _lfv[i]; } + double &rt(int i) { return _rtv[i]; } + double &tp(int i) { return _tpv[i]; } + double &bt(int i) { return _btv[i]; } + double &kv(int i) { return _kernv[i]; } + + inline int add_kv(double d); + + void interpolate_dimens(const Metrics &, double, bool increment); + + // PAIR PROGRAM + + PairProgram *pair_program() { return &_pairp; } + const PairProgram *pair_program() const { return &_pairp; } + inline bool add_kern(GlyphIndex, GlyphIndex, int); + inline bool add_lig(GlyphIndex, GlyphIndex, GlyphIndex, int = opLigSimple); + + // EXTENSIONS + + MetricsXt *find_xt(PermString name) const { return _xt[_xt_map[name]]; } + void add_xt(MetricsXt *); + + private: + + PermString _font_name; + + PermString _family; + PermString _full_name; + PermString _weight; + PermString _version; + + HashMap<PermString, GlyphIndex> _name_map; + Vector<PermString> _names; + Encoding8 _encoding; + + double _scale; + + Vector<double> _fdv; + Vector<double> _wdv; + Vector<double> _lfv; + Vector<double> _rtv; + Vector<double> _tpv; + Vector<double> _btv; + + PairProgram _pairp; + Vector<double> _kernv; + + HashMap<PermString, int> _xt_map; + Vector<MetricsXt *> _xt; + + unsigned _uses; + +}; + + +class MetricsXt { + + public: + + MetricsXt() { } + virtual ~MetricsXt() { } + + virtual PermString kind() const = 0; + + virtual void reserve_glyphs(int) { } + +}; + + +enum FontDimensionDefs { + + fdCapHeight = 0, + fdXHeight, + fdAscender, + fdDescender, + + fdItalicAngle, + fdUnderlinePosition, + fdUnderlineThickness, + + fdFontBBllx, + fdFontBBlly, + fdFontBBurx, + fdFontBBury, + + fdStdHW, + fdStdVW, + + fdLast + +}; + + +inline bool Metrics::add_kern(GlyphIndex g1, GlyphIndex g2, int ki) +{ + return _pairp.add_kern(g1, g2, ki); +} + +inline bool Metrics::add_lig(GlyphIndex g1, GlyphIndex g2, GlyphIndex gr, int kind) +{ + return _pairp.add_lig(g1, g2, gr, kind); +} + +inline int Metrics::add_kv(double d) +{ + int k = _kernv.size(); + _kernv.push_back(d); + return k; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh new file mode 100644 index 00000000000..c47c1c29cf8 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh @@ -0,0 +1,371 @@ +// -*- related-file-name: "../../libefont/otf.cc" -*- +#ifndef EFONT_OTF_HH +#define EFONT_OTF_HH +#include <efont/otfdata.hh> +#include <lcdf/hashcode.hh> +class ErrorHandler; +namespace Efont { namespace OpenType { +class Post; +class Name; + +typedef int Glyph; // 16-bit integer + +class Tag { + public: + Tag() : _tag(0U) { } + explicit Tag(uint32_t tag) : _tag(tag) { } + Tag(const char *name); + Tag(const String &name); + // default destructor + + static Tag head_tag() { return Tag(0x68656164U); } + + typedef bool (Tag::*unspecified_bool_type)() const; + bool null() const { return _tag == 0; } + operator unspecified_bool_type() const { + return _tag != 0 ? &Tag::null : 0; + } + bool valid() const; + + uint32_t value() const { return _tag; } + + String text() const; + static String langsys_text(Tag script, Tag langsys = Tag()); + + const uint8_t* table_entry(const uint8_t* table, int n, int entry_size) const; + + const char* script_description() const; + const char* language_description() const; + const char* feature_description() const; + + private: + uint32_t _tag; +}; + +inline hashcode_t hashcode(const Tag& t) { + return t.value(); +} + +class Font { + public: + Font(const String& str, ErrorHandler* errh = 0); + // default destructor + + bool ok() const { return _error >= 0; } + bool check_checksums(ErrorHandler* errh = 0) const; + int error() const { return _error; } + + const String& data_string() const { return _str; } + const uint8_t* data() const { return _str.udata(); } + int length() const { return _str.length(); } + + unsigned units_per_em() const { return _units_per_em; } + + int ntables() const; + bool has_table(Tag tag) const; + String table(Tag tag) const; + uint32_t table_checksum(Tag tag) const; + Tag table_tag(int i) const; + + static uint32_t checksum(const uint8_t *, const uint8_t *); + static uint32_t checksum(const String &); + static Font make(bool truetype, const Vector<Tag>& tags, const Vector<String>& data); + + enum { HEADER_SIZE = 12, TABLE_DIR_ENTRY_SIZE = 16 }; + + private: + String _str; + int _error; + unsigned _units_per_em; + + int parse_header(ErrorHandler*); +}; + +class ScriptList { + public: + ScriptList() { } + inline ScriptList(const String&, ErrorHandler* = 0); + int assign(const String&, ErrorHandler* = 0); + // default destructor + + bool ok() const { return _str.length() > 0; } + + int language_systems(Vector<Tag>& scripts, Vector<Tag>& langsys, ErrorHandler* = 0) const; + int features(Tag script, Tag langsys, int& required_fid, Vector<int>& fids, ErrorHandler* = 0, bool clear_fids = true) const; + + private: + enum { SCRIPTLIST_HEADERSIZE = 2, SCRIPT_RECSIZE = 6, + SCRIPT_HEADERSIZE = 4, LANGSYS_RECSIZE = 6, + LANGSYS_HEADERSIZE = 6, FEATURE_RECSIZE = 2 }; + + String _str; + + int check_header(ErrorHandler*); + int script_offset(Tag) const; + int check_script(Tag, int, ErrorHandler*) const; + int langsys_offset(Tag, Tag, ErrorHandler* = 0) const; +}; + +class FeatureList { + public: + FeatureList() { } + inline FeatureList(const String&, ErrorHandler* = 0); + int assign(const String&, ErrorHandler* = 0); + // default destructor + + bool ok() const { return _str.length() > 0; } + + Tag tag(int fid) const; + String params(int fid, int length, ErrorHandler* = 0, bool old_style_offset = false) const; + String size_params(int fid, const Name& name, ErrorHandler* = 0) const; + int lookups(int fid, Vector<int>& results, ErrorHandler* = 0, bool clear_results = true) const; + + int find(Tag, const Vector<int>& fids) const; + void filter(Vector<int>& fids, const Vector<Tag>& sorted_ftags) const; + inline void filter(Vector<int>& fids, Tag ftag) const; + + int lookups(const Vector<int>& fids, Vector<int>& results, ErrorHandler* = 0) const; + int lookups(const Vector<int>& required_fids, const Vector<int>& fids, const Vector<Tag>& sorted_ftags, Vector<int>& results, ErrorHandler* = 0) const; + int lookups(int required_fid, const Vector<int>& fids, const Vector<Tag>& sorted_ftags, Vector<int>& results, ErrorHandler* = 0) const; + int lookups(const ScriptList&, Tag script, Tag langsys, const Vector<Tag>& sorted_ftags, Vector<int>& results, ErrorHandler* = 0) const; + + private: + enum { FEATURELIST_HEADERSIZE = 2, FEATURE_RECSIZE = 6, + FEATURE_HEADERSIZE = 4, LOOKUPLIST_RECSIZE = 2 }; + + String _str; + + int check_header(ErrorHandler*); + int script_offset(Tag) const; + int langsys_offset(Tag, Tag, ErrorHandler* = 0) const; +}; + +class Coverage { + public: + Coverage() throw (); // empty coverage + Coverage(Glyph first, Glyph last) throw (); // range coverage + Coverage(const Vector<bool> &gmap) throw (); // used-bytemap coverage + Coverage(const String &str, ErrorHandler *errh = 0, bool check = true) throw (); + // default destructor + + bool ok() const throw () { return _str.length() > 0; } + int size() const throw (); + bool has_fast_covers() const throw () { + return _str.length() > 0 && _str.data()[1] == T_X_BYTEMAP; + } + + int coverage_index(Glyph) const throw (); + bool covers(Glyph g) const throw () { return coverage_index(g) >= 0; } + + void unparse(StringAccum&) const throw (); + String unparse() const throw (); + + class iterator { public: + iterator() : _pos(0), _value(0) { } + // private constructor + // default destructor + + bool ok() const { return _pos < _str.length(); } + operator bool() const { return ok(); } + + Glyph operator*() const { return _value; } + Glyph value() const { return _value; } + int coverage_index() const; + + void operator++(int); + void operator++() { (*this)++; } + bool forward_to(Glyph); + + // XXX should check iterators are of same type + bool operator<(const iterator& o) { return _value < o._value; } + bool operator<=(const iterator& o) { return _value <= o._value; } + bool operator>=(const iterator& o) { return _value >= o._value; } + bool operator>(const iterator& o) { return _value > o._value; } + bool operator==(const iterator& o) { return _value == o._value; } + bool operator!=(const iterator& o) { return _value != o._value; } + + private: + String _str; + int _pos; + Glyph _value; + friend class Coverage; + iterator(const String &str, bool is_end); + }; + + iterator begin() const { return iterator(_str, false); } + iterator end() const { return iterator(_str, true); } + Glyph operator[](int) const throw (); + + enum { T_LIST = 1, T_RANGES = 2, T_X_BYTEMAP = 3, + HEADERSIZE = 4, LIST_RECSIZE = 2, RANGES_RECSIZE = 6 }; + + private: + String _str; + + int check(ErrorHandler*); +}; + +Coverage operator&(const Coverage&, const Coverage&); +bool operator<=(const Coverage&, const Coverage&); + +inline bool operator>=(const Coverage& a, const Coverage& b) { + return b <= a; +} + +class GlyphSet { + public: + GlyphSet(); + GlyphSet(const GlyphSet&); + ~GlyphSet(); + + inline bool covers(Glyph g) const; + inline bool operator[](Glyph g) const; + int change(Glyph, bool); + void insert(Glyph g) { change(g, true); } + void remove(Glyph g) { change(g, false); } + + GlyphSet& operator=(const GlyphSet&); + + private: + enum { GLYPHBITS = 16, SHIFT = 8, + MAXGLYPH = (1 << GLYPHBITS) - 1, UNSHIFT = GLYPHBITS - SHIFT, + MASK = (1 << UNSHIFT) - 1, VLEN = (1 << SHIFT), + VULEN = (1 << UNSHIFT) >> 5 + }; + + uint32_t* _v[VLEN]; +}; + +class ClassDef { + public: + ClassDef(const String&, ErrorHandler* = 0) throw (); + // default destructor + + bool ok() const { return _str.length() > 0; } + int nclass() const throw (); + + int lookup(Glyph) const throw (); + int operator[](Glyph g) const throw () { return lookup(g); } + + void unparse(StringAccum&) const throw (); + String unparse() const throw (); + + class class_iterator { + public: + // private constructor + // default destructor + + bool ok() const { return _pos < _str.length(); } + operator bool() const { return ok(); } + + Glyph operator*() const { return *_coviter; } + Glyph value() const { return *_coviter; } + int class_value() const { return _class; } + + void operator++(int); + void operator++() { (*this)++; } + + // XXX should check iterators are of same type + bool operator<(const class_iterator& o) { return _coviter < o._coviter; } + bool operator<=(const class_iterator& o) { return _coviter <= o._coviter; } + bool operator>=(const class_iterator& o) { return _coviter >= o._coviter; } + bool operator>(const class_iterator& o) { return _coviter > o._coviter; } + bool operator==(const class_iterator& o) { return _coviter == o._coviter; } + bool operator!=(const class_iterator& o) { return _coviter != o._coviter; } + + private: + String _str; + int _pos; + int _class; + Coverage::iterator _coviter; + friend class ClassDef; + class_iterator(const String&, int, int, const Coverage::iterator&); + void increment_class0(); + enum { FIRST_POS = -1, LAST_POS = -2 }; + }; + + // XXX does not work correctly for class 0 + class_iterator begin(int c) const { return class_iterator(_str, 0, c, Coverage::iterator()); } + class_iterator begin(int c, const Coverage& coverage) const { return class_iterator(_str, 0, c, coverage.begin()); } + class_iterator end(int c) const { return class_iterator(_str, _str.length(), c, Coverage::iterator()); } + + enum { T_LIST = 1, T_RANGES = 2, + LIST_HEADERSIZE = 6, LIST_RECSIZE = 2, + RANGES_HEADERSIZE = 4, RANGES_RECSIZE = 6 }; + + private: + String _str; + + int check(ErrorHandler*); +}; + +extern Vector<PermString> debug_glyph_names; + + +inline bool operator==(Tag t1, uint32_t t2) { + return t1.value() == t2; +} + +inline bool operator!=(Tag t1, uint32_t t2) { + return t1.value() != t2; +} + +inline bool operator<(Tag t1, uint32_t t2) { + return t1.value() < t2; +} + +inline bool operator>(Tag t1, uint32_t t2) { + return t1.value() > t2; +} + +inline bool operator<=(Tag t1, uint32_t t2) { + return t1.value() <= t2; +} + +inline bool operator>=(Tag t1, uint32_t t2) { + return t1.value() >= t2; +} + +inline bool operator==(Tag t1, Tag t2) { + return t1.value() == t2.value(); +} + +inline bool operator!=(Tag t1, Tag t2) { + return t1.value() != t2.value(); +} + +inline bool operator<(Tag t1, Tag t2) { + return t1.value() < t2.value(); +} + +inline ScriptList::ScriptList(const String& str, ErrorHandler* errh) { + assign(str, errh); +} + +inline FeatureList::FeatureList(const String& str, ErrorHandler* errh) { + assign(str, errh); +} + +inline void FeatureList::filter(Vector<int>& fids, Tag ftag) const { + Vector<Tag> tags; + tags.push_back(ftag); + filter(fids, tags); +} + +inline bool GlyphSet::covers(Glyph g) const { + if ((unsigned)g > MAXGLYPH) + return false; + else if (const uint32_t* u = _v[g >> SHIFT]) + return (u[(g & MASK) >> 5] & (1 << (g & 0x1F))) != 0; + else + return false; +} + +inline bool GlyphSet::operator[](Glyph g) const { + return covers(g); +} + +} // namespace Efont::OpenType +} // namespace Efont + +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfcmap.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfcmap.hh new file mode 100644 index 00000000000..1fdce99802d --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfcmap.hh @@ -0,0 +1,60 @@ +// -*- related-file-name: "../../libefont/otfcmap.cc" -*- +#ifndef EFONT_OTFCMAP_HH +#define EFONT_OTFCMAP_HH +#include <efont/otf.hh> +#include <lcdf/error.hh> +#include <utility> +namespace Efont { namespace OpenType { + +class Cmap { public: + + Cmap(const String &, ErrorHandler * = 0); + // default destructor + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + inline Glyph map_uni(uint32_t c) const; + int map_uni(const Vector<uint32_t> &in, Vector<Glyph> &out) const; + inline void unmap_all(Vector<std::pair<uint32_t, Glyph> > &ugp) const; + + private: + + String _str; + int _error; + int _ntables; + mutable int _first_unicode_table; + mutable Vector<int> _table_error; + + enum { HEADER_SIZE = 4, ENCODING_SIZE = 8, + HIBYTE_SUBHEADERS = 524 }; + enum Format { F_BYTE = 0, F_HIBYTE = 2, F_SEGMENTED = 4, F_TRIMMED = 6, + F_HIBYTE32 = 8, F_TRIMMED32 = 10, F_SEGMENTED32 = 12 }; + enum { USE_FIRST_UNICODE_TABLE = -2 }; + + int parse_header(ErrorHandler *); + int first_unicode_table() const { return _first_unicode_table; } + int first_table(int platform, int encoding) const; + int check_table(int t, ErrorHandler * = 0) const; + Glyph map_table(int t, uint32_t, ErrorHandler * = 0) const; + void dump_table(int t, Vector<std::pair<uint32_t, Glyph> > &ugp, ErrorHandler * = 0) const; + inline const uint8_t* table_data(int t) const; + +}; + + +inline Glyph Cmap::map_uni(uint32_t c) const { + return map_table(USE_FIRST_UNICODE_TABLE, c, ErrorHandler::default_handler()); +} + +inline void Cmap::unmap_all(Vector<std::pair<uint32_t, Glyph> > &ugp) const { + dump_table(USE_FIRST_UNICODE_TABLE, ugp, ErrorHandler::default_handler()); +} + +inline const uint8_t* Cmap::table_data(int t) const { + const uint8_t* data = _str.udata(); + return data + Data::u32_aligned(data + HEADER_SIZE + t * ENCODING_SIZE + 4); +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh new file mode 100644 index 00000000000..30e40860291 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh @@ -0,0 +1,240 @@ +// -*- related-file-name: "../../libefont/otfdata.cc" -*- +#ifndef EFONT_OTFDATA_HH +#define EFONT_OTFDATA_HH +#include <lcdf/string.hh> +#include <lcdf/vector.hh> +#include <lcdf/inttypes.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#if NEED_ARPA_INET_H +# include <arpa/inet.h> +#endif +#if HAVE_BYTEORDER_H +# include <byteorder.h> +#elif HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif HAVE_SYS_PARAM_H +# include <sys/param.h> +#elif !defined(WIN32) +# error "configury disaster! Report this error to ekohler@gmail.com" +#endif +#ifdef WIN32 +# ifdef __MSC_VER +# pragma warning (disable: 4290) +# endif +# include <winsock2.h> +#endif +class ErrorHandler; +namespace Efont { namespace OpenType { + +#if HAVE_PRECONDITION_CHECKING +#define efont_precondition(x) assert((x)) +#else +#define efont_precondition(x) +#endif + +class Error { + public: + String description; + Error() : description(String::make_stable("unspecified error")) { } + Error(const String &d) : description(d) { } +}; + +class Bounds : public Error { + public: + Bounds() : Error(String::make_stable("bounds error")) { } +}; + +class Format : public Error { + public: + Format(const String& name) : Error(name + " format error") { } + Format(const String& name, const String& type) + : Error(name + " " + type + " format error") { } +}; + +class BlankTable : public Format { + public: + BlankTable(const String& name) : Format(name, "blank table") { } +}; + +class Data { + public: + Data() { } + Data(const String& str) : _str(str) { _str.align(2); } + // default copy constructor + // default destructor + + const String& string() const { return _str; } + operator const String&() const { return _str; } + + operator String::unspecified_bool_type() const { return _str; } + const uint8_t *udata() const { return _str.udata(); } + int length() const { return _str.length(); } + + static inline uint16_t u16(const unsigned char* s); + static inline uint16_t u16_aligned(const unsigned char* s); + static inline int16_t s16(const unsigned char* s); + static inline int16_t s16_aligned(const unsigned char* s); + static inline uint32_t u32(const unsigned char* s); + static inline uint32_t u32_aligned16(const unsigned char* s); + static inline uint32_t u32_aligned(const unsigned char* s); + static inline int32_t s32(const unsigned char* s); + static inline int32_t s32_aligned16(const unsigned char* s); + static inline int32_t s32_aligned(const unsigned char* s); + + inline uint8_t operator[](unsigned offset) const throw (Bounds); + inline uint16_t u16(unsigned offset) const throw (Bounds); + inline int16_t s16(unsigned offset) const throw (Bounds); + inline uint32_t u32(unsigned offset) const throw (Bounds); + inline int32_t s32(unsigned offset) const throw (Bounds); + inline uint8_t operator[](int offset) const throw (Bounds); + inline uint16_t u16(int offset) const throw (Bounds); + inline int16_t s16(int offset) const throw (Bounds); + inline uint32_t u32(int offset) const throw (Bounds); + inline int32_t s32(int offset) const throw (Bounds); + + Data subtable(unsigned offset) const throw (Bounds); + Data offset_subtable(unsigned offset_offset) const throw (Bounds); + inline Data substring(int left, int len = -1) const throw (); + + void align_long() { _str.align(4); } + + private: + + String _str; + +}; + +inline uint8_t Data::operator[](unsigned offset) const throw (Bounds) { + if (offset >= static_cast<unsigned>(_str.length())) + throw Bounds(); + else + return _str[offset]; +} + +inline uint16_t Data::u16(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohs(*reinterpret_cast<const uint16_t*>(s)); +#else + return (s[0] << 8) + s[1]; +#endif +} + +inline uint16_t Data::u16_aligned(const unsigned char* s) { + efont_precondition((reinterpret_cast<uintptr_t>(s) & 1) == 0); + return ntohs(*reinterpret_cast<const uint16_t*>(s)); +} + +inline int16_t Data::s16(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohs(*reinterpret_cast<const int16_t*>(s)); +#else + return (int16_t) ((s[0] << 8) + s[1]); +#endif +} + +inline int16_t Data::s16_aligned(const unsigned char* s) { + efont_precondition((reinterpret_cast<uintptr_t>(s) & 1) == 0); + return ntohs(*reinterpret_cast<const int16_t*>(s)); +} + +inline uint32_t Data::u32(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohl(*reinterpret_cast<const uint32_t*>(s)); +#else + return (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; +#endif +} + +inline uint32_t Data::u32_aligned16(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohl(*reinterpret_cast<const uint32_t*>(s)); +#else + efont_precondition((reinterpret_cast<uintptr_t>(s) & 1) == 0); + return (u16_aligned(s) << 16) + u16_aligned(s + 2); +#endif +} + +inline uint32_t Data::u32_aligned(const unsigned char* s) { + efont_precondition((reinterpret_cast<uintptr_t>(s) & 3) == 0); + return ntohl(*reinterpret_cast<const uint32_t*>(s)); +} + +inline int32_t Data::s32(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohl(*reinterpret_cast<const int32_t*>(s)); +#else + return (int32_t) ((s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); +#endif +} + +inline int32_t Data::s32_aligned16(const unsigned char* s) { +#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT + return ntohl(*reinterpret_cast<const int32_t*>(s)); +#else + efont_precondition((reinterpret_cast<uintptr_t>(s) & 1) == 0); + return (int32_t) ((u16_aligned(s) << 16) + u16_aligned(s + 2)); +#endif +} + +inline int32_t Data::s32_aligned(const unsigned char* s) { + efont_precondition((reinterpret_cast<uintptr_t>(s) & 3) == 0); + return ntohl(*reinterpret_cast<const int32_t*>(s)); +} + +inline uint16_t Data::u16(unsigned offset) const throw (Bounds) { + if (offset + 1 >= static_cast<unsigned>(_str.length()) || offset + 1 == 0) + throw Bounds(); + else + return u16_aligned(_str.udata() + offset); +} + +inline int16_t Data::s16(unsigned offset) const throw (Bounds) { + if (offset + 1 >= static_cast<unsigned>(_str.length()) || offset + 1 == 0) + throw Bounds(); + else + return s16_aligned(_str.udata() + offset); +} + +inline uint32_t Data::u32(unsigned offset) const throw (Bounds) { + if (offset + 3 >= static_cast<unsigned>(_str.length()) || offset + 3 < 3) + throw Bounds(); + else + return u32_aligned16(_str.udata() + offset); +} + +inline int32_t Data::s32(unsigned offset) const throw (Bounds) { + if (offset + 3 >= static_cast<unsigned>(_str.length()) || offset + 3 < 3) + throw Bounds(); + else + return s32_aligned16(_str.udata() + offset); +} + +inline uint8_t Data::operator[](int offset) const throw (Bounds) { + return (*this)[unsigned(offset)]; +} + +inline uint16_t Data::u16(int offset) const throw (Bounds) { + return u16(unsigned(offset)); +} + +inline int16_t Data::s16(int offset) const throw (Bounds) { + return s16(unsigned(offset)); +} + +inline uint32_t Data::u32(int offset) const throw (Bounds) { + return u32(unsigned(offset)); +} + +inline int32_t Data::s32(int offset) const throw (Bounds) { + return s32(unsigned(offset)); +} + +inline Data Data::substring(int left, int len) const throw () { + return Data(_str.substring(left, len)); +} + +} // namespace Efont::OpenType +} // namespace Efont +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh new file mode 100644 index 00000000000..ec5573cb964 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh @@ -0,0 +1,249 @@ +// -*- related-file-name: "../../libefont/otfgpos.cc" -*- +#ifndef EFONT_OTFGPOS_HH +#define EFONT_OTFGPOS_HH +#include <efont/otf.hh> +#include <efont/otfdata.hh> +namespace Efont { namespace OpenType { +class GposLookup; +class Positioning; + +class Gpos { public: + + Gpos(const Data &, ErrorHandler * = 0) throw (Error); + // default destructor + + const ScriptList &script_list() const { return _script_list; } + const FeatureList &feature_list() const { return _feature_list; } + + int nlookups() const; + GposLookup lookup(unsigned) const; + + enum { HEADERSIZE = 10 }; + + private: + + ScriptList _script_list; + FeatureList _feature_list; + Data _lookup_list; + +}; + +class GposLookup { public: + GposLookup(const Data &) throw (Error); + int type() const { return _type; } + uint16_t flags() const { return _d.u16(2); } + bool unparse_automatics(Vector<Positioning> &, ErrorHandler * = 0) const; + enum { + HEADERSIZE = 6, RECSIZE = 2, + L_SINGLE = 1, L_PAIR = 2, L_CURSIVE = 3, L_MARKTOBASE = 4, + L_MARKTOLIGATURE = 5, L_MARKTOMARK = 6, L_CONTEXT = 7, + L_CHAIN = 8, L_EXTENSION = 9 + }; + private: + Data _d; + int _type; + Data subtable(int i) const; +}; + +class GposValue { public: + static inline int size(uint16_t format); + static inline int16_t xplacement(uint16_t format, const Data &); + static inline int16_t yplacement(uint16_t format, const Data &); + static inline int16_t xadvance(uint16_t format, const Data &); + static inline int16_t yadvance(uint16_t format, const Data &); + enum { + F_XPLACEMENT = 0x0001, + F_YPLACEMENT = 0x0002, + F_XADVANCE = 0x0004, + F_YADVANCE = 0x0008, + F_XPLACEMENT_DEVICE = 0x0010, + F_YPLACEMENT_DEVICE = 0x0020, + F_XADVANCE_DEVICE = 0x0040, + F_YADVANCE_DEVICE = 0x0080 + }; + private: + static const int nibble_bitcount_x2[]; +}; + +class GposSingle { public: + GposSingle(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + void unparse(Vector<Positioning> &) const; + enum { F2_HEADERSIZE = 8 }; + private: + Data _d; +}; + +class GposPair { public: + GposPair(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + void unparse(Vector<Positioning> &) const; + enum { F1_HEADERSIZE = 10, F1_RECSIZE = 2, + PAIRSET_HEADERSIZE = 2, PAIRVALUE_HEADERSIZE = 2, + F2_HEADERSIZE = 16 }; + private: + Data _d; +}; + +struct Position { + Glyph g; + int pdx, pdy; // placement + int adx, ady; // advance + inline Position(); + inline Position(Glyph, uint16_t format, const Data &); + inline Position(uint16_t format, const Data &); + inline Position(Glyph, const Position &); + inline Position(Glyph g, int pdx, int pdy, int adx, int ady); + bool empty() const { return pdx == 0 && pdy == 0 && adx == 0 && ady == 0; } + operator bool() const { return !empty(); } + bool h_empty() const { return pdx == 0 && pdy == 0 && adx == 0; } + bool placed() const { return pdx != 0 || pdy != 0; } + void unparse(StringAccum &, const Vector<PermString> * = 0) const; + String unparse(const Vector<PermString> * = 0) const; +}; + +class Positioning { public: + + Positioning(); + + // single positioning + inline Positioning(const Position &); + + // pair positioning + inline Positioning(const Position &, const Position &); + + bool context_in(const Coverage &) const; + bool context_in(const GlyphSet &) const; + + // types + inline operator bool() const; + inline bool is_single() const; + inline bool is_pair() const; + inline bool is_pairkern() const; + + // extract data + const Position &left() const { return _left; } + Glyph left_glyph() const { return _left.g; } + const Position &right() const { return _right; } + Glyph right_glyph() const { return _right.g; } + inline void all_in_glyphs(Vector<Glyph> &gs) const; + + void unparse(StringAccum &, const Vector<PermString> * = 0) const; + String unparse(const Vector<PermString> * = 0) const; + + private: + + Position _left; + Position _right; + +}; + +inline int GposValue::size(uint16_t format) +{ + return (nibble_bitcount_x2[format & 15] + nibble_bitcount_x2[(format>>4) & 15]); +} + +inline int16_t GposValue::xplacement(uint16_t format, const Data &d) +{ + if (format & F_XPLACEMENT) + return d.s16(0); + else + return 0; +} + +inline int16_t GposValue::yplacement(uint16_t format, const Data &d) +{ + if (format & F_YPLACEMENT) + return d.s16((format & F_XPLACEMENT ? 2 : 0)); + else + return 0; +} + +inline int16_t GposValue::xadvance(uint16_t format, const Data &d) +{ + if (format & F_XADVANCE) + return d.s16(nibble_bitcount_x2[format & (F_XADVANCE - 1)]); + else + return 0; +} + +inline int16_t GposValue::yadvance(uint16_t format, const Data &d) +{ + if (format & F_YADVANCE) + return d.s16(nibble_bitcount_x2[format & (F_YADVANCE - 1)]); + else + return 0; +} + +inline Position::Position() + : g(0) +{ +} + +inline Position::Position(Glyph g_, uint16_t format, const Data &value) + : g(g_), + pdx(GposValue::xplacement(format, value)), pdy(GposValue::yplacement(format, value)), + adx(GposValue::xadvance(format, value)), ady(GposValue::yadvance(format, value)) +{ +} + +inline Position::Position(uint16_t format, const Data &value) + : g(0), + pdx(GposValue::xplacement(format, value)), pdy(GposValue::yplacement(format, value)), + adx(GposValue::xadvance(format, value)), ady(GposValue::yadvance(format, value)) +{ +} + +inline Position::Position(Glyph g_, const Position &p) + : g(g_), pdx(p.pdx), pdy(p.pdy), adx(p.adx), ady(p.ady) +{ +} + +inline Position::Position(Glyph g_, int pdx_, int pdy_, int adx_, int ady_) + : g(g_), pdx(pdx_), pdy(pdy_), adx(adx_), ady(ady_) +{ +} + +inline Positioning::Positioning(const Position &left) + : _left(left) +{ +} + +inline Positioning::Positioning(const Position &left, const Position &right) + : _left(left), _right(right) +{ +} + +inline Positioning::operator bool() const +{ + return _left.g != 0; +} + +inline bool Positioning::is_single() const +{ + return _left.g != 0 && _right.g == 0; +} + +inline bool Positioning::is_pair() const +{ + return _left.g != 0 && _right.g != 0; +} + +inline bool Positioning::is_pairkern() const +{ + return _left.g != 0 && !_left.placed() && _right.g != 0 && _right.h_empty(); +} + +inline void Positioning::all_in_glyphs(Vector<Glyph> &gs) const +{ + gs.clear(); + if (_left.g != 0) + gs.push_back(_left.g); + if (_right.g != 0) + gs.push_back(_right.g); +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh new file mode 100644 index 00000000000..383389e5895 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh @@ -0,0 +1,415 @@ +// -*- related-file-name: "../../libefont/otfgsub.cc" -*- +#ifndef EFONT_OTFGSUB_HH +#define EFONT_OTFGSUB_HH +#include <efont/otf.hh> +#include <efont/otfdata.hh> +namespace Efont { namespace OpenType { +class GsubLookup; +class Substitution; + +class Gsub { public: + + Gsub(const Data &, const Font *, ErrorHandler * = 0) throw (Error); + // default destructor + + const ScriptList &script_list() const { return _script_list; } + const FeatureList &feature_list() const { return _feature_list; } + bool chaincontext_reverse_backtrack() const { return _chaincontext_reverse_backtrack; } + + int nlookups() const; + GsubLookup lookup(unsigned) const; + + enum { HEADERSIZE = 10 }; + + private: + + ScriptList _script_list; + FeatureList _feature_list; + Data _lookup_list; + bool _chaincontext_reverse_backtrack; + +}; + +class GsubLookup { public: + GsubLookup(const Data &) throw (Error); + int type() const { return _type; } + uint16_t flags() const { return _d.u16(2); } + void mark_out_glyphs(const Gsub &gsub, Vector<bool> &gmap) const; + bool unparse_automatics(const Gsub &gsub, Vector<Substitution> &subs, const Coverage &limit) const; + bool apply(const Glyph *, int pos, int n, Substitution &) const; + enum { + HEADERSIZE = 6, RECSIZE = 2, + L_SINGLE = 1, L_MULTIPLE = 2, L_ALTERNATE = 3, L_LIGATURE = 4, + L_CONTEXT = 5, L_CHAIN = 6, L_EXTENSION = 7, L_REVCHAIN = 8 + }; + private: + Data _d; + int _type; + Data subtable(int i) const; +}; + +class GsubSingle { public: + GsubSingle(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + Glyph map(Glyph) const; + void mark_out_glyphs(Vector<bool> &gmap) const; + void unparse(Vector<Substitution> &subs, const Coverage &limit) const; + bool apply(const Glyph *, int pos, int n, Substitution &) const; + enum { HEADERSIZE = 6, FORMAT2_RECSIZE = 2 }; + private: + Data _d; +}; + +class GsubMultiple { public: + GsubMultiple(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + bool map(Glyph, Vector<Glyph> &) const; + void mark_out_glyphs(Vector<bool> &gmap) const; + void unparse(Vector<Substitution> &, bool alternate = false) const; + bool apply(const Glyph *, int pos, int n, Substitution &, bool alternate = false) const; + enum { HEADERSIZE = 6, RECSIZE = 2, + SEQ_HEADERSIZE = 2, SEQ_RECSIZE = 2 }; + private: + Data _d; +}; + +class GsubLigature { public: + GsubLigature(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + bool map(const Vector<Glyph> &, Glyph &, int &) const; + void mark_out_glyphs(Vector<bool> &gmap) const; + void unparse(Vector<Substitution> &) const; + bool apply(const Glyph *, int pos, int n, Substitution &) const; + enum { HEADERSIZE = 6, RECSIZE = 2, + SET_HEADERSIZE = 2, SET_RECSIZE = 2, + LIG_HEADERSIZE = 4, LIG_RECSIZE = 2 }; + private: + Data _d; +}; + +class GsubContext { public: + GsubContext(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + void mark_out_glyphs(const Gsub &gsub, Vector<bool> &gmap) const; + bool unparse(const Gsub &gsub, Vector<Substitution> &out_subs, const Coverage &limit) const; + enum { F3_HSIZE = 6, SUBRECSIZE = 4 }; + private: + Data _d; + static void subruleset_mark_out_glyphs(const Data &data, int nsub, int subtab_offset, const Gsub &gsub, Vector<bool> &gmap); + static bool f1_unparse(const Data& data, + int nsub, int subtab_offset, + const Gsub& gsub, Vector<Substitution>& outsubs, + Substitution prototype_sub); + static bool f3_unparse(const Data &data, + int nglyph, int glyphtab_offset, const Coverage &limit, + int nsub, int subtab_offset, + const Gsub &gsub, Vector<Substitution> &outsubs, + const Substitution &prototype_sub); + friend class GsubChainContext; +}; + +class GsubChainContext { public: + GsubChainContext(const Data &) throw (Error); + // default destructor + Coverage coverage() const throw (); + void mark_out_glyphs(const Gsub &gsub, Vector<bool> &gmap) const; + bool unparse(const Gsub &gsub, Vector<Substitution> &subs, const Coverage &limit) const; + enum { F1_HEADERSIZE = 6, F1_RECSIZE = 2, + F1_SRS_HSIZE = 2, F1_SRS_RSIZE = 2, + F3_HSIZE = 4, F3_INPUT_HSIZE = 2, F3_LOOKAHEAD_HSIZE = 2, F3_SUBST_HSIZE = 2 }; + private: + Data _d; + bool f1_unparse(const Gsub &gsub, Vector<Substitution> &subs, const Coverage &limit) const; + bool f3_unparse(const Gsub &gsub, Vector<Substitution> &subs, const Coverage &limit) const; +}; + +class Substitution { public: + + Substitution(); + Substitution(const Substitution &); + + // single substitution + Substitution(Glyph in, Glyph out); + + // multiple substitution + Substitution(Glyph in, const Vector<Glyph> &out, bool is_alternate = false); + + // ligature substitution + Substitution(Glyph in1, Glyph in2, Glyph out); + Substitution(const Vector<Glyph> &in, Glyph out); + Substitution(int nin, const Glyph *in, Glyph out); + + // space + Substitution(int nleft, int nin, int nout, int nright); + + ~Substitution(); + + Substitution &operator=(const Substitution &); + + bool context_in(const Coverage &) const; + bool context_in(const GlyphSet &) const; + + // types + inline operator bool() const; + bool is_noop() const; + inline bool is_single() const; + inline bool is_multiple() const; + inline bool is_alternate() const; + inline bool is_ligature() const; + inline bool is_simple_context() const; + inline bool is_single_lcontext() const; + inline bool is_single_rcontext() const; + inline bool is_lcontext() const; + inline bool is_rcontext() const; + + // extract data + inline Glyph left_glyph() const; + inline int left_nglyphs() const; + inline Glyph *left_glyphptr(); + inline const Glyph *left_glyphptr() const; + + inline Glyph in_glyph() const; + inline Glyph in_glyph(int pos) const; + inline bool in_glyphs(Vector<Glyph> &) const; + inline int in_nglyphs() const; + inline Glyph *in_glyphptr(); + inline const Glyph *in_glyphptr() const; + + inline bool in_matches(int pos, Glyph) const; + + inline Glyph out_glyph() const; + inline Glyph out_glyph(int pos) const; + inline bool out_glyphs(Vector<Glyph> &) const; + inline Glyph *out_glyphptr(); + inline const Glyph *out_glyphptr() const; + + inline int out_nglyphs() const; + inline Glyph right_glyph() const; + inline Glyph *right_glyphptr(); + inline const Glyph *right_glyphptr() const; + + bool all_in_glyphs(Vector<Glyph> &gs) const; + bool all_out_glyphs(Vector<Glyph> &gs) const; + + // alter + void add_outer_left(Glyph); + void remove_outer_left(); + Substitution in_out_append_glyph(Glyph) const; + bool out_alter(const Substitution &, int) throw (); + void add_outer_right(Glyph); + void remove_outer_right(); + + void unparse(StringAccum &, const Vector<PermString> * = &debug_glyph_names) const; + String unparse(const Vector<PermString> * = &debug_glyph_names) const; + + private: + + enum { T_NONE = 0, T_GLYPH, T_GLYPHS, T_COVERAGE }; + typedef union { + Glyph gid; + Glyph *gids; // first entry is a count + Coverage *coverage; + } Substitute; + + Substitute _left; + Substitute _in; + Substitute _out; + Substitute _right; + + uint8_t _left_is; + uint8_t _in_is; + uint8_t _out_is; + uint8_t _right_is; + + bool _alternate : 1; + + static void clear(Substitute &, uint8_t &); + static void assign_space(Substitute &, uint8_t &, int); + static void assign(Substitute &, uint8_t &, Glyph); + static void assign(Substitute &, uint8_t &, int, const Glyph *); + static void assign(Substitute &, uint8_t &, const Coverage &); + static void assign(Substitute &, uint8_t &, const Substitute &, uint8_t); + static void assign_append(Substitute &, uint8_t &, const Substitute &, uint8_t, const Substitute &, uint8_t); + static void assign_append(Substitute &, uint8_t &, const Substitute &, uint8_t, Glyph); + static bool substitute_in(const Substitute &, uint8_t, const Coverage &); + static bool substitute_in(const Substitute &, uint8_t, const GlyphSet &); + + static Glyph extract_glyph(const Substitute &, uint8_t) throw (); + static Glyph extract_glyph(const Substitute &, int which, uint8_t) throw (); + static bool extract_glyphs(const Substitute &, uint8_t, Vector<Glyph> &, bool coverage_ok) throw (); + static Glyph *extract_glyphptr(const Substitute &, uint8_t) throw (); + static int extract_nglyphs(const Substitute &, uint8_t, bool coverage_ok) throw (); + static bool matches(const Substitute &, uint8_t, int pos, Glyph) throw (); + + static void unparse_glyphids(StringAccum &, const Substitute &, uint8_t, const Vector<PermString> *) throw (); + +}; + +inline Substitution::Substitution() + : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_NONE), _right_is(T_NONE) +{ +} + +/* Single 1: u16 format, offset coverage, u16 glyphdelta + Single 2: u16 format, offset coverage, u16 count, glyph subst[] + Multiple 1: u16 format, offset coverage, u16 count, offset sequence[]; + sequence is: u16 count, glyph subst[] + Alternate 1: u16 format, offset coverage, u16 count, offset alternates[]; + alternate is: u16 count, glyph alts[] + Ligature 1: u16 format, offset coverage, u16 count, offset sets[]; + set is: u16 count, offset ligatures[]; + ligature is: glyph result, u16 count, glyph components[] +*/ + +inline Substitution::operator bool() const +{ + return !(_left_is == T_NONE && _in_is == T_NONE && _out_is == T_NONE && _right_is == T_NONE); +} + +inline bool Substitution::is_single() const +{ + return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_NONE; +} + +inline bool Substitution::is_multiple() const +{ + return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPHS && _right_is == T_NONE && !_alternate; +} + +inline bool Substitution::is_alternate() const +{ + return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPHS && _right_is == T_NONE && _alternate; +} + +inline bool Substitution::is_ligature() const +{ + return _left_is == T_NONE && _in_is == T_GLYPHS && _out_is == T_GLYPH && _right_is == T_NONE; +} + +inline bool Substitution::is_simple_context() const +{ + return _left_is != T_COVERAGE && (_in_is == T_GLYPH || _in_is == T_GLYPHS) && (_out_is == T_GLYPH || _out_is == T_GLYPHS) && _right_is != T_COVERAGE; +} + +inline bool Substitution::is_single_lcontext() const +{ + return _left_is == T_GLYPH && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_NONE; +} + +inline bool Substitution::is_single_rcontext() const +{ + return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_GLYPH; +} + +inline Glyph Substitution::left_glyph() const +{ + return extract_glyph(_left, _left_is); +} + +inline int Substitution::left_nglyphs() const +{ + return extract_nglyphs(_left, _left_is, false); +} + +inline Glyph Substitution::in_glyph() const +{ + return extract_glyph(_in, _in_is); +} + +inline Glyph Substitution::in_glyph(int which) const +{ + return extract_glyph(_in, which, _in_is); +} + +inline bool Substitution::in_glyphs(Vector<Glyph> &v) const +{ + return extract_glyphs(_in, _in_is, v, true); +} + +inline int Substitution::in_nglyphs() const +{ + return extract_nglyphs(_in, _in_is, true); +} + +inline bool Substitution::in_matches(int pos, Glyph g) const +{ + return matches(_in, _in_is, pos, g); +} + +inline Glyph Substitution::out_glyph() const +{ + return extract_glyph(_out, _out_is); +} + +inline Glyph Substitution::out_glyph(int which) const +{ + return extract_glyph(_out, which, _out_is); +} + +inline bool Substitution::out_glyphs(Vector<Glyph> &v) const +{ + return extract_glyphs(_out, _out_is, v, false); +} + +inline int Substitution::out_nglyphs() const +{ + return extract_nglyphs(_out, _out_is, false); +} + +inline Glyph Substitution::right_glyph() const +{ + return extract_glyph(_right, _right_is); +} + +inline const Glyph *Substitution::left_glyphptr() const +{ + return extract_glyphptr(_left, _left_is); +} + +inline Glyph *Substitution::left_glyphptr() +{ + return extract_glyphptr(_left, _left_is); +} + +inline const Glyph *Substitution::in_glyphptr() const +{ + return extract_glyphptr(_in, _in_is); +} + +inline Glyph *Substitution::in_glyphptr() +{ + return extract_glyphptr(_in, _in_is); +} + +inline const Glyph *Substitution::out_glyphptr() const +{ + return extract_glyphptr(_out, _out_is); +} + +inline Glyph *Substitution::out_glyphptr() +{ + return extract_glyphptr(_out, _out_is); +} + +inline const Glyph *Substitution::right_glyphptr() const +{ + return extract_glyphptr(_right, _right_is); +} + +inline Glyph *Substitution::right_glyphptr() +{ + return extract_glyphptr(_right, _right_is); +} + +inline StringAccum &operator<<(StringAccum &sa, const Substitution &sub) +{ + sub.unparse(sa); + return sa; +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfname.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfname.hh new file mode 100644 index 00000000000..692354f0f97 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfname.hh @@ -0,0 +1,122 @@ +// -*- related-file-name: "../../libefont/otfname.cc" -*- +#ifndef EFONT_OTFNAME_HH +#define EFONT_OTFNAME_HH +#include <efont/otf.hh> +#include <efont/otfdata.hh> // for ntohl() +#include <lcdf/error.hh> +namespace Efont { namespace OpenType { + +class Name { public: + + Name(const String &, ErrorHandler * = 0); + // default destructor + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + enum NameID { N_COPYRIGHT = 0, N_FAMILY = 1, N_SUBFAMILY = 2, + N_UNIQUEID = 3, N_FULLNAME = 4, N_VERSION = 5, + N_POSTSCRIPT = 6, N_TRADEMARK = 7, N_MANUFACTURER = 8, + N_DESIGNER = 9, N_DESCRIPTION = 10, N_VENDOR_URL = 11, + N_DESIGNER_URL = 12, N_LICENSE_DESCRIPTION = 13, + N_LICENSE_URL = 14, N_PREF_FAMILY = 16, + N_PREF_SUBFAMILY = 17, N_MAC_COMPAT_FULLNAME = 18, + N_SAMPLE_TEXT = 19, N_POSTSCRIPT_CID = 20 }; + enum Platform { P_UNICODE = 0, P_MACINTOSH = 1, P_MICROSOFT = 3, + E_MS_UNICODE_BMP = 1, E_MAC_ROMAN = 0, + L_MS_ENGLISH_AMERICAN = 0x409 }; + enum { HEADER_SIZE = 6, NAMEREC_SIZE = 12 }; + + typedef uint8_t namerecord_t[NAMEREC_SIZE]; + typedef const namerecord_t *const_iterator; + + inline static int nameid(const namerecord_t &); + inline static int platform(const namerecord_t &); + inline static int encoding(const namerecord_t &); + inline static int language(const namerecord_t &); + + inline const_iterator begin() const; + inline const_iterator end() const; + String name(const_iterator) const; + String utf8_name(const_iterator) const; + String english_name(int nameid) const; + + // check version string for backwards compatibility + bool version_chaincontext_reverse_backtrack() const; + + struct PlatformPred { + inline PlatformPred(int nameid, int platform = -1, int encoding = -1, int language = -1); + inline bool operator()(const namerecord_t &) const; + private: + int _nameid, _platform, _encoding, _language; + }; + + struct EnglishPlatformPred { + EnglishPlatformPred(int nameid) : _nameid(nameid) { } + inline bool operator()(const namerecord_t &) const; + private: + int _nameid; + }; + + private: + + String _str; + int _error; + + int parse_header(ErrorHandler *); + +}; + + +inline int Name::nameid(const namerecord_t &nr) { + return Data::u16_aligned(reinterpret_cast<const unsigned char*>(&nr) + 6); +} + +inline int Name::platform(const namerecord_t &nr) { + return Data::u16_aligned(reinterpret_cast<const unsigned char*>(&nr)); +} + +inline int Name::encoding(const namerecord_t &nr) { + return Data::u16_aligned(reinterpret_cast<const unsigned char*>(&nr) + 2); +} + +inline int Name::language(const namerecord_t &nr) { + return Data::u16_aligned(reinterpret_cast<const unsigned char*>(&nr) + 4); +} + +inline Name::const_iterator Name::begin() const { + return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE); +} + +inline Name::const_iterator Name::end() const { + if (_error >= 0) { + int count = Data::u16_aligned(_str.udata() + 2); + return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE + NAMEREC_SIZE * count); + } else + return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE); +} + + +inline Name::PlatformPred::PlatformPred(int nid, int p, int e, int l) + : _nameid(nid), _platform(p), _encoding(e), _language(l) { +} + +inline bool Name::PlatformPred::operator()(const namerecord_t &i) const { + return (_nameid == nameid(i)) + && (_platform < 0 || _platform == platform(i)) + && (_encoding < 0 || _encoding == encoding(i)) + && (_language < 0 || _language == language(i)); +} + +inline bool Name::EnglishPlatformPred::operator()(const namerecord_t &i) const { + if (_nameid == nameid(i)) { + int p = platform(i), e = encoding(i), l = language(i); + return (p == P_MACINTOSH && e == E_MAC_ROMAN && l == 0) + || (p == P_MICROSOFT && e == E_MS_UNICODE_BMP && l == L_MS_ENGLISH_AMERICAN); + } else + return false; +} + +} // namespace Efont::OpenType +} // namespace Efont +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh new file mode 100644 index 00000000000..30eaaef1a83 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh @@ -0,0 +1,94 @@ +// -*- related-file-name: "../../libefont/otfos2.cc" -*- +#ifndef EFONT_OTFOS2_HH +#define EFONT_OTFOS2_HH +#include <efont/otf.hh> +#include <efont/otfdata.hh> +#include <lcdf/error.hh> +namespace Efont { namespace OpenType { + +class Os2 { public: + + Os2(const Data &, ErrorHandler * = 0); + // default destructor + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + enum Offsets { O_AVGCHARWIDTH = 2, O_SUBSCRIPTXSIZE = 10, + O_SUBSCRIPTYSIZE = 12, O_SUBSCRIPTXOFFSET = 14, + O_SUBSCRIPTYOFFSET = 16, O_SUPERSCRIPTXSIZE = 18, + O_SUPERSCRIPTYSIZE = 20, O_SUPERSCRIPTXOFFSET = 22, + O_SUPERSCRIPTYOFFSET = 24, O_STRIKEOUTSIZE = 26, + O_STRIKEOUTPOSITION = 28, O_VENDORID = 58, + O_TYPOASCENDER = 68, O_TYPODESCENDER = 70, + O_TYPOLINEGAP = 72, O_XHEIGHT = 86, O_CAPHEIGHT = 88, + O_LOWEROPTICALPOINTSIZE = 96, O_UPPEROPTICALPOINTSIZE = 98 }; + enum { HEADER_SIZE = 2 }; + + inline int16_t typo_ascender() const throw (Bounds); + inline int16_t typo_descender() const throw (Bounds); + inline int16_t typo_line_gap() const throw (Bounds); + inline int16_t x_height() const throw (Bounds); + inline int16_t cap_height() const throw (Bounds); + inline double lower_optical_point_size() const throw (Bounds); + inline double upper_optical_point_size() const throw (Bounds); + inline bool has_optical_point_size() const throw (); + inline String vendor_id() const throw (); + + private: + + Data _data; + int _error; + + int parse_header(ErrorHandler *); + +}; + + +inline int16_t Os2::typo_ascender() const throw (Bounds) +{ + return _data.s16(O_TYPOASCENDER); +} + +inline int16_t Os2::typo_descender() const throw (Bounds) +{ + return _data.s16(O_TYPODESCENDER); +} + +inline int16_t Os2::typo_line_gap() const throw (Bounds) +{ + return _data.s16(O_TYPOLINEGAP); +} + +inline int16_t Os2::x_height() const throw (Bounds) +{ + return _data.s16(O_XHEIGHT); +} + +inline int16_t Os2::cap_height() const throw (Bounds) +{ + return _data.s16(O_CAPHEIGHT); +} + +inline double Os2::lower_optical_point_size() const throw (Bounds) +{ + return _data.u16(O_LOWEROPTICALPOINTSIZE) / 20.; +} + +inline double Os2::upper_optical_point_size() const throw (Bounds) +{ + return _data.u16(O_UPPEROPTICALPOINTSIZE) / 20.; +} + +inline bool Os2::has_optical_point_size() const throw () +{ + return _data.length() >= O_UPPEROPTICALPOINTSIZE + 2; +} + +inline String Os2::vendor_id() const throw () +{ + return _data.substring(O_VENDORID, 4).string(); +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfpost.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfpost.hh new file mode 100644 index 00000000000..57564efc6a3 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfpost.hh @@ -0,0 +1,62 @@ +// -*- related-file-name: "../../libefont/otfpost.cc" -*- +#ifndef EFONT_OTFPOST_HH +#define EFONT_OTFPOST_HH +#include <efont/otfdata.hh> +#include <lcdf/error.hh> +namespace Efont { namespace OpenType { + +class Post { public: + + Post(const String &, ErrorHandler * = 0); + // default destructor + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + double italic_angle() const; + bool is_fixed_pitch() const; + inline int underline_position() const; + inline int underline_thickness() const; + inline uint32_t mem_type42(bool ismax) const; + int nglyphs() const { return _nglyphs; } + bool glyph_names(Vector<PermString> &gnames) const; + + private: + + Data _str; + int _error; + uint32_t _version; + int _nglyphs; + Vector<int> _extend_glyph_names; + + enum { HEADER_SIZE = 32, N_MAC_GLYPHS = 258 }; + int parse_header(ErrorHandler *); + +}; + +inline int +Post::underline_position() const +{ + // NB: "This is the suggested distance of the top of the underline from + // the baseline (negative values indicate below baseline). The PostScript + // definition of this FontInfo dictionary key (the y coordinate of the + // center of the stroke) is not used for historical reasons. The value of + // the PostScript key may be calculated by subtracting half the + // underlineThickness from the value of this field." -- OpenType spec + return ok() ? _str.s16(8) : 0; +} + +inline int +Post::underline_thickness() const +{ + return ok() ? _str.s16(10) : 0; +} + +inline uint32_t +Post::mem_type42(bool ismax) const +{ + return ok() ? _str.u32(ismax ? 20 : 16) : 0; +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/pairop.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/pairop.hh new file mode 100644 index 00000000000..360912a00d1 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/pairop.hh @@ -0,0 +1,113 @@ +// -*- related-file-name: "../../libefont/pairop.cc" -*- +#ifndef PAIROP_HH +#define PAIROP_HH +#include <efont/encoding.hh> /* get GlyphIndex */ +namespace Efont { + +enum PairOpDefs { + + opNoop = -1, + opLigature = -2, + + opLigSimple = 0, + opLigSaveLeft = 1, + opLigSaveRight = 2, + opLigPast1 = 4, + opLigPast2 = 8, + + opAllblock = 0 + +}; + + +typedef int PairOpIndex; + + +class PairOp { public: + + PairOp() { } + inline PairOp(GlyphIndex l, GlyphIndex r, int v, PairOpIndex nl); + inline PairOp(GlyphIndex l, GlyphIndex r, GlyphIndex x, int kind, PairOpIndex nl); + + void noopify() { _val = opNoop; } + void set_value(int val) { _val = val; } + + inline void set_next(PairOpIndex); + + bool is_lig() const { return _val <= opLigature; } + bool is_kern() const { return _val >= 0; } + bool is_noop() const { return _val == opNoop; } + int lig_kind() const { assert(is_lig()); return -_val+opLigature; } + + GlyphIndex left() const { return _left; } + GlyphIndex right() const { return _right; } + GlyphIndex result() const { assert(is_lig()); return _result; } + int value() const { return _val; } + PairOpIndex next_left() const { return _next_left; } + + private: + + GlyphIndex _left; + GlyphIndex _right; + GlyphIndex _result; + int _val; + + PairOpIndex _next_left; + +}; + + +class PairProgram { public: + + PairProgram() : _reversed(false) { } + PairProgram(const PairProgram &); + + void reserve_glyphs(int); + + PairOpIndex find_left(GlyphIndex gi) const { return _left_map[gi]; } + PairOpIndex find(GlyphIndex leftgi, GlyphIndex rightgi) const; + + int op_count() const { return _op.size(); } + const PairOp &op(PairOpIndex i) const { return _op[i]; } + + // Return true if it's a duplicate. + bool add_kern(GlyphIndex, GlyphIndex, int); + bool add_lig(GlyphIndex, GlyphIndex, GlyphIndex, int kind = opLigSimple); + + void set_reversed(bool r) { _reversed = r; } + void unreverse(); + void optimize(); + + void print() const; + + private: + + bool _reversed; + Vector<PairOpIndex> _left_map; + Vector<PairOp> _op; + + inline const char *print_name(GlyphIndex) const; + + PairProgram &operator=(const PairProgram &) { assert(0); return *this; } + +}; + + +inline PairOp::PairOp(GlyphIndex l, GlyphIndex r, int v, PairOpIndex nl) + : _left(l), _right(r), _result(), _val(v), _next_left(nl) +{ +} + +inline PairOp::PairOp(GlyphIndex l, GlyphIndex r, GlyphIndex x, int kind, + PairOpIndex nl) + : _left(l), _right(r), _result(x), _val(opLigature - kind), _next_left(nl) +{ +} + +inline void PairOp::set_next(PairOpIndex nl) +{ + _next_left = nl; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/psres.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/psres.hh new file mode 100644 index 00000000000..f33ee8ab0e8 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/psres.hh @@ -0,0 +1,74 @@ +// -*- related-file-name: "../../libefont/psres.cc" -*- +#ifndef EFONT_PSRES_HH +#define EFONT_PSRES_HH +#include <lcdf/vector.hh> +#include <lcdf/hashmap.hh> +#include <lcdf/string.hh> +#include <lcdf/filename.hh> +class Slurper; +namespace Efont { +class PsresDatabaseSection; + +class PsresDatabase { public: + + PsresDatabase(); + ~PsresDatabase(); + + void add_psres_path(const char* path, const char* defaults, bool override); + bool add_psres_file(Filename&, bool override); + void add_database(PsresDatabase*, bool override); + + inline PsresDatabaseSection* section(PermString section) const; + const String& value(PermString section, PermString key) const; + const String& unescaped_value(PermString section, PermString key) const; + Filename filename_value(PermString section, PermString key) const; + + private: + + HashMap<PermString, int> _section_map; + Vector<PsresDatabaseSection*> _sections; + + PsresDatabaseSection* force_section(PermString); + bool add_one_psres_file(Slurper&, bool override); + void add_psres_directory(PermString); + +}; + +class PsresDatabaseSection { public: + + PsresDatabaseSection(PermString); + + PermString section_name() const { return _section_name; } + + void add_psres_file_section(Slurper&, PermString, bool); + void add_section(PsresDatabaseSection*, bool override); + + const String& value(PermString key) { return value(_map[key]); } + inline const String& unescaped_value(PermString key) const; + Filename filename_value(PermString key); + + private: + + PermString _section_name; + HashMap<PermString, int> _map; + Vector<PermString> _directories; + Vector<String> _values; + Vector<int> _value_escaped; + + const String& value(int index); + +}; + +inline PsresDatabaseSection* PsresDatabase::section(PermString n) const +{ + return _sections[_section_map[n]]; +} + +inline const String& PsresDatabaseSection::unescaped_value(PermString key) const +{ + assert(!_value_escaped[_map[key]]); + return _values[_map[key]]; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh new file mode 100644 index 00000000000..1f1addaebc2 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh @@ -0,0 +1,95 @@ +// -*- related-file-name: "../../libefont/t1bounds.cc" -*- +#ifndef EFONT_T1BOUNDS_HH +#define EFONT_T1BOUNDS_HH +#include <efont/t1interp.hh> +#include <lcdf/transform.hh> +namespace Efont { + +class CharstringBounds : public CharstringInterp { public: + + CharstringBounds(); + CharstringBounds(const Transform&); + CharstringBounds(const Transform&, const Vector<double>& weight_vec); + ~CharstringBounds() { } + + const Point& width() const { return _width; } + double x_width() const { return _width.x; } + bool bb_known() const { return KNOWN(_lb.x); } + double bb_left() const { return _lb.x; } + double bb_top() const { return _rt.y; } + double bb_right() const { return _rt.x; } + double bb_bottom() const { return _lb.y; } + const Point& bb_bottom_left() const { return _lb; } + const Point& bb_top_right() const { return _rt; } + + void act_width(int, const Point&); + void act_line(int, const Point&, const Point&); + void act_curve(int, const Point&, const Point&, const Point&, const Point&); + inline void mark(const Point&); + + void clear(); + bool char_bounds(const CharstringContext&, bool shift = true); + void translate(double dx, double dy); + inline Point transform(const Point& p) const; + bool output(double bb[4], double& width, bool use_cur_width = false) const; + + static bool bounds(const CharstringContext&, + double bounds[4], double& width); + static bool bounds(const Transform&, const CharstringContext&, + double bounds[4], double& width); + + private: + + Point _lb; + Point _rt; + Point _width; + Transform _xf; + Transform _nonfont_xf; + const CharstringProgram* _last_xf_program; + + void set_xf(const CharstringProgram*); + + inline void xf_mark(const Point&); + void xf_mark(const Bezier&); + + inline bool xf_inside(const Point&) const; + inline bool xf_controls_inside(const Bezier&) const; + +}; + +inline void CharstringBounds::xf_mark(const Point& p) +{ + if (!KNOWN(_lb.x)) + _lb = _rt = p; + if (p.x < _lb.x) + _lb.x = p.x; + else if (p.x > _rt.x) + _rt.x = p.x; + if (p.y < _lb.y) + _lb.y = p.y; + else if (p.y > _rt.y) + _rt.y = p.y; +} + +inline void CharstringBounds::mark(const Point& p) +{ + xf_mark(p * _xf); +} + +inline bool CharstringBounds::xf_inside(const Point& p) const +{ + return p.x >= _lb.x && p.x <= _rt.x && p.y >= _lb.y && p.y <= _rt.y; +} + +inline bool CharstringBounds::xf_controls_inside(const Bezier& b) const +{ + return xf_inside(b.point(1)) && xf_inside(b.point(2)); +} + +inline Point CharstringBounds::transform(const Point& p) const +{ + return p * _xf; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1cs.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1cs.hh new file mode 100644 index 00000000000..d9f36db6cd9 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1cs.hh @@ -0,0 +1,345 @@ +// -*- related-file-name: "../../libefont/t1cs.cc" -*- +#ifndef EFONT_T1CS_HH +#define EFONT_T1CS_HH +#include <lcdf/permstr.hh> +#include <lcdf/string.hh> +#include <lcdf/vector.hh> +#include <lcdf/inttypes.h> +namespace Efont { + +// Allow unknown doubles to have some `fuzz' -- so if an unknown double +// is a bit off from the canonical UNKDOUBLE value, we'll still recognize +// it as unknown. (Useful for interpolation.) +#define UNKDOUBLE -9.79797e97 +#define MIN_KNOWN_DOUBLE -9.69696e97 +#define KNOWN(d) ((d) >= MIN_KNOWN_DOUBLE) + +class CharstringProgram; +class CharstringInterp; +struct CharstringContext; +class MultipleMasterSpace; +class Type1Encoding; + +class Charstring { public: + + Charstring() { } + virtual ~Charstring(); + + virtual bool process(CharstringInterp &) const = 0; + + enum Commands { + cError = 0, + cHstem = 1, + cVstem = 3, + cVmoveto = 4, + cRlineto = 5, + cHlineto = 6, + cVlineto = 7, + cRrcurveto = 8, + cClosepath = 9, + cCallsubr = 10, + cReturn = 11, + cEscape = 12, + cHsbw = 13, + cEndchar = 14, + cBlend = 16, + cHstemhm = 18, + cHintmask = 19, + cCntrmask = 20, + cRmoveto = 21, + cHmoveto = 22, + cVstemhm = 23, + cRcurveline = 24, + cRlinecurve = 25, + cVvcurveto = 26, + cHhcurveto = 27, + cShortint = 28, + cCallgsubr = 29, + cVhcurveto = 30, + cHvcurveto = 31, + + cEscapeDelta = 32, + cDotsection = 32 + 0, + cVstem3 = 32 + 1, + cHstem3 = 32 + 2, + cAnd = 32 + 3, + cOr = 32 + 4, + cNot = 32 + 5, + cSeac = 32 + 6, + cSbw = 32 + 7, + cStore = 32 + 8, + cAbs = 32 + 9, + cAdd = 32 + 10, + cSub = 32 + 11, + cDiv = 32 + 12, + cLoad = 32 + 13, + cNeg = 32 + 14, + cEq = 32 + 15, + cCallothersubr = 32 + 16, + cPop = 32 + 17, + cDrop = 32 + 18, + cPut = 32 + 20, + cGet = 32 + 21, + cIfelse = 32 + 22, + cRandom = 32 + 23, + cMul = 32 + 24, + cSqrt = 32 + 26, + cDup = 32 + 27, + cExch = 32 + 28, + cIndex = 32 + 29, + cRoll = 32 + 30, + cSetcurrentpoint = 32 + 33, + cHflex = 32 + 34, + cFlex = 32 + 35, + cHflex1 = 32 + 36, + cFlex1 = 32 + 37, + + cLastCommand = cFlex1 + }; + + enum OthersubrCommands { + othcFlexend = 0, + othcFlexbegin = 1, + othcFlexmiddle = 2, + othcReplacehints = 3, + othcCountercontrolpart = 12, + othcCountercontrol = 13, + othcMM1 = 14, + othcMM2 = 15, + othcMM3 = 16, + othcMM4 = 17, + othcMM6 = 18, + othcITC_load = 19, + othcITC_add = 20, + othcITC_sub = 21, + othcITC_mul = 22, + othcITC_div = 23, + othcITC_put = 24, + othcITC_get = 25, + othcITC_unknown = 26, + othcITC_ifelse = 27, + othcITC_random = 28 + }; + + static String command_name(int); + static const char * const command_names[]; + + static const char * const standard_encoding[256]; + +}; + + +class Type1Charstring : public Charstring { public: + + Type1Charstring() { } + inline Type1Charstring(const String &); // unencrypted + Type1Charstring(int lenIV, const String &); // encrypted + // default copy constructor + // default destructor + // default assignment operator + + inline const uint8_t *data() const; + int length() const { return _s.length(); } + operator String::unspecified_bool_type() const { return _s; } + + inline const String &data_string() const; + inline String substring(int pos, int len) const; + int first_caret_after(int pos) const; + + inline void assign(const String &); + void prepend(const Type1Charstring &); + void assign_substring(int pos, int len, const String &); + + bool process(CharstringInterp &) const; + + private: + + mutable String _s; + mutable int _key; + + void decrypt() const; + +}; + + +class Type2Charstring : public Charstring { public: + + Type2Charstring() { } + inline Type2Charstring(const String &); + // default copy constructor + // default destructor + // default assignment operator + + inline const uint8_t *data() const; + int length() const { return _s.length(); } + + bool process(CharstringInterp &) const; + + private: + + String _s; + +}; + + +struct CharstringContext { + + CharstringContext(const CharstringProgram *program_, const Charstring *cs_) : program(program_), cs(cs_) { } + + operator String::unspecified_bool_type() const { + return cs != 0 ? &String::length : 0; + } + + const CharstringProgram *program; + const Charstring *cs; + +}; + + +class CharstringProgram { public: + + explicit CharstringProgram(unsigned units_per_em); + virtual ~CharstringProgram() { } + + virtual PermString font_name() const { return PermString(); } + virtual void font_matrix(double[6]) const; + unsigned units_per_em() const { return _units_per_em; } + + inline const CharstringProgram *program(int) const; + virtual const CharstringProgram *child_program(int) const; + bool parent_program() const { return _parent_program; } + void set_parent_program(bool pp) { _parent_program = pp; } + + virtual int nsubrs() const { return 0; } + virtual Charstring *subr(int) const { return 0; } + virtual int subr_bias() const { return 0; } + + virtual int ngsubrs() const { return 0; } + virtual Charstring *gsubr(int) const { return 0; } + virtual int gsubr_bias() const { return 0; } + + inline int nxsubrs(bool g) const; + inline Charstring *xsubr(bool g, int) const; + inline int xsubr_bias(bool g) const; + + virtual int nglyphs() const { return 0; } + virtual PermString glyph_name(int) const { return PermString(); } + virtual void glyph_names(Vector<PermString> &) const; + virtual Charstring *glyph(int) const { return 0; } + virtual Charstring *glyph(PermString) const { return 0; } + + inline CharstringContext glyph_context(int) const; + inline CharstringContext glyph_context(PermString) const; + + virtual bool is_mm() const { return mmspace() != 0; } + virtual MultipleMasterSpace *mmspace() const { return 0; } + enum VectorType { VEC_WEIGHT = 0, VEC_NORM_DESIGN = 1, VEC_DESIGN = 2 }; + virtual Vector<double> *mm_vector(VectorType, bool writable) const; + + virtual Type1Encoding *type1_encoding() const { return 0; } + + virtual double global_width_x(bool is_nominal) const; + + private: + + bool _parent_program; + uint16_t _units_per_em; + +}; + + +enum Type1Defs { + t1Warmup_ee = 4, + t1R_ee = 55665, + t1R_cs = 4330, + t1C1 = 52845, + t1C2 = 22719 +}; + + +inline Type1Charstring::Type1Charstring(const String &s) + : Charstring(), _s(s), _key(-1) +{ +} + +inline void Type1Charstring::assign(const String &s) +{ + _s = s; + _key = -1; +} + +inline const uint8_t *Type1Charstring::data() const +{ + if (_key >= 0) + decrypt(); + return reinterpret_cast<const uint8_t *>(_s.data()); +} + +inline const String &Type1Charstring::data_string() const +{ + if (_key >= 0) + decrypt(); + return _s; +} + +inline String Type1Charstring::substring(int pos, int len) const +{ + if (_key >= 0) + decrypt(); + return _s.substring(pos, len); +} + +inline bool operator==(const Type1Charstring &a, const Type1Charstring &b) +{ + return a.data_string() == b.data_string(); +} + + +inline Type2Charstring::Type2Charstring(const String &s) + : _s(s) +{ +} + +inline const uint8_t *Type2Charstring::data() const +{ + return reinterpret_cast<const uint8_t *>(_s.data()); +} + + +inline int CharstringProgram::nxsubrs(bool g) const +{ + return (g ? ngsubrs() : nsubrs()); +} + +inline Charstring *CharstringProgram::xsubr(bool g, int i) const +{ + return (g ? gsubr(i) : subr(i)); +} + +inline int CharstringProgram::xsubr_bias(bool g) const +{ + return (g ? gsubr_bias() : subr_bias()); +} + +inline const CharstringProgram *CharstringProgram::program(int gi) const +{ + return (_parent_program ? child_program(gi) : this); +} + +inline CharstringContext CharstringProgram::glyph_context(int gi) const +{ + if (!_parent_program) + return CharstringContext(this, glyph(gi)); + else if (const CharstringProgram *p = child_program(gi)) + return CharstringContext(p, p->glyph(gi)); + else + return CharstringContext(0, 0); +} + +inline CharstringContext CharstringProgram::glyph_context(PermString gn) const +{ + return CharstringContext(this, glyph(gn)); +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1csgen.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1csgen.hh new file mode 100644 index 00000000000..f5cb128fd8f --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1csgen.hh @@ -0,0 +1,123 @@ +// -*- related-file-name: "../../libefont/t1csgen.cc" -*- +#ifndef EFONT_T1CSGEN_HH +#define EFONT_T1CSGEN_HH +#include <efont/t1interp.hh> +#include <lcdf/straccum.hh> +namespace Efont { +class Type1Font; + +class Type1CharstringGen { public: + + Type1CharstringGen(int precision = 5); + + int precision() const { return _precision; } + + void clear(); + char *data() { return _ncs.data(); } + const char *data() const { return _ncs.data(); } + int length() const { return _ncs.length(); } + + void gen_number(double, int kind = 0); + void gen_command(int); + void gen_stack(CharstringInterp &, int for_cmd); + + void append_charstring(const String &); + + const Point ¤t_point(bool real) const { return (real ? _true : _false); } + void gen_moveto(const Point &, bool closepath, bool always); + + inline String take_string(); + Type1Charstring *output(); + void output(Type1Charstring &); + + static String callsubr_string(int subr); + + private: + + StringAccum _ncs; + int _precision; + double _f_precision; + + Point _true; + Point _false; + + enum State { S_INITIAL, S_GEN }; + State _state; + + void gen_rational(int big_val, int divisor); + bool gen_stem3_stack(CharstringInterp &interp); + +}; + +class Type1CharstringGenInterp : public CharstringInterp { public: + + Type1CharstringGenInterp(int precision); + + int precision() const { return _csgen.precision(); } + void set_direct_hint_replacement(bool dhr) { _direct_hr = dhr; } + void set_hint_replacement_storage(Type1Font *); + + int nhints() const { return _stem_hstem.size(); } + double max_flex_height() const { return _max_flex_height; } + bool bad_flex() const { return _bad_flex; } + + const Type1CharstringGen &csgen() const { return _csgen; } + + void act_width(int, const Point &); + void act_seac(int, double, double, double, int, int); + + void act_hstem(int, double, double); + void act_vstem(int, double, double); + void act_hintmask(int, const unsigned char *, int); + + void act_line(int, const Point &, const Point &); + void act_curve(int, const Point &, const Point &, const Point &, const Point &); + void act_closepath(int); + void act_flex(int, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, double); + + void intermediate_output(Type1Charstring &out); + void run(const CharstringContext &g, Type1Charstring &out); + + private: + + // output + Type1CharstringGen _csgen; + mutable Type1CharstringGen _hint_csgen; + + // current glyph + Point _width; + enum State { S_INITIAL, S_OPEN, S_CLOSED, S_SEAC }; + State _state; + + // hints and hint replacement + Vector<double> _stem_pos; + Vector<double> _stem_width; + Vector<int> _stem_hstem; + String _last_hints; + + bool _in_hr; + bool _direct_hr; + int _hr_firstsubr; + Type1Font *_hr_storage; + + // Flex + double _max_flex_height; + bool _bad_flex; + + inline void gen_number(double, int = 0); + inline void gen_command(int); + void gen_sbw(bool hints_follow); + String gen_hints(const unsigned char *, int) const; + void swap_stem_hints(); + +}; + +inline String Type1CharstringGen::take_string() +{ + String s = _ncs.take_string(); + clear(); + return s; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1font.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1font.hh new file mode 100644 index 00000000000..a879a11e9ab --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1font.hh @@ -0,0 +1,167 @@ +// -*- related-file-name: "../../libefont/t1font.cc" -*- +#ifndef EFONT_T1FONT_HH +#define EFONT_T1FONT_HH +#include <efont/t1cs.hh> +#include <lcdf/hashmap.hh> +class StringAccum; +class ErrorHandler; +namespace Efont { +class Type1Item; +class Type1Definition; +class Type1Encoding; +class Type1IncludedFont; +class Type1Subr; +class Type1Reader; +class Type1Writer; +class MultipleMasterSpace; + +class Type1Font : public CharstringProgram { public: + + Type1Font(Type1Reader &); + ~Type1Font(); + + int read(Type1Reader &); + + bool ok() const; + + inline PermString font_name() const; + void font_matrix(double[6]) const; + + int nitems() const { return _items.size(); } + Type1Item *item(int i) const { return _items[i]; } + void add_item(Type1Item *it) { _items.push_back(it); } + void add_definition(int dict, Type1Definition *); + void add_type1_encoding(Type1Encoding *); + + int nsubrs() const { return _subrs.size(); } + Type1Charstring *subr(int) const; + + int nglyphs() const { return _glyphs.size(); } + PermString glyph_name(int) const; + Type1Charstring *glyph(int) const; + Type1Charstring *glyph(PermString) const; + void add_glyph(Type1Subr *); + + Type1Subr *subr_x(int i) const { return _subrs[i]; } + bool set_subr(int, const Type1Charstring &, PermString definer = PermString()); + bool remove_subr(int); + void fill_in_subrs(); + void renumber_subrs(const Vector<int> &); // dangerous! + + Type1Subr *glyph_x(int i) const { return _glyphs[i]; } + + Type1Encoding *type1_encoding() const { return _encoding; } + + // note: the order is relevant + enum Dict { + dFont = 0, dF = dFont, + dFontInfo = 1, dFI = dFontInfo, + dPrivate = 2, dP = dPrivate, + dBlend = 3, dB = dBlend, + dBlendFontInfo = dB+dFI, dBFI = dBlendFontInfo, + dBlendPrivate = dB+dP, dBP = dBlendPrivate, + dLast + }; + + Type1Definition *dict(int d, PermString s) const { return _dict[d][s]; } + Type1Definition *dict(PermString s) const { return _dict[dF][s]; } + Type1Definition *p_dict(PermString s) const { return _dict[dP][s]; } + Type1Definition *b_dict(PermString s) const { return _dict[dB][s]; } + Type1Definition *bp_dict(PermString s) const { return _dict[dBP][s];} + Type1Definition *fi_dict(PermString s) const { return _dict[dFI][s];} + + typedef HashMap<PermString, Type1Definition *> DictHashMap; + inline DictHashMap::const_iterator dict_begin(int dict) const; + inline DictHashMap::iterator dict_begin(int dict); + int first_dict_item(int d) const { return _index[d]; } + + Type1Definition *ensure(Dict, PermString); + void add_header_comment(const String &); + + MultipleMasterSpace *create_mmspace(ErrorHandler * = 0) const; + MultipleMasterSpace *mmspace() const; + + void undo_synthetic(); + + void set_charstring_definer(PermString d) { _charstring_definer = d; } + + void write(Type1Writer &); + + // font skeletons + static Type1Font *skeleton_make(PermString, const String &version = String()); + static Type1Font *skeleton_make_copy(const Type1Font *, PermString, const Vector<double> *xuid_extension); + void skeleton_comments_end(); + void skeleton_fontinfo_end(); + void skeleton_fontdict_end(); + void skeleton_private_end(); + void skeleton_common_subrs(); + + // for experts only + void set_item(int, Type1Item *); + inline void set_dict(int dict, PermString, Type1Definition *); + void uncache_defs(); + + private: + + mutable bool _cached_defs; + bool _built; + mutable PermString _font_name; + + Vector<Type1Item *> _items; + + HashMap<PermString, Type1Definition *> *_dict; + int _index[dLast]; + int _dict_deltas[dLast]; + + Vector<Type1Subr *> _subrs; + Vector<Type1Subr *> _glyphs; + HashMap<PermString, int> _glyph_map; + + PermString _charstring_definer; + Type1Encoding *_encoding; + + mutable bool _cached_mmspace; + mutable MultipleMasterSpace *_mmspace; + + Type1IncludedFont *_synthetic_item; + + Type1Font(PermString); + Type1Font(const Type1Font &); + Type1Font &operator=(const Type1Font &); + + void read_encoding(Type1Reader &, const char *); + bool read_synthetic_font(Type1Reader &, const char *, StringAccum &); + void cache_defs() const; + void shift_indices(int, int); + + Type1Item *dict_size_item(int) const; + int get_dict_size(int) const; + void set_dict_size(int, int); + +}; + + +inline Type1Font::DictHashMap::const_iterator Type1Font::dict_begin(int dict) const +{ + return _dict[dict].begin(); +} + +inline Type1Font::DictHashMap::iterator Type1Font::dict_begin(int dict) +{ + return _dict[dict].begin(); +} + +inline void Type1Font::set_dict(int dict, PermString name, Type1Definition *t1d) +{ + _dict[dict].insert(name, t1d); +} + +inline PermString Type1Font::font_name() const +{ + if (!_cached_defs) + cache_defs(); + return _font_name; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1interp.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1interp.hh new file mode 100644 index 00000000000..16c878a3677 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1interp.hh @@ -0,0 +1,239 @@ +// -*- related-file-name: "../../libefont/t1interp.cc" -*- +#ifndef EFONT_T1INTERP_HH +#define EFONT_T1INTERP_HH +#include <efont/t1cs.hh> +#include <lcdf/point.hh> +#include <stdio.h> +namespace Efont { + +class CharstringInterp { public: + + CharstringInterp(); + CharstringInterp(const Vector<double> &weight_vec); + virtual ~CharstringInterp() { } + + int error() const { return _error; } + int error_data() const { return _error_data; } + static String error_string(int error, int error_data); + inline String error_string() const; + + bool careful() const { return _careful; } + void set_careful(bool c) { _careful = c; } + + bool done() const { return _done; } + void set_done() { _done = true; } + + int size() const { return _sp; } + double &at(unsigned i) { return _s[i]; } + double &top(unsigned i = 0) { return _s[_sp - i - 1]; } + double pop(unsigned n = 1) { _sp -= n; return _s[_sp]; } + inline void push(double); + void clear() { _sp = 0; } + + int ps_size() const { return _ps_sp; } + double ps_at(unsigned i) const { return _ps_s[i]; } + double ps_pop() { return _ps_s[--_ps_sp]; } + inline void ps_push(double); + void ps_clear() { _ps_sp = 0; } + + int subr_depth() const { return _subr_depth; } + + inline double &vec(Vector<double> *, int); + const Vector<double> &weight_vector() const { return _weight_vector; } + Vector<double> *scratch_vector() { return &_scratch_vector; } + + const CharstringProgram *program() const { return _program; } + inline Charstring *get_subr(int) const; + inline Charstring *get_gsubr(int) const; + inline Charstring *get_xsubr(bool g, int) const; + inline Charstring *get_glyph(PermString) const; + + bool interpret(const CharstringProgram *, const Charstring *); + inline bool interpret(const CharstringContext &); + + //virtual void init(const CharstringProgram *); + bool error(int c) { return error(c, 0); } + virtual bool error(int, int); + virtual bool number(double); + + bool arith_command(int); + bool vector_command(int); + bool blend_command(); + bool callsubr_command(); + bool callgsubr_command(); + inline bool callxsubr_command(bool g); + bool mm_command(int, int); + bool itc_command(int, int); + + const Point &left_sidebearing() const { return _lsb; } + const Point ¤tpoint() const { return _cp; } + void set_state_path() { _state = S_PATH; } + + virtual bool callothersubr_command(int, int); + virtual bool type1_command(int); + virtual bool type2_command(int, const uint8_t *, int *); + + virtual void act_sidebearing(int cmd, const Point &lsb); + virtual void act_width(int cmd, const Point &width); + virtual void act_default_width(int cmd); + virtual void act_nominal_width_delta(int cmd, double delta); + virtual void act_seac(int cmd, double asb, double adx, double ady, int bchar, int achar); + + virtual void act_line(int cmd, const Point &p0, const Point &p1); + virtual void act_curve(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3); + virtual void act_closepath(int cmd); + + virtual void act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth); + + virtual void act_hstem(int cmd, double y, double dy); + virtual void act_vstem(int cmd, double x, double dx); + virtual void act_hstem3(int cmd, double y0, double dy0, double y1, double dy1, double y2, double dy2); + virtual void act_vstem3(int cmd, double x0, double dx0, double x1, double dx1, double x2, double dx2); + virtual void act_hintmask(int cmd, const uint8_t *data, int nhints); + + typedef Charstring Cs; + + enum Errors { + errOK = 0, + errInternal = -1, + errRunoff = -2, + errUnimplemented = -3, + errOverflow = -4, + errUnderflow = -5, + errVector = -6, + errValue = -7, + errSubr = -8, + errGlyph = -9, + errCurrentPoint = -10, + errFlex = -11, + errMultipleMaster = -12, + errOpenStroke = -13, + errLateSidebearing = -14, + errOthersubr = -15, + errOrdering = -16, + errHintmask = -17, + errSubrDepth = -18, + errLastError = -18 + }; + + enum { STACK_SIZE = 48, PS_STACK_SIZE = 24, MAX_SUBR_DEPTH = 10, + SCRATCH_SIZE = 32 }; + + private: + + int _error; + int _error_data; + bool _done; + bool _careful; + + double _s[STACK_SIZE]; + int _sp; + double _ps_s[PS_STACK_SIZE]; + int _ps_sp; + + int _subr_depth; + + Vector<double> _weight_vector; + Vector<double> _scratch_vector; + + Point _lsb; + Point _cp; + Point _seac_origin; + + const CharstringProgram *_program; + + enum State { + S_INITIAL, S_SEAC, S_SBW, S_HSTEM, S_VSTEM, S_HINTMASK, S_IPATH, S_PATH + }; + State _state; + bool _flex; + + // for processing Type 2 charstrings + int _t2nhints; + + static double double_for_error; + + void initialize(); + + inline void ensure_weight_vector(); + void fetch_weight_vector(); + + bool roll_command(); + int type2_handle_width(int, bool); + + inline void actp_rmoveto(int, double, double); + inline void actp_rlineto(int, double, double); + void actp_rrcurveto(int, double, double, double, double, double, double); + void actp_rrflex(int, double, double, double, double, double, double, double, double, double, double, double, double, double); + +}; + + +inline String CharstringInterp::error_string() const +{ + return error_string(_error, _error_data); +} + +inline void CharstringInterp::push(double d) +{ + if (_sp < STACK_SIZE) + _s[_sp++] = d; + else + error(errOverflow); +} + +inline void CharstringInterp::ps_push(double d) +{ + if (_ps_sp < PS_STACK_SIZE) + _ps_s[_ps_sp++] = d; + else + error(errOverflow); +} + +inline double &CharstringInterp::vec(Vector<double> *v, int i) +{ + if (i < 0 || i >= v->size()) { + error(errVector); + return double_for_error; + } else + return v->at_u(i); +} + +inline Charstring *CharstringInterp::get_subr(int n) const +{ + return _program ? _program->subr(n) : 0; +} + +inline Charstring *CharstringInterp::get_gsubr(int n) const +{ + return _program ? _program->gsubr(n) : 0; +} + +inline Charstring *CharstringInterp::get_xsubr(bool g, int n) const +{ + return _program ? _program->xsubr(g, n) : 0; +} + +inline Charstring *CharstringInterp::get_glyph(PermString n) const +{ + return _program ? _program->glyph(n) : 0; +} + +inline void CharstringInterp::ensure_weight_vector() +{ + if (!_weight_vector.size()) + fetch_weight_vector(); +} + +inline bool CharstringInterp::callxsubr_command(bool g) +{ + return (g ? callgsubr_command() : callsubr_command()); +} + +inline bool CharstringInterp::interpret(const CharstringContext &g) +{ + return interpret(g.program, g.cs); +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1item.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1item.hh new file mode 100644 index 00000000000..8b5bfb8f8cb --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1item.hh @@ -0,0 +1,268 @@ +// -*- related-file-name: "../../libefont/t1item.cc" -*- +#ifndef EFONT_T1ITEM_HH +#define EFONT_T1ITEM_HH +#include <efont/t1cs.hh> +#include <lcdf/straccum.hh> +namespace Efont { +class Type1Reader; +class Type1Writer; +class CharstringInterp; +class Type1Font; +class Type1CopyItem; +class Type1Subr; +class Type1SubrGroupItem; +class Type1Definition; + +class Type1Item { public: + + Type1Item() { } + virtual ~Type1Item() { } + + virtual void gen(Type1Writer &) = 0; + + virtual Type1CopyItem *cast_copy() { return 0; } + virtual Type1Subr *cast_subr() { return 0; } + virtual Type1Definition *cast_definition() { return 0; } + virtual Type1SubrGroupItem *cast_subr_group() { return 0; } + + private: + + Type1Item(const Type1Item &); + Type1Item &operator=(const Type1Item &); + +}; + +class Type1NullItem : public Type1Item { public: + + Type1NullItem() { } + + void gen(Type1Writer &); + +}; + +class Type1CopyItem : public Type1Item { public: + + Type1CopyItem(const String &s) : _value(s) { } + ~Type1CopyItem() { } + + const String &value() const { return _value; } + int length() const { return _value.length(); } + + void set_value(const String &s) { _value = s; } + + void gen(Type1Writer &); + + Type1CopyItem *cast_copy() { return this; } + + private: + + String _value; + +}; + +class Type1EexecItem : public Type1Item { public: + + Type1EexecItem(bool on) : _eexec_on(on) { } + + void gen(Type1Writer &w); + + private: + + bool _eexec_on; + +}; + +class Type1Definition : public Type1Item { public: + + typedef Vector<double> NumVector; + + Type1Definition(PermString, const String &, PermString); + ~Type1Definition() { } + static Type1Definition *make(StringAccum &, Type1Reader * = 0, bool force = false); + static Type1Definition *make_string(PermString, const String &, PermString); + static inline Type1Definition *make_literal(PermString, const String &, PermString); + static inline Type1Definition *make(PermString, double, PermString); + + PermString name() const { return _name; } + const String &value() const { return _val; } + PermString definer() const { return _definer; } + + bool value_bool(bool &) const; + bool value_int(int &) const; + bool value_num(double &) const; + bool value_string(String &) const; + bool value_name(PermString &) const; + bool value_numvec(NumVector &) const; + bool value_numvec_vec(Vector<NumVector> &) const; + bool value_normalize(Vector<NumVector> &in, Vector<NumVector> &out) const; + bool value_namevec(Vector<PermString> &) const; + + void set_bool(bool); + void set_int(int); + void set_num(double); + void set_string(const String &); + void set_name(PermString, bool name = true); + void set_code(const char *s) { set_val(s); } + void set_numvec(const NumVector &, bool executable = false); + void set_numvec_vec(const Vector<NumVector> &); + void set_normalize(const Vector<NumVector> &, const Vector<NumVector> &); + void set_namevec(const Vector<PermString> &, bool executable = true); + + void gen(Type1Writer &); + void gen(StringAccum &); + + Type1Definition *cast_definition() { return this; } + + private: + + PermString _name; + String _val; + PermString _definer; + + static int slurp_string(StringAccum &, int, Type1Reader *); + static int slurp_proc(StringAccum &, int, Type1Reader *); + + inline void set_val(const String &); + inline void set_val(StringAccum &); + +}; + +class Type1Encoding : public Type1Item { public: + + Type1Encoding(); + Type1Encoding(const Type1Encoding &); + ~Type1Encoding(); + + void clear(); + void unshare(); + + PermString operator[](int e) const { assert(e>=0&&e<256); return _v[e]; } + PermString elt(int e) const { return (*this)[e]; } + PermString operator[](unsigned char e) const { return _v[e]; } + PermString elt(unsigned char e) const { return operator[](e); } + inline void put(int e, PermString p); + + void set_definer(PermString s) { _definer = s; } + + static Type1Encoding *standard_encoding(); + + void gen(Type1Writer &); + + private: + + PermString *_v; + Type1Encoding *_copy_of; + PermString _definer; + + Type1Encoding(Type1Encoding *); + Type1Encoding &operator=(const Type1Encoding &); + +}; + +class Type1Subr : public Type1Item { public: + + static Type1Subr *make(const char *, int, int cs_start, int cs_len, int lenIV); + static Type1Subr *make_subr(int, const Type1Charstring &, PermString); + static Type1Subr *make_glyph(PermString, const Type1Charstring &, PermString); + + bool is_subr() const { return !_name; } + PermString name() const { return _name; } + int subrno() const { return _subrno; } + PermString definer() const { return _definer; } + + Type1Charstring &t1cs() { return _cs; } + const Type1Charstring &t1cs() const { return _cs; } + operator Type1Charstring &() { return _cs; } + operator const Type1Charstring &() const { return _cs; } + + void gen(Type1Writer &); + + virtual Type1Subr *cast_subr() { return this; } + + private: + + PermString _name; + int _subrno; + PermString _definer; + + Type1Charstring _cs; + + static PermString cached_definer; + + Type1Subr(PermString, int, PermString, int, const String &); + Type1Subr(PermString, int, PermString, const Type1Charstring &); + +}; + +class Type1SubrGroupItem : public Type1Item { public: + + Type1SubrGroupItem(Type1Font *, bool, const String &); + Type1SubrGroupItem(const Type1SubrGroupItem &, Type1Font *); + ~Type1SubrGroupItem() { } + + void set_end_text(const String &s) { _end_text = s; } + void add_end_text(const String &); + + bool is_subrs() const { return _is_subrs; } + const String &end_text() const { return _end_text; } + + void gen(Type1Writer &); + + Type1SubrGroupItem *cast_subr_group() { return this; } + + private: + + Type1Font *_font; + bool _is_subrs; + String _value; + String _end_text; + +}; + +class Type1IncludedFont : public Type1Item { public: + + Type1IncludedFont(Type1Font *, int); + ~Type1IncludedFont(); + + Type1Font *included_font() const { return _included_font; } + + void gen(Type1Writer &); + + private: + + Type1Font *_included_font; + int _unique_id; + +}; + + +inline Type1Definition *Type1Definition::make_literal(PermString n, const String &v, PermString d) +{ + return new Type1Definition(n, v, d); +} + +inline Type1Definition *Type1Definition::make(PermString n, double v, PermString d) +{ + return new Type1Definition(n, String(v), d); +} + +inline void Type1Definition::set_val(const String &v) +{ + _val = v; +} + +inline void Type1Definition::set_val(StringAccum &sa) +{ + _val = sa.take_string(); +} + +inline void Type1Encoding::put(int e, PermString glyph) +{ + if (_copy_of) + unshare(); + assert(e >= 0 && e < 256); + _v[e] = glyph; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1mm.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1mm.hh new file mode 100644 index 00000000000..8564f46cf67 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1mm.hh @@ -0,0 +1,108 @@ +// -*- related-file-name: "../../libefont/t1mm.cc" -*- +#ifndef EFONT_T1MM_HH +#define EFONT_T1MM_HH +#include <efont/t1cs.hh> +class ErrorHandler; +namespace Efont { +class Type1Font; + +class MultipleMasterSpace : public CharstringProgram { public: + + MultipleMasterSpace(PermString, int naxes, int nmasters); + // default destructor + + typedef Vector<double> NumVector; + + PermString font_name() const { return _font_name; } + int naxes() const { return _naxes; } + int nmasters() const { return _nmasters; } + + int axis(PermString) const; + double axis_low(int) const; + double axis_high(int) const; + + PermString axis_type(int a) const { return _axis_types[a]; } + PermString axis_label(int a) const { return _axis_labels[a]; } + inline PermString axis_abbreviation(int a) const; + static PermString axis_abbreviation(PermString); + + const Type1Charstring &ndv() const { return _ndv; } + const Type1Charstring &cdv() const { return _cdv; } + + void set_master_positions(const Vector<NumVector> &); + void set_normalize(const Vector<NumVector> &, const Vector<NumVector> &); + void set_axis_type(int, PermString); + void set_axis_label(int, PermString); + void set_ndv(const Type1Charstring &cs) { _ndv = cs; } + void set_cdv(const Type1Charstring &cs) { _cdv = cs; } + void set_design_vector(const NumVector &); + void set_weight_vector(const NumVector &); + + bool check(ErrorHandler * = 0); + bool check_intermediate(ErrorHandler * = 0); + + NumVector empty_design_vector() const; + inline const NumVector &default_design_vector() const; + bool set_design(NumVector &, int, double, ErrorHandler * = 0) const; + bool set_design(NumVector &, PermString, double, ErrorHandler * = 0) const; + + inline const NumVector &default_weight_vector() const; + + bool design_to_norm_design(const NumVector &, NumVector &, ErrorHandler * = 0) const; + bool design_to_weight(const NumVector &, NumVector &, ErrorHandler * = 0) const; + + NumVector *mm_vector(VectorType, bool writable) const; + + private: + + mutable bool _ok; + + PermString _font_name; + int _naxes; + int _nmasters; + + Vector<NumVector> _master_positions; + Vector<NumVector> _normalize_in; + Vector<NumVector> _normalize_out; + + Vector<PermString> _axis_types; + Vector<PermString> _axis_labels; + + Type1Charstring _ndv; + Type1Charstring _cdv; + + NumVector _default_design_vector; + NumVector _default_weight_vector; + + mutable NumVector *_design_vector; + mutable NumVector *_norm_design_vector; + mutable NumVector *_weight_vector; + + bool error(ErrorHandler *, const char *, ...) const; + + MultipleMasterSpace(const MultipleMasterSpace &); + MultipleMasterSpace &operator=(const MultipleMasterSpace &); + + bool normalize_vector(ErrorHandler *) const; + bool convert_vector(ErrorHandler *) const; + +}; + + +inline const Vector<double> &MultipleMasterSpace::default_design_vector() const +{ + return _default_design_vector; +} + +inline const Vector<double> &MultipleMasterSpace::default_weight_vector() const +{ + return _default_weight_vector; +} + +inline PermString MultipleMasterSpace::axis_abbreviation(int a) const +{ + return axis_abbreviation(_axis_types[a]); +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1rw.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1rw.hh new file mode 100644 index 00000000000..03af2cfeeb8 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1rw.hh @@ -0,0 +1,232 @@ +// -*- related-file-name: "../../libefont/t1rw.cc" -*- +#ifndef EFONT_T1RW_HH +#define EFONT_T1RW_HH +#include <stdio.h> +#include <lcdf/string.hh> +#include <lcdf/straccum.hh> +namespace Efont { + +class Type1Reader { public: + + Type1Reader(); + virtual ~Type1Reader(); + + int get_data(unsigned char *, int); + virtual int more_data(unsigned char *, int) = 0; + virtual bool preserve_whitespace() const { return false; } + + void switch_eexec(bool, unsigned char *, int); + virtual void set_charstring_definer(PermString); + + bool next_line(StringAccum &); + bool was_charstring() const { return _charstring_len > 0; } + int charstring_start() const { return _charstring_start; } + int charstring_length() const { return _charstring_len; } + + private: + + enum { DATA_SIZE = 1024 }; + + unsigned char *_data; + int _len; + int _pos; + + PermString _charstring_definer; + int _charstring_start; + int _charstring_len; + + int _ungot; + int _crlf; + + bool _eexec; + bool _binary_eexec; + int _r; + + Type1Reader(const Type1Reader &); + Type1Reader &operator=(const Type1Reader &); + + int more_data(); + + inline int eexec(int); + int ascii_eexec_get(); + inline int get_base(); + inline int get(); + + void start_eexec(int ascii_chars); + + bool test_charstring(StringAccum &); + + static unsigned char xvalue_store[]; + static unsigned char *xvalue; + static void static_initialize(); + +}; + + +class Type1PFAReader : public Type1Reader { + + FILE *_f; + + public: + + Type1PFAReader(FILE *); + + int more_data(unsigned char *, int); + +}; + +class Type1PFBReader : public Type1Reader { + + FILE *_f; + bool _binary; + int _left; + + public: + + Type1PFBReader(FILE *); + + int more_data(unsigned char *, int); + bool preserve_whitespace() const; + +}; + +class Type1SubsetReader : public Type1Reader { + + Type1Reader *_reader; + int _left; + + public: + + Type1SubsetReader(Type1Reader *, int); + + int more_data(unsigned char *, int); + bool preserve_whitespace() const; + +}; + + +/***** + * Writers + **/ + +class Type1Writer { public: + + Type1Writer(); + virtual ~Type1Writer(); + + bool eexecing() const { return _eexec; } + + inline void print(int); + void print(const char *, int); + + inline Type1Writer &operator<<(char); + inline Type1Writer &operator<<(unsigned char); + Type1Writer &operator<<(int); + Type1Writer &operator<<(double); + + virtual void flush(); + virtual void switch_eexec(bool); + virtual void print0(const unsigned char *, int) = 0; + + PermString charstring_start() const { return _charstring_start; } + int lenIV() const { return _lenIV; } + void set_charstring_start(PermString p) { _charstring_start = p; } + void set_lenIV(int l) { _lenIV = l; } + + private: + + enum { BufSize = 1024 }; + + unsigned char *_buf; + int _pos; + + bool _eexec; + int _eexec_start; + int _eexec_end; + int _r; + + PermString _charstring_start; + int _lenIV; + + void local_flush(); + inline unsigned char eexec(int); + + Type1Writer(const Type1Writer &); + Type1Writer &operator=(const Type1Writer &); + +}; + + +class Type1PFAWriter: public Type1Writer { + + FILE *_f; + int _hex_line; + + public: + + Type1PFAWriter(FILE *); + ~Type1PFAWriter(); + + void switch_eexec(bool); + void print0(const unsigned char *, int); + +}; + + +class Type1PFBWriter: public Type1Writer { + + StringAccum _save; + FILE *_f; + bool _binary; + + public: + + Type1PFBWriter(FILE *); + ~Type1PFBWriter(); + + void flush(); + void switch_eexec(bool); + void print0(const unsigned char *, int); + +}; + + +inline void Type1Writer::print(int c) +{ + if (_pos >= BufSize) + local_flush(); + _buf[_pos++] = c; +} + +inline Type1Writer &operator<<(Type1Writer &w, const char *cc) +{ + w.print(cc, strlen(cc)); + return w; +} + +inline Type1Writer &operator<<(Type1Writer &w, PermString p) +{ + w.print(p.c_str(), p.length()); + return w; +} + +inline Type1Writer &operator<<(Type1Writer &w, const String &s) +{ + w.print(s.data(), s.length()); + return w; +} + +inline Type1Writer &Type1Writer::operator<<(char c) +{ + print((unsigned char)c); + return *this; +} + +inline Type1Writer &Type1Writer::operator<<(unsigned char c) +{ + print(c); + return *this; +} + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1unparser.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1unparser.hh new file mode 100644 index 00000000000..15e12fb79d1 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1unparser.hh @@ -0,0 +1,39 @@ +// -*- related-file-name: "../../libefont/t1unparser.cc" -*- +#ifndef EFONT_T1UNPARSER_HH +#define EFONT_T1UNPARSER_HH +#include <efont/t1interp.hh> +#include <lcdf/straccum.hh> +namespace Efont { + +class CharstringUnparser : public CharstringInterp { public: + + CharstringUnparser(); + CharstringUnparser(const CharstringUnparser &); + + const String &indent() const { return _indent; } + void set_indent(const String &s) { _indent = s; } + void set_one_command_per_line(bool b) { _one_command_per_line = b; } + + void clear(); + + bool number(double); + bool type1_command(int); + bool type2_command(int, const unsigned char *, int *); + void act_hintmask(int, const unsigned char *, int); + + String value(); + + static String unparse(const Charstring *); + static String unparse(const Charstring &); + + private: + + String _indent; + bool _one_command_per_line; + bool _start_of_line; + StringAccum _sa; + +}; + +} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfcs.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfcs.hh new file mode 100644 index 00000000000..96758435603 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfcs.hh @@ -0,0 +1,40 @@ +// -*- related-file-name: "../../libefont/ttfcs.cc" -*- +#ifndef EFONT_TTFCS_HH +#define EFONT_TTFCS_HH +#include <efont/t1cs.hh> +#include <efont/otf.hh> +#include <efont/otfdata.hh> +namespace Efont { + +class TrueTypeBoundsCharstringProgram : public CharstringProgram { public: + + TrueTypeBoundsCharstringProgram(const OpenType::Font *); + ~TrueTypeBoundsCharstringProgram(); + + void font_matrix(double[6]) const; + + int nglyphs() const; + Charstring *glyph(int gi) const; + PermString glyph_name(int gi) const; + void glyph_names(Vector<PermString> &) const; + + private: + + const OpenType::Font *_otf; + int _nglyphs; + int _nhmtx; + bool _loca_long; + OpenType::Data _loca; + OpenType::Data _glyf; + OpenType::Data _hmtx; + mutable Vector<Charstring*> _charstrings; + mutable Vector<PermString> _glyph_names; + mutable bool _got_glyph_names; + mutable Vector<uint32_t> _unicodes; + mutable bool _got_unicodes; + +}; + +} +#endif + diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfhead.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfhead.hh new file mode 100644 index 00000000000..f5ab4cedff6 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfhead.hh @@ -0,0 +1,41 @@ +// -*- related-file-name: "../../libefont/ttfhead.cc" -*- +#ifndef EFONT_TTFHEAD_HH +#define EFONT_TTFHEAD_HH +#include <efont/otf.hh> +#include <efont/otfdata.hh> // for ntohl() +#include <lcdf/error.hh> +namespace Efont { namespace OpenType { + +class Head { public: + + Head(const String &, ErrorHandler * = 0); + // default destructor + + bool ok() const { return _error >= 0; } + int error() const { return _error; } + + unsigned units_per_em() const; + unsigned index_to_loc_format() const; + + private: + + Data _d; + int _error; + + int parse_header(ErrorHandler *); + +}; + + +inline unsigned Head::units_per_em() const +{ + return (_error >= 0 ? _d.u16(18) : 0); +} + +inline unsigned Head::index_to_loc_format() const +{ + return (_error >= 0 ? _d.u16(50) : 0); +} + +}} +#endif diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh new file mode 100644 index 00000000000..ebe35331ce6 --- /dev/null +++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh @@ -0,0 +1,42 @@ +// -*- related-file-name: "../../libefont/ttfkern.cc" -*- +#ifndef EFONT_TTFKERN_HH +#define EFONT_TTFKERN_HH +#include <efont/otfgpos.hh> +namespace Efont { namespace OpenType { + +class KernTable { public: + + KernTable(const Data &, ErrorHandler * = 0) throw (Error); + // default destructor + + bool ok() const { return _error >= 0; } + + bool unparse_automatics(Vector<Positioning> &, ErrorHandler * = 0) const; + + private: + + Data _d; + int _version; + int _error; + + enum { + COV_V0_HORIZONTAL = 0x0001, COV_V0_MINIMUM = 0x0002, + COV_V0_CROSS_STREAM = 0x0004, COV_V0_OVERRIDE = 0x0008, + COV_V0_FORMAT = 0xFF00, COV_V0_FORMAT0 = 0x0000, + COV_V1_VERTICAL = 0x8000, COV_V1_CROSS_STREAM = 0x4000, + COV_V1_VARIATION = 0x2000, + COV_V1_FORMAT = 0x00FF, COV_V1_FORMAT0 = 0x0000 + }; + + inline uint32_t ntables() const { + return _version == 0 ? _d.u16(2) : _d.u32(4); + } + inline uint32_t first_offset() const { + return _version == 0 ? 4 : 8; + } + inline Data subtable(uint32_t &off) const throw (Error); + +}; + +}} +#endif |