diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.1.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.1 2018-02-23 12:47:54.075972154 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/cfftot1.cc 2018-02-23 12:47:54.075972154 -0500 @@ -1,6 +1,6 @@ /* cfftot1.cc -- driver for translating CFF fonts to Type 1 fonts * - * Copyright (c) 2002-2016 Eddie Kohler + * Copyright (c) 2002-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -221,7 +221,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("cfftot1 (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2002-2016 Eddie Kohler\n\ + printf("Copyright (C) 2002-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/maket1font.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/maket1font.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/maket1font.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/cfftot1/maket1font.cc 2018-02-23 12:47:54.076972128 -0500 @@ -1,6 +1,6 @@ /* maket1font.{cc,hh} -- translate CFF fonts to Type 1 fonts * - * Copyright (c) 2002-2016 Eddie Kohler + * Copyright (c) 2002-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/configure.ac.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/configure.ac --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/configure.ac.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/configure.ac 2018-02-23 12:47:54.076972128 -0500 @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([lcdf-typetools], [2.106]) +AC_INIT([lcdf-typetools], [2.107]) AC_CONFIG_SRCDIR([NEWS.md]) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS([autoconf.h]) diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/config.h.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/config.h --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/config.h.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/config.h 2018-02-23 12:47:54.076972128 -0500 @@ -7,7 +7,6 @@ #ifdef WIN32 # ifdef __MINGW32__ # include -# include # else # include # endif @@ -39,6 +38,11 @@ double good_strtod(const char *s, char * } /* Get rid of a possible inline macro under C++. */ # define inline inline + +/* Ignore `noexcept` if compiler is too old. */ +#if __cplusplus < 201103L +#define noexcept +#endif #endif #endif /* LCDF_TYPETOOLS_CONFIG_H */ diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/cff.hh 2018-02-23 12:47:54.076972128 -0500 @@ -31,7 +31,7 @@ class Cff { public: int nfonts() const { return _name_index.size(); } PermString font_name(int i) const { return _name_index[i]; } - FontParent *font(PermString = PermString(), ErrorHandler * = 0); + FontParent* font(PermString = PermString(), ErrorHandler* = 0); enum { NSTANDARD_STRINGS = 391, MAX_SID = 64999 }; int max_sid() const { return NSTANDARD_STRINGS - 1 + _strings.size(); } @@ -125,13 +125,12 @@ class Cff { public: mutable HashMap _strings_map; IndexIterator _gsubrs_index; - Vector _gsubrs_cs; + Vector _gsubrs_cs; + Vector _fonts; 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 }; @@ -238,12 +237,14 @@ class Cff::FontParent : public Charstrin Cff* _cff; int _charstring_type; int _error; + int _font_index; FontParent(const FontParent &); FontParent &operator=(const FontParent &); Charstring *charstring(const IndexIterator &, int) const; + friend class Cff; friend class Cff::Font; friend class Cff::CIDFont; friend class Cff::ChildFont; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfdata.hh 2018-02-23 12:47:54.077972103 -0500 @@ -83,20 +83,20 @@ class Data { 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 (); + inline uint8_t operator[](unsigned offset) const; + inline uint16_t u16(unsigned offset) const; + inline int16_t s16(unsigned offset) const; + inline uint32_t u32(unsigned offset) const; + inline int32_t s32(unsigned offset) const; + inline uint8_t operator[](int offset) const; + inline uint16_t u16(int offset) const; + inline int16_t s16(int offset) const; + inline uint32_t u32(int offset) const; + inline int32_t s32(int offset) const; + + Data subtable(unsigned offset) const; + Data offset_subtable(unsigned offset_offset) const; + inline Data substring(int left, int len = -1) const noexcept; void align_long() { _str.align(4); } @@ -106,7 +106,7 @@ class Data { }; -inline uint8_t Data::operator[](unsigned offset) const throw (Bounds) { +inline uint8_t Data::operator[](unsigned offset) const { if (offset >= static_cast(_str.length())) throw Bounds(); else @@ -114,11 +114,7 @@ inline uint8_t Data::operator[](unsigned } inline uint16_t Data::u16(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohs(*reinterpret_cast(s)); -#else return (s[0] << 8) + s[1]; -#endif } inline uint16_t Data::u16_aligned(const unsigned char* s) { @@ -127,11 +123,7 @@ inline uint16_t Data::u16_aligned(const } inline int16_t Data::s16(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohs(*reinterpret_cast(s)); -#else return (int16_t) ((s[0] << 8) + s[1]); -#endif } inline int16_t Data::s16_aligned(const unsigned char* s) { @@ -140,20 +132,12 @@ inline int16_t Data::s16_aligned(const u } inline uint32_t Data::u32(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohl(*reinterpret_cast(s)); -#else - return (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; -#endif + return ((unsigned) s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; } inline uint32_t Data::u32_aligned16(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohl(*reinterpret_cast(s)); -#else efont_precondition((reinterpret_cast(s) & 1) == 0); - return (u16_aligned(s) << 16) + u16_aligned(s + 2); -#endif + return ((unsigned) u16_aligned(s) << 16) + u16_aligned(s + 2); } inline uint32_t Data::u32_aligned(const unsigned char* s) { @@ -162,20 +146,12 @@ inline uint32_t Data::u32_aligned(const } inline int32_t Data::s32(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohl(*reinterpret_cast(s)); -#else - return (int32_t) ((s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); -#endif + return (int32_t) (((unsigned) s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); } inline int32_t Data::s32_aligned16(const unsigned char* s) { -#if __x86__ || __x86_64__ || HAVE_INDIFFERENT_ALIGNMENT - return ntohl(*reinterpret_cast(s)); -#else efont_precondition((reinterpret_cast(s) & 1) == 0); - return (int32_t) ((u16_aligned(s) << 16) + u16_aligned(s + 2)); -#endif + return (int32_t) (((unsigned) u16_aligned(s) << 16) + u16_aligned(s + 2)); } inline int32_t Data::s32_aligned(const unsigned char* s) { @@ -183,55 +159,55 @@ inline int32_t Data::s32_aligned(const u return ntohl(*reinterpret_cast(s)); } -inline uint16_t Data::u16(unsigned offset) const throw (Bounds) { +inline uint16_t Data::u16(unsigned offset) const { if (offset + 1 >= static_cast(_str.length()) || offset + 1 == 0) throw Bounds(); else return u16_aligned(_str.udata() + offset); } -inline int16_t Data::s16(unsigned offset) const throw (Bounds) { +inline int16_t Data::s16(unsigned offset) const { if (offset + 1 >= static_cast(_str.length()) || offset + 1 == 0) throw Bounds(); else return s16_aligned(_str.udata() + offset); } -inline uint32_t Data::u32(unsigned offset) const throw (Bounds) { +inline uint32_t Data::u32(unsigned offset) const { if (offset + 3 >= static_cast(_str.length()) || offset + 3 < 3) throw Bounds(); else return u32_aligned16(_str.udata() + offset); } -inline int32_t Data::s32(unsigned offset) const throw (Bounds) { +inline int32_t Data::s32(unsigned offset) const { if (offset + 3 >= static_cast(_str.length()) || offset + 3 < 3) throw Bounds(); else return s32_aligned16(_str.udata() + offset); } -inline uint8_t Data::operator[](int offset) const throw (Bounds) { +inline uint8_t Data::operator[](int offset) const { return (*this)[unsigned(offset)]; } -inline uint16_t Data::u16(int offset) const throw (Bounds) { +inline uint16_t Data::u16(int offset) const { return u16(unsigned(offset)); } -inline int16_t Data::s16(int offset) const throw (Bounds) { +inline int16_t Data::s16(int offset) const { return s16(unsigned(offset)); } -inline uint32_t Data::u32(int offset) const throw (Bounds) { +inline uint32_t Data::u32(int offset) const { return u32(unsigned(offset)); } -inline int32_t Data::s32(int offset) const throw (Bounds) { +inline int32_t Data::s32(int offset) const { return s32(unsigned(offset)); } -inline Data Data::substring(int left, int len) const throw () { +inline Data Data::substring(int left, int len) const noexcept { return Data(_str.substring(left, len)); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgpos.hh 2018-02-23 12:47:54.077972103 -0500 @@ -9,7 +9,7 @@ class Positioning; class Gpos { public: - Gpos(const Data &, ErrorHandler * = 0) throw (Error); + Gpos(const Data &, ErrorHandler * = 0); // default destructor const ScriptList &script_list() const { return _script_list; } @@ -29,7 +29,7 @@ class Gpos { public: }; class GposLookup { public: - GposLookup(const Data &) throw (Error); + GposLookup(const Data &); int type() const { return _type; } uint16_t flags() const { return _d.u16(2); } bool unparse_automatics(Vector &, ErrorHandler * = 0) const; @@ -66,9 +66,9 @@ class GposValue { public: }; class GposSingle { public: - GposSingle(const Data &) throw (Error); + GposSingle(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; void unparse(Vector &) const; enum { F2_HEADERSIZE = 8 }; private: @@ -76,9 +76,9 @@ class GposSingle { public: }; class GposPair { public: - GposPair(const Data &) throw (Error); + GposPair(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; void unparse(Vector &) const; enum { F1_HEADERSIZE = 10, F1_RECSIZE = 2, PAIRSET_HEADERSIZE = 2, PAIRVALUE_HEADERSIZE = 2, diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfgsub.hh 2018-02-23 12:47:54.077972103 -0500 @@ -9,7 +9,7 @@ class Substitution; class Gsub { public: - Gsub(const Data &, const Font *, ErrorHandler * = 0) throw (Error); + Gsub(const Data &, const Font *, ErrorHandler * = 0); // default destructor const ScriptList &script_list() const { return _script_list; } @@ -31,7 +31,7 @@ class Gsub { public: }; class GsubLookup { public: - GsubLookup(const Data &) throw (Error); + GsubLookup(const Data &); int type() const { return _type; } uint16_t flags() const { return _d.u16(2); } void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; @@ -49,9 +49,9 @@ class GsubLookup { public: }; class GsubSingle { public: - GsubSingle(const Data &) throw (Error); + GsubSingle(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; Glyph map(Glyph) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &subs, const Coverage &limit) const; @@ -62,9 +62,9 @@ class GsubSingle { public: }; class GsubMultiple { public: - GsubMultiple(const Data &) throw (Error); + GsubMultiple(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; bool map(Glyph, Vector &) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &, bool alternate = false) const; @@ -76,9 +76,9 @@ class GsubMultiple { public: }; class GsubLigature { public: - GsubLigature(const Data &) throw (Error); + GsubLigature(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; bool map(const Vector &, Glyph &, int &) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &) const; @@ -91,9 +91,9 @@ class GsubLigature { public: }; class GsubContext { public: - GsubContext(const Data &) throw (Error); + GsubContext(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; bool unparse(const Gsub &gsub, Vector &out_subs, const Coverage &limit) const; enum { F3_HSIZE = 6, SUBRECSIZE = 4 }; @@ -113,9 +113,9 @@ class GsubContext { public: }; class GsubChainContext { public: - GsubChainContext(const Data &) throw (Error); + GsubChainContext(const Data &); // default destructor - Coverage coverage() const throw (); + Coverage coverage() const noexcept; void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; bool unparse(const Gsub &gsub, Vector &subs, const Coverage &limit) const; enum { F1_HEADERSIZE = 6, F1_RECSIZE = 2, @@ -199,7 +199,7 @@ class Substitution { public: void add_outer_left(Glyph); void remove_outer_left(); Substitution in_out_append_glyph(Glyph) const; - bool out_alter(const Substitution &, int) throw (); + bool out_alter(const Substitution &, int) noexcept; void add_outer_right(Glyph); void remove_outer_right(); @@ -238,14 +238,14 @@ class Substitution { public: 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 &, 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 Glyph extract_glyph(const Substitute &, uint8_t) noexcept; + static Glyph extract_glyph(const Substitute &, int which, uint8_t) noexcept; + static bool extract_glyphs(const Substitute &, uint8_t, Vector &, bool coverage_ok) noexcept; + static Glyph *extract_glyphptr(const Substitute &, uint8_t) noexcept; + static int extract_nglyphs(const Substitute &, uint8_t, bool coverage_ok) noexcept; + static bool matches(const Substitute &, uint8_t, int pos, Glyph) noexcept; - static void unparse_glyphids(StringAccum &, const Substitute &, uint8_t, const Vector *) throw (); + static void unparse_glyphids(StringAccum &, const Substitute &, uint8_t, const Vector *) noexcept; }; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otf.hh 2018-02-23 12:47:54.077972103 -0500 @@ -142,23 +142,23 @@ class FeatureList { class Coverage { public: - Coverage() throw (); // empty coverage - Coverage(Glyph first, Glyph last) throw (); // range coverage - Coverage(const Vector &gmap) throw (); // used-bytemap coverage - Coverage(const String &str, ErrorHandler *errh = 0, bool check = true) throw (); + Coverage() noexcept; // empty coverage + Coverage(Glyph first, Glyph last) noexcept; // range coverage + Coverage(const Vector &gmap) noexcept; // used-bytemap coverage + Coverage(const String &str, ErrorHandler *errh = 0, bool check = true) noexcept; // default destructor - bool ok() const throw () { return _str.length() > 0; } - int size() const throw (); - bool has_fast_covers() const throw () { + bool ok() const noexcept { return _str.length() > 0; } + int size() const noexcept; + bool has_fast_covers() const noexcept { 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; } + int coverage_index(Glyph) const noexcept; + bool covers(Glyph g) const noexcept { return coverage_index(g) >= 0; } - void unparse(StringAccum&) const throw (); - String unparse() const throw (); + void unparse(StringAccum&) const noexcept; + String unparse() const noexcept; class iterator { public: iterator() : _pos(0), _value(0) { } @@ -194,7 +194,7 @@ class Coverage { iterator begin() const { return iterator(_str, false); } iterator end() const { return iterator(_str, true); } - Glyph operator[](int) const throw (); + Glyph operator[](int) const noexcept; enum { T_LIST = 1, T_RANGES = 2, T_X_BYTEMAP = 3, HEADERSIZE = 4, LIST_RECSIZE = 2, RANGES_RECSIZE = 6 }; @@ -238,17 +238,17 @@ class GlyphSet { class ClassDef { public: - ClassDef(const String&, ErrorHandler* = 0) throw (); + ClassDef(const String&, ErrorHandler* = 0) noexcept; // default destructor bool ok() const { return _str.length() > 0; } - int nclass() const throw (); + int nclass() const noexcept; - int lookup(Glyph) const throw (); - int operator[](Glyph g) const throw () { return lookup(g); } + int lookup(Glyph) const noexcept; + int operator[](Glyph g) const noexcept { return lookup(g); } - void unparse(StringAccum&) const throw (); - String unparse() const throw (); + void unparse(StringAccum&) const noexcept; + String unparse() const noexcept; class class_iterator { public: diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/otfos2.hh 2018-02-23 12:47:54.077972103 -0500 @@ -25,15 +25,15 @@ class Os2 { public: 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 (); + inline int16_t typo_ascender() const; + inline int16_t typo_descender() const; + inline int16_t typo_line_gap() const; + inline int16_t x_height() const; + inline int16_t cap_height() const; + inline double lower_optical_point_size() const; + inline double upper_optical_point_size() const; + inline bool has_optical_point_size() const noexcept; + inline String vendor_id() const noexcept; private: @@ -45,47 +45,47 @@ class Os2 { public: }; -inline int16_t Os2::typo_ascender() const throw (Bounds) +inline int16_t Os2::typo_ascender() const { return _data.s16(O_TYPOASCENDER); } -inline int16_t Os2::typo_descender() const throw (Bounds) +inline int16_t Os2::typo_descender() const { return _data.s16(O_TYPODESCENDER); } -inline int16_t Os2::typo_line_gap() const throw (Bounds) +inline int16_t Os2::typo_line_gap() const { return _data.s16(O_TYPOLINEGAP); } -inline int16_t Os2::x_height() const throw (Bounds) +inline int16_t Os2::x_height() const { return _data.s16(O_XHEIGHT); } -inline int16_t Os2::cap_height() const throw (Bounds) +inline int16_t Os2::cap_height() const { return _data.s16(O_CAPHEIGHT); } -inline double Os2::lower_optical_point_size() const throw (Bounds) +inline double Os2::lower_optical_point_size() const { return _data.u16(O_LOWEROPTICALPOINTSIZE) / 20.; } -inline double Os2::upper_optical_point_size() const throw (Bounds) +inline double Os2::upper_optical_point_size() const { return _data.u16(O_UPPEROPTICALPOINTSIZE) / 20.; } -inline bool Os2::has_optical_point_size() const throw () +inline bool Os2::has_optical_point_size() const noexcept { return _data.length() >= O_UPPEROPTICALPOINTSIZE + 2; } -inline String Os2::vendor_id() const throw () +inline String Os2::vendor_id() const noexcept { return _data.substring(O_VENDORID, 4).string(); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/t1bounds.hh 2018-02-23 12:47:54.077972103 -0500 @@ -31,8 +31,9 @@ class CharstringBounds : public Charstri 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; + // output: [left, bottom, right, top] + 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&, diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/efont/ttfkern.hh 2018-02-23 12:47:54.078972078 -0500 @@ -6,7 +6,7 @@ namespace Efont { namespace OpenType { class KernTable { public: - KernTable(const Data &, ErrorHandler * = 0) throw (Error); + KernTable(const Data &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } @@ -34,7 +34,7 @@ class KernTable { public: inline uint32_t first_offset() const { return _version == 0 ? 4 : 8; } - inline Data subtable(uint32_t &off) const throw (Error); + inline Data subtable(uint32_t &off) const; }; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/bezier.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/bezier.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/bezier.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/bezier.hh 2018-02-23 12:47:54.078972078 -0500 @@ -8,30 +8,30 @@ class Bezier { public: Bezier() : _bb(-1) { } - inline Bezier(Point p[4]) throw (); - inline Bezier(const Point &, const Point &, const Point &, const Point &) throw (); + inline Bezier(Point p[4]) noexcept; + inline Bezier(const Point &, const Point &, const Point &, const Point &) noexcept; const Point *points() const { return _p; } const Point &point(int i) const { assert(i>=0&&i<4); return _p[i]; } Point &mpoint(int i) { assert(i>=0&&i<4); _bb = -1; return _p[i]; } void set_point(int i, const Point &p) { mpoint(i) = p; } - Point eval(double) const throw (); - bool is_flat(double) const throw (); - bool in_bb(const Point &, double) const throw (); - bool hit(const Point &, double) const throw (); - - inline double bb_left() const throw (); - inline double bb_right() const throw (); - inline double bb_top() const throw (); - inline double bb_bottom() const throw (); - - inline double bb_left_x() const throw (); - inline double bb_right_x() const throw (); - inline double bb_top_x() const throw (); - inline double bb_bottom_x() const throw (); + Point eval(double) const noexcept; + bool is_flat(double) const noexcept; + bool in_bb(const Point &, double) const noexcept; + bool hit(const Point &, double) const noexcept; + + inline double bb_left() const noexcept; + inline double bb_right() const noexcept; + inline double bb_top() const noexcept; + inline double bb_bottom() const noexcept; + + inline double bb_left_x() const noexcept; + inline double bb_right_x() const noexcept; + inline double bb_top_x() const noexcept; + inline double bb_bottom_x() const noexcept; - void halve(Bezier &, Bezier &) const throw (); + void halve(Bezier &, Bezier &) const noexcept; inline void segmentize(Vector &) const; void segmentize(Vector &, bool) const; @@ -43,23 +43,23 @@ class Bezier { public: Point _p[4]; mutable int _bb; - void make_bb() const throw (); - inline void ensure_bb() const throw (); + void make_bb() const noexcept; + inline void ensure_bb() const noexcept; - double hit_recurse(const Point &, double, double, double, double, double) const throw (); + double hit_recurse(const Point &, double, double, double, double, double) const noexcept; }; inline -Bezier::Bezier(Point p[4]) throw () +Bezier::Bezier(Point p[4]) noexcept : _bb(-1) { memcpy(_p, p, sizeof(Point) * 4); } inline -Bezier::Bezier(const Point &p0, const Point &p1, const Point &p2, const Point &p3) throw () +Bezier::Bezier(const Point &p0, const Point &p1, const Point &p2, const Point &p3) noexcept { _p[0] = p0; _p[1] = p1; @@ -69,59 +69,59 @@ Bezier::Bezier(const Point &p0, const Po } inline void -Bezier::ensure_bb() const throw () +Bezier::ensure_bb() const noexcept { if (_bb < 0) make_bb(); } inline double -Bezier::bb_top_x() const throw () +Bezier::bb_top_x() const noexcept { return _p[(_bb >> 4) & 3].y; } inline double -Bezier::bb_left_x() const throw () +Bezier::bb_left_x() const noexcept { return _p[(_bb >> 2) & 3].x; } inline double -Bezier::bb_bottom_x() const throw () +Bezier::bb_bottom_x() const noexcept { return _p[(_bb >> 6) & 3].y; } inline double -Bezier::bb_right_x() const throw () +Bezier::bb_right_x() const noexcept { return _p[(_bb >> 0) & 3].x; } inline double -Bezier::bb_top() const throw () +Bezier::bb_top() const noexcept { ensure_bb(); return bb_top_x(); } inline double -Bezier::bb_left() const throw () +Bezier::bb_left() const noexcept { ensure_bb(); return bb_left_x(); } inline double -Bezier::bb_bottom() const throw () +Bezier::bb_bottom() const noexcept { ensure_bb(); return bb_bottom_x(); } inline double -Bezier::bb_right() const throw () +Bezier::bb_right() const noexcept { ensure_bb(); return bb_right_x(); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/clp.h.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/clp.h --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/clp.h.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/clp.h 2018-02-23 12:47:54.078972078 -0500 @@ -8,7 +8,7 @@ extern "C" { /* clp.h - Public interface to CLP. * This file is part of CLP, the command line parser package. * - * Copyright (c) 1997-2016 Eddie Kohler, ekohler@gmail.com + * Copyright (c) 1997-2018 Eddie Kohler, ekohler@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/point.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/point.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/point.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/point.hh 2018-02-23 12:47:54.078972078 -0500 @@ -14,28 +14,28 @@ struct Point { Point(const Point &p, double dx, double dy) : x(p.x + dx), y(p.y + dy) { } // ~Point() use compiler default - inline double squared_length() const throw (); - inline double length() const throw (); - inline double magnitude() const throw (); - static inline double distance(const Point &, const Point &) throw (); - static inline double dot(const Point &, const Point &) throw (); - static Point midpoint(const Point &, const Point &) throw (); + inline double squared_length() const noexcept; + inline double length() const noexcept; + inline double magnitude() const noexcept; + static inline double distance(const Point &, const Point &) noexcept; + static inline double dot(const Point &, const Point &) noexcept; + static Point midpoint(const Point &, const Point &) noexcept; - inline double angle() const throw (); + inline double angle() const noexcept; void shift(double dx, double dy) { x += dx; y += dy; } - inline Point shifted(double dx, double dy) const throw (); - Point rotated(double) const throw (); - inline Point normal() const throw (); - - bool on_line(const Point &, const Point &, double) const throw (); - bool on_segment(const Point &, const Point &, double) const throw (); - - inline Point &operator+=(const Point &) throw (); - inline Point &operator-=(const Point &) throw (); - inline Point &operator*=(double) throw (); - inline Point &operator/=(double) throw (); + inline Point shifted(double dx, double dy) const noexcept; + Point rotated(double) const noexcept; + inline Point normal() const noexcept; + + bool on_line(const Point &, const Point &, double) const noexcept; + bool on_segment(const Point &, const Point &, double) const noexcept; + + inline Point &operator+=(const Point &) noexcept; + inline Point &operator-=(const Point &) noexcept; + inline Point &operator*=(double) noexcept; + inline Point &operator/=(double) noexcept; // Point operator+(Point, const Point &); // Point operator-(Point, const Point &); @@ -49,44 +49,44 @@ struct Point { }; inline double -Point::squared_length() const throw () +Point::squared_length() const noexcept { return x*x + y*y; } inline double -Point::length() const throw () +Point::length() const noexcept { return sqrt(x*x + y*y); } inline double -Point::magnitude() const throw () +Point::magnitude() const noexcept { return length(); } inline double -Point::angle() const throw () +Point::angle() const noexcept { return atan2(y, x); } inline Point -Point::shifted(double dx, double dy) const throw () +Point::shifted(double dx, double dy) const noexcept { return Point(x + dx, y + dy); } inline Point -Point::normal() const throw () +Point::normal() const noexcept { double l = length(); return (l ? Point(x/l, y/l) : *this); } inline Point & -Point::operator+=(const Point &p) throw () +Point::operator+=(const Point &p) noexcept { x += p.x; y += p.y; @@ -94,7 +94,7 @@ Point::operator+=(const Point &p) throw } inline Point & -Point::operator-=(const Point &p) throw () +Point::operator-=(const Point &p) noexcept { x -= p.x; y -= p.y; @@ -102,7 +102,7 @@ Point::operator-=(const Point &p) throw } inline Point & -Point::operator*=(double d) throw () +Point::operator*=(double d) noexcept { x *= d; y *= d; @@ -110,7 +110,7 @@ Point::operator*=(double d) throw () } inline Point & -Point::operator/=(double d) throw () +Point::operator/=(double d) noexcept { x /= d; y /= d; @@ -118,66 +118,66 @@ Point::operator/=(double d) throw () } inline bool -operator==(const Point &a, const Point &b) throw () +operator==(const Point &a, const Point &b) noexcept { return a.x == b.x && a.y == b.y; } inline bool -operator!=(const Point &a, const Point &b) throw () +operator!=(const Point &a, const Point &b) noexcept { return a.x != b.x || a.y != b.y; } inline Point -operator+(Point a, const Point &b) throw () +operator+(Point a, const Point &b) noexcept { a += b; return a; } inline Point -operator-(Point a, const Point &b) throw () +operator-(Point a, const Point &b) noexcept { a -= b; return a; } inline Point -operator-(const Point &a) throw () +operator-(const Point &a) noexcept { return Point(-a.x, -a.y); } inline Point -operator*(Point a, double scale) throw () +operator*(Point a, double scale) noexcept { a *= scale; return a; } inline Point -operator*(double scale, Point a) throw () +operator*(double scale, Point a) noexcept { a *= scale; return a; } inline Point -operator/(Point a, double scale) throw () +operator/(Point a, double scale) noexcept { a /= scale; return a; } inline double -Point::distance(const Point &a, const Point &b) throw () +Point::distance(const Point &a, const Point &b) noexcept { return (a - b).length(); } inline double -Point::dot(const Point &a, const Point &b) throw () +Point::dot(const Point &a, const Point &b) noexcept { return a.x*b.x + a.y*b.y; } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/straccum.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/straccum.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/straccum.hh.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/straccum.hh 2018-02-23 12:47:54.078972078 -0500 @@ -20,143 +20,41 @@ template class Vector; class StringAccum { public: - /** @brief Construct an empty StringAccum (with length 0). */ - StringAccum() - : _s(0), _len(0), _cap(0) { - } - - /** @brief Construct a StringAccum with room for at least @a capacity - * characters. - * @param capacity initial capacity - * - * If @a capacity <= 0, the StringAccum is created empty. If @a capacity - * is too large (so that @a capacity bytes of memory can't be allocated), - * the StringAccum falls back to a smaller capacity (possibly zero). */ - explicit inline StringAccum(int capacity); - - /** @brief Construct a StringAccum containing the characters in @a s. */ - explicit inline StringAccum(const char *cstr) - : _s(0), _len(0), _cap(0) { - append(cstr); - } - - /** @brief Construct a StringAccum containing the characters in @a s. */ - inline StringAccum(const char *s, int len) - : _s(0), _len(0), _cap(0) { - append(s, len); - } - - /** @brief Construct a StringAccum containing the characters in @a str. */ - StringAccum(const String &str) - : _s(0), _len(0), _cap(0) { - append(str.begin(), str.end()); - } - - /** @brief Construct a StringAccum containing a copy of @a x. */ - StringAccum(const StringAccum &x) - : _s(0), _len(0), _cap(0) { - append(x.data(), x.length()); - } - - /** @brief Destroy a StringAccum, freeing its memory. */ - ~StringAccum() { - if (_cap > 0) - delete[] (_s - MEMO_SPACE); - } - - - /** @brief Return the contents of the StringAccum. - * @return The StringAccum's contents. - * - * The return value is null if the StringAccum is empty or out-of-memory. - * The returned data() value points to writable memory (unless the - * StringAccum itself is const). */ - inline const char *data() const { - return reinterpret_cast(_s); - } - - /** @overload */ - inline char *data() { - return reinterpret_cast(_s); - } + typedef const char* const_iterator; + typedef char* iterator; - inline const unsigned char* udata() const { - return _s; - } - - inline unsigned char* udata() { - return _s; - } - - /** @brief Return true iff the StringAccum is empty or out-of-memory. */ - bool empty() const { - return _len == 0; - } - - /** @brief Return the length of the StringAccum. */ - int length() const { - return _len; - } - - /** @brief Return the StringAccum's current capacity. - * - * The capacity is the maximum length the StringAccum can hold without - * incurring a memory allocation. Returns -1 for out-of-memory - * StringAccums. */ - int capacity() const { - return _cap; - } - - - typedef const char *const_iterator; - typedef char *iterator; - - /** @brief Return an iterator for the first character in the StringAccum. - * - * StringAccum iterators are simply pointers into string data, so they are - * quite efficient. @sa StringAccum::data */ - inline const_iterator begin() const { - return reinterpret_cast(_s); - } - - /** @overload */ - inline iterator begin() { - return reinterpret_cast(_s); - } - - /** @brief Return an iterator for the end of the StringAccum. - * - * The return value points one character beyond the last character in the - * StringAccum. */ - inline StringAccum::const_iterator end() const { - return reinterpret_cast(_s + _len); - } - - /** @overload */ - inline iterator end() { - return reinterpret_cast(_s + _len); - } + typedef int (StringAccum::*unspecified_bool_type)() const; + inline StringAccum(); + explicit inline StringAccum(int capacity); + explicit inline StringAccum(const char *cstr); + inline StringAccum(const char* s, int len); + inline StringAccum(const String& str); + inline StringAccum(const StringAccum& x); + inline ~StringAccum(); + + inline const char* data() const; + inline char* data(); + inline const unsigned char* udata() const; + inline unsigned char* udata(); + inline int length() const; + inline int capacity() const; + + inline bool empty() const; + inline bool operator!() const; + inline bool out_of_memory() const; + + inline const_iterator begin() const; + inline iterator begin(); + inline const_iterator end() const; + inline iterator end(); - typedef int (StringAccum::*unspecified_bool_type)() const; /** @brief Return true iff the StringAccum contains characters. * * Returns false for empty and out-of-memory StringAccums. */ - operator unspecified_bool_type() const { - return _len != 0 ? &StringAccum::capacity : 0; - } - - /** @brief Return true iff the StringAccum does not contain characters. - * - * Returns true for empty and out-of-memory StringAccums. */ - bool operator!() const { - return _len == 0; - } - - /** @brief Return true iff the StringAccum is out-of-memory. */ - bool out_of_memory() const { - return _cap < 0; + inline operator unspecified_bool_type() const { + return _len != 0 ? &StringAccum::capacity : 0; } @@ -169,182 +67,44 @@ class StringAccum { public: const char *c_str(); - /** @brief Return the ith character in the string. - * @param i character index - * @pre 0 <= @a i < length() */ - char operator[](int i) const { - assert((unsigned) i < (unsigned) _len); - return static_cast(_s[i]); - } - - /** @brief Return a reference to the ith character in the string. - * @param i character index - * @pre 0 <= @a i < length() */ - char &operator[](int i) { - assert((unsigned) i < (unsigned) _len); - return reinterpret_cast(_s[i]); - } - - /** @brief Return the first character in the string. - * @pre length() > 0 */ - char front() const { - assert(_len > 0); - return static_cast(_s[0]); - } + inline char operator[](int i) const; + inline char& operator[](int i); + inline char front() const; + inline char& front(); + inline char back() const; + inline char& back(); - /** @brief Return a reference to the first character in the string. - * @pre length() > 0 */ - char &front() { - assert(_len > 0); - return reinterpret_cast(_s[0]); - } - - /** @brief Return the last character in the string. - * @pre length() > 0 */ - char back() const { - assert(_len > 0); - return static_cast(_s[_len - 1]); - } - - /** @brief Return a reference to the last character in the string. - * @pre length() > 0 */ - char &back() { - assert(_len > 0); - return reinterpret_cast(_s[_len - 1]); - } + inline void clear(); - - /** @brief Clear the StringAccum's comments. - * - * All characters in the StringAccum are erased. Also resets the - * StringAccum's out-of-memory status. */ - inline void clear() { - if (_cap < 0) { - _cap = 0; - _s = 0; - } - _len = 0; - } - - - /** @brief Reserve space for at least @a n characters. - * @return a pointer to at least @a n characters, or null if allocation - * fails - * @pre @a n >= 0 - * - * reserve() does not change the string's length(), only its capacity(). - * In a frequent usage pattern, code calls reserve(), passing an upper - * bound on the characters that could be written by a series of - * operations. After writing into the returned buffer, adjust_length() is - * called to account for the number of characters actually written. - * - * On failure, null is returned and errno is set to ENOMEM. */ - inline char *reserve(int n) { - assert(n >= 0); - if (_len + n <= _cap) - return reinterpret_cast(_s + _len); - else - return grow(_len + n); - } - - /** @brief Set the StringAccum's length to @a len. - * @param len new length in characters - * @pre 0 <= @a len <= capacity() - * @sa adjust_length */ - inline void set_length(int len) { - assert(len >= 0 && _len <= _cap); - _len = len; - } + inline char* reserve(int n); + inline void set_length(int len); /** @brief Set the StringAccum's length to @a len. * @pre @a len >= 0 * @return 0 on success, -ENOMEM on failure */ int resize(int len); - /** @brief Adjust the StringAccum's length. - * @param delta length adjustment - * @pre If @a delta > 0, then length() + @a delta <= capacity(). - * If @a delta < 0, then length() + delta >= 0. - * - * The StringAccum's length after adjust_length(@a delta) equals its old - * length plus @a delta. Generally adjust_length() is used after a call - * to reserve(). @sa set_length */ - inline void adjust_length(int delta) { - assert(_len + delta >= 0 && _len + delta <= _cap); - _len += delta; - } - - /** @brief Reserve space and adjust length in one operation. - * @param nadjust number of characters to reserve and adjust length - * @param nreserve additional characters to reserve - * @pre @a nadjust >= 0 and @a nreserve >= 0 - * - * This operation combines the effects of reserve(@a nadjust + @a - * nreserve) and adjust_length(@a nadjust). Returns the result of the - * reserve() call. */ - inline char *extend(int nadjust, int nreserve = 0) { - assert(nadjust >= 0 && nreserve >= 0); - if (_len + nadjust + nreserve <= _cap) { - char *x = reinterpret_cast(_s + _len); - _len += nadjust; - return x; - } else - return hard_extend(nadjust, nreserve); - } - - - /** @brief Remove characters from the end of the StringAccum. - * @param n number of characters to remove - * @pre @a n >= 0 and @a n <= length() - * - * Same as adjust_length(-@a n). */ - inline void pop_back(int n = 1) { - assert(n >= 0 && _len >= n); - _len -= n; - } + inline void adjust_length(int delta); + inline char* extend(int nadjust, int nreserve = 0); + inline void pop_back(int n = 1); - /** @brief Append character @a c to the StringAccum. - * @param c character to append */ - inline void append(char c) { - if (_len < _cap || grow(_len)) - _s[_len++] = c; - } - /** @overload */ - inline void append(unsigned char c) { - append(static_cast(c)); - } + inline void append(char c); + inline void append(unsigned char c); /** @brief Append @a len copies of character @a c to the StringAccum. */ void append_fill(int c, int len); - /** @brief Append the UTF-8 encoding of Unicode character @a ch. */ - inline void append_utf8(unsigned ch) { - if (ch < 0x80) - append((unsigned char) ch); - else - append_utf8_hard(ch); - } + inline void append_utf8(unsigned ch); /** @brief Append the null-terminated C string @a s to this StringAccum. * @param s data to append */ - void append(const char *s); - /** @brief Append the first @a len characters of @a s to this StringAccum. - * @param s data to append - * @param len length of data - * @pre @a len >= 0 */ - inline void append(const char *s, int len); - /** @overload */ - inline void append(const unsigned char *s, int len); - - /** @brief Append the data from @a begin to @a end to the end of this - * StringAccum. - * - * Does nothing if @a begin >= @a end. */ - inline void append(const char *begin, const char *end); - /** @overload */ - inline void append(const unsigned char *begin, const unsigned char *end); + void append(const char* s); + inline void append(const char* s, int len); + inline void append(const unsigned char* s, int len); + inline void append(const char* begin, const char* end); + inline void append(const unsigned char* begin, const unsigned char* end); // word joining void append_break_lines(const String &text, int linelen, const String &leftmargin = String()); @@ -374,16 +134,7 @@ class StringAccum { public: String take_string(); - /** @brief Assign this StringAccum to @a x. */ - StringAccum &operator=(const StringAccum &x) { - if (&x != this) { - if (out_of_memory()) - _s = 0, _cap = 0; - _len = 0; - append(x.data(), x.length()); - } - return *this; - } + inline StringAccum& operator=(const StringAccum& x); /** @brief Swap this StringAccum's contents with @a x. */ void swap(StringAccum &x); @@ -393,7 +144,7 @@ class StringAccum { public: private: enum { - MEMO_SPACE = String::MEMO_SPACE + MEMO_SPACE = String::MEMO_SPACE }; unsigned char *_s; @@ -434,42 +185,329 @@ StringAccum &operator<<(StringAccum &, u StringAccum &operator<<(StringAccum &, double); -inline -StringAccum::StringAccum(int capacity) - : _len(0) -{ +/** @brief Construct an empty StringAccum (with length 0). */ +inline StringAccum::StringAccum() + : _s(0), _len(0), _cap(0) { +} + +/** @brief Construct a StringAccum with room for at least @a capacity + * characters. + * @param capacity initial capacity + * + * If @a capacity <= 0, the StringAccum is created empty. If @a capacity + * is too large (so that @a capacity bytes of memory can't be allocated), + * the StringAccum falls back to a smaller capacity (possibly zero). */ +inline StringAccum::StringAccum(int capacity) + : _len(0) { assert(capacity >= 0); if (capacity - && (_s = new unsigned char[capacity + MEMO_SPACE])) { - _s += MEMO_SPACE; - _cap = capacity; + && (_s = new unsigned char[capacity + MEMO_SPACE])) { + _s += MEMO_SPACE; + _cap = capacity; } else { - _s = 0; - _cap = 0; + _s = 0; + _cap = 0; } } -inline void StringAccum::append(const char *s, int len) { +/** @brief Construct a StringAccum containing the characters in @a s. */ +inline StringAccum::StringAccum(const char *cstr) + : _s(0), _len(0), _cap(0) { + append(cstr); +} + +/** @brief Construct a StringAccum containing the characters in @a s. */ +inline StringAccum::StringAccum(const char *s, int len) + : _s(0), _len(0), _cap(0) { + append(s, len); +} + +/** @brief Construct a StringAccum containing the characters in @a str. */ +inline StringAccum::StringAccum(const String &str) + : _s(0), _len(0), _cap(0) { + append(str.begin(), str.end()); +} + +/** @brief Construct a StringAccum containing a copy of @a x. */ +inline StringAccum::StringAccum(const StringAccum &x) + : _s(0), _len(0), _cap(0) { + append(x.data(), x.length()); +} + +/** @brief Destroy a StringAccum, freeing its memory. */ +inline StringAccum::~StringAccum() { + if (_cap > 0) + delete[] (_s - MEMO_SPACE); +} + +/** @brief Return the contents of the StringAccum. + * @return The StringAccum's contents. + * + * The return value is null if the StringAccum is empty or out-of-memory. + * The returned data() value points to writable memory (unless the + * StringAccum itself is const). */ +inline const char* StringAccum::data() const { + return reinterpret_cast(_s); +} + +/** @overload */ +inline char* StringAccum::data() { + return reinterpret_cast(_s); +} + +inline const unsigned char* StringAccum::udata() const { + return _s; +} + +inline unsigned char* StringAccum::udata() { + return _s; +} + +/** @brief Return true iff the StringAccum is empty or out-of-memory. */ +inline bool StringAccum::empty() const { + return _len == 0; +} + +/** @brief Return the length of the StringAccum. */ +inline int StringAccum::length() const { + return _len; +} + +/** @brief Return the StringAccum's current capacity. + * + * The capacity is the maximum length the StringAccum can hold without + * incurring a memory allocation. Returns -1 for out-of-memory + * StringAccums. */ +inline int StringAccum::capacity() const { + return _cap; +} + +/** @brief Return an iterator for the first character in the StringAccum. + * + * StringAccum iterators are simply pointers into string data, so they are + * quite efficient. @sa StringAccum::data */ +inline StringAccum::const_iterator StringAccum::begin() const { + return reinterpret_cast(_s); +} + +/** @overload */ +inline StringAccum::iterator StringAccum::begin() { + return reinterpret_cast(_s); +} + +/** @brief Return an iterator for the end of the StringAccum. + * + * The return value points one character beyond the last character in the + * StringAccum. */ +inline StringAccum::const_iterator StringAccum::end() const { + return reinterpret_cast(_s + _len); +} + +/** @overload */ +inline StringAccum::iterator StringAccum::end() { + return reinterpret_cast(_s + _len); +} + +/** @brief Return true iff the StringAccum does not contain characters. + * + * Returns true for empty and out-of-memory StringAccums. */ +inline bool StringAccum::operator!() const { + return _len == 0; +} + +/** @brief Return true iff the StringAccum is out-of-memory. */ +inline bool StringAccum::out_of_memory() const { + return _cap < 0; +} + +/** @brief Return the ith character in the string. + * @param i character index + * @pre 0 <= @a i < length() */ +inline char StringAccum::operator[](int i) const { + assert((unsigned) i < (unsigned) _len); + return static_cast(_s[i]); +} + +/** @brief Return a reference to the ith character in the string. + * @param i character index + * @pre 0 <= @a i < length() */ +inline char& StringAccum::operator[](int i) { + assert((unsigned) i < (unsigned) _len); + return reinterpret_cast(_s[i]); +} + +/** @brief Return the first character in the string. + * @pre length() > 0 */ +inline char StringAccum::front() const { + assert(_len > 0); + return static_cast(_s[0]); +} + +/** @brief Return a reference to the first character in the string. + * @pre length() > 0 */ +inline char& StringAccum::front() { + assert(_len > 0); + return reinterpret_cast(_s[0]); +} + +/** @brief Return the last character in the string. + * @pre length() > 0 */ +inline char StringAccum::back() const { + assert(_len > 0); + return static_cast(_s[_len - 1]); +} + +/** @brief Return a reference to the last character in the string. + * @pre length() > 0 */ +inline char& StringAccum::back() { + assert(_len > 0); + return reinterpret_cast(_s[_len - 1]); +} + +/** @brief Clear the StringAccum's comments. + * + * All characters in the StringAccum are erased. Also resets the + * StringAccum's out-of-memory status. */ +inline void StringAccum::clear() { + if (_cap < 0) { + _cap = 0; + _s = 0; + } + _len = 0; +} + +/** @brief Reserve space for at least @a n characters. + * @return a pointer to at least @a n characters, or null if allocation + * fails + * @pre @a n >= 0 + * + * reserve() does not change the string's length(), only its capacity(). + * In a frequent usage pattern, code calls reserve(), passing an upper + * bound on the characters that could be written by a series of + * operations. After writing into the returned buffer, adjust_length() is + * called to account for the number of characters actually written. + * + * On failure, null is returned and errno is set to ENOMEM. */ +inline char* StringAccum::reserve(int n) { + assert(n >= 0); + if (_len + n <= _cap) + return reinterpret_cast(_s + _len); + else + return grow(_len + n); +} + +/** @brief Set the StringAccum's length to @a len. + * @param len new length in characters + * @pre 0 <= @a len <= capacity() + * @sa adjust_length */ +inline void StringAccum::set_length(int len) { + assert(len >= 0 && _len <= _cap); + _len = len; +} + +/** @brief Adjust the StringAccum's length. + * @param delta length adjustment + * @pre If @a delta > 0, then length() + @a delta <= capacity(). + * If @a delta < 0, then length() + delta >= 0. + * + * The StringAccum's length after adjust_length(@a delta) equals its old + * length plus @a delta. Generally adjust_length() is used after a call + * to reserve(). @sa set_length */ +inline void StringAccum::adjust_length(int delta) { + assert(_len + delta >= 0 && _len + delta <= _cap); + _len += delta; +} + +/** @brief Reserve space and adjust length in one operation. + * @param nadjust number of characters to reserve and adjust length + * @param nreserve additional characters to reserve + * @pre @a nadjust >= 0 and @a nreserve >= 0 + * + * This operation combines the effects of reserve(@a nadjust + @a + * nreserve) and adjust_length(@a nadjust). Returns the result of the + * reserve() call. */ +inline char* StringAccum::extend(int nadjust, int nreserve) { + assert(nadjust >= 0 && nreserve >= 0); + if (_len + nadjust + nreserve <= _cap) { + char *x = reinterpret_cast(_s + _len); + _len += nadjust; + return x; + } else + return hard_extend(nadjust, nreserve); +} + +/** @brief Remove characters from the end of the StringAccum. + * @param n number of characters to remove + * @pre @a n >= 0 and @a n <= length() + * + * Same as adjust_length(-@a n). */ +inline void StringAccum::pop_back(int n) { + assert(n >= 0 && _len >= n); + _len -= n; +} + +/** @brief Append character @a c to the StringAccum. + * @param c character to append */ +inline void StringAccum::append(char c) { + if (_len < _cap || grow(_len)) + _s[_len++] = c; +} + +/** @overload */ +inline void StringAccum::append(unsigned char c) { + append(static_cast(c)); +} + +/** @brief Append the UTF-8 encoding of Unicode character @a ch. */ +inline void StringAccum::append_utf8(unsigned ch) { + if (ch < 0x80) + append((unsigned char) ch); + else + append_utf8_hard(ch); +} + +/** @brief Append the first @a len characters of @a s to this StringAccum. + * @param s data to append + * @param len length of data + * @pre @a len >= 0 */ +inline void StringAccum::append(const char* s, int len) { assert(len >= 0); if (_len + len <= _cap) { - memcpy(_s + _len, s, len); - _len += len; + memcpy(_s + _len, s, len); + _len += len; } else - hard_append(s, len); + hard_append(s, len); } -inline void StringAccum::append(const unsigned char *s, int len) { +/** @overload */ +inline void StringAccum::append(const unsigned char* s, int len) { append(reinterpret_cast(s), len); } -inline void StringAccum::append(const char *begin, const char *end) { +/** @brief Append the data from @a begin to @a end to the end of this + * StringAccum. + * + * Does nothing if @a begin >= @a end. */ +inline void StringAccum::append(const char* begin, const char* end) { if (begin < end) - append(begin, end - begin); + append(begin, end - begin); } -inline void StringAccum::append(const unsigned char *begin, const unsigned char *end) { +/** @overload */ +inline void StringAccum::append(const unsigned char* begin, const unsigned char* end) { if (begin < end) - append(begin, end - begin); + append(begin, end - begin); +} + +/** @brief Assign this StringAccum to @a x. */ +inline StringAccum& StringAccum::operator=(const StringAccum& x) { + if (&x != this) { + if (out_of_memory()) + _s = 0, _cap = 0; + _len = 0; + append(x.data(), x.length()); + } + return *this; } /** @relates StringAccum @@ -513,9 +551,9 @@ operator<<(StringAccum &sa, bool b) { static const char truefalse[] = "truefalse"; if (b) - sa.append(truefalse, 4); + sa.append(truefalse, 4); else - sa.append(truefalse + 4, 5); + sa.append(truefalse + 4, 5); return sa; } @@ -562,9 +600,9 @@ inline StringAccum & operator<<(StringAccum &sa, const String &str) { if (!str.out_of_memory()) - sa.hard_append(str.begin(), str.length()); + sa.hard_append(str.begin(), str.length()); else - sa.assign_out_of_memory(); + sa.assign_out_of_memory(); return sa; } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/vector.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/vector.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/vector.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/include/lcdf/vector.cc 2018-02-23 12:47:54.079972053 -0500 @@ -7,7 +7,7 @@ * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2003 International Computer Science Institute - * Copyright (c) 1999-2016 Eddie Kohler + * Copyright (c) 1999-2018 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/lcdf-typetools.spec.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/lcdf-typetools.spec --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/lcdf-typetools.spec.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/lcdf-typetools.spec 2018-02-23 12:47:54.079972053 -0500 @@ -1,6 +1,6 @@ Summary: Programs to manipulate OpenType and multiple-master fonts Name: lcdf-typetools -Version: 2.106 +Version: 2.107 Copyright: GPL Vendor: Little Cambridgeport Design Factory Group: Utilities/Printing diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afm.cc 2018-02-23 12:47:54.079972053 -0500 @@ -2,7 +2,7 @@ /* afm.{cc,hh} -- Adobe Font Metrics files * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmparse.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmparse.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmparse.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmparse.cc 2018-02-23 12:47:54.079972053 -0500 @@ -2,7 +2,7 @@ /* afmparse.{cc,hh} -- Adobe Font Metrics parsing * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmw.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmw.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmw.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/afmw.cc 2018-02-23 12:47:54.079972053 -0500 @@ -2,7 +2,7 @@ /* afmw.{cc,hh} -- Adobe Font Metrics writing * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/amfm.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/amfm.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/amfm.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/amfm.cc 2018-02-23 12:47:54.079972053 -0500 @@ -2,7 +2,7 @@ /* amfm.{cc,hh} -- Adobe Multiple-Master Font Metrics * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/cff.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/cff.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/cff.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/cff.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* cff.{cc,hh} -- Compact Font Format fonts * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -326,17 +326,11 @@ static const uint8_t default_dict_cff_da 0, 0 }; -static const Cff::Dict & +static const Cff::Dict& default_dict() { - static Cff *cff; - static Cff::Font *cfffont; - if (!cfffont) { - cff = new Cff(String::make_stable((const char *) default_dict_cff_data, sizeof(default_dict_cff_data)), - 0, ErrorHandler::default_handler()); - cfffont = (Cff::Font *) cff->font(); - } - return cfffont->top_dict(); + static Cff cff(String::make_stable((const char*) default_dict_cff_data, sizeof(default_dict_cff_data)), 0, ErrorHandler::default_handler()); + return static_cast(cff.font())->top_dict(); } @@ -360,6 +354,8 @@ Cff::~Cff() { for (int i = 0; i < _gsubrs_cs.size(); i++) delete _gsubrs_cs[i]; + for (int i = 0; i < _fonts.size(); ++i) + delete _fonts[i]; } /* @@ -500,25 +496,6 @@ Cff::sid_permstring(int sid) const } } -int -Cff::font_offset(int findex, int &offset, int &length) const -{ - if (findex < 0 || findex >= nfonts()) - return -ENOENT; - offset = _top_dict_index[findex] - _data; - length = _top_dict_index[findex + 1] - _top_dict_index[findex]; - return 0; -} - -int -Cff::font_offset(PermString name, int &offset, int &length) const -{ - for (int i = 0; i < _name_index.size(); i++) - if (_name_index[i] == name && name) - return font_offset(i, offset, length); - return -ENOENT; -} - Cff::FontParent * Cff::font(PermString font_name, ErrorHandler *errh) { @@ -529,24 +506,39 @@ Cff::font(PermString font_name, ErrorHan return errh->error("invalid CFF"), (FontParent *) 0; // search for a font named 'font_name' - for (int i = 0; i < _name_index.size(); i++) - if (_name_index[i] && (!font_name || font_name == _name_index[i])) { - int td_offset = _top_dict_index[i] - _data; - int td_length = _top_dict_index[i + 1] - _top_dict_index[i]; - Dict top_dict(this, td_offset, td_length, errh, "Top DICT"); - if (!top_dict.ok()) - return 0; - else if (top_dict.has_first(oROS)) - return new Cff::CIDFont(this, _name_index[i], top_dict, errh); - else - return new Cff::Font(this, _name_index[i], top_dict, errh); - } + int findex; + for (findex = 0; findex < _name_index.size(); ++findex) { + if (_name_index[findex] + && (!font_name || font_name == _name_index[findex])) + break; + } + if (findex >= _name_index.size()) { + if (!font_name) + errh->error("no fonts in CFF"); + else + errh->error("font %<%s%> not found", font_name.c_str()); + return 0; + } + + // return font + for (int i = 0; i < _fonts.size(); ++i) + if (_fonts[i]->_font_index == findex) + return _fonts[i]; + + int td_offset = _top_dict_index[findex] - _data; + int td_length = _top_dict_index[findex + 1] - _top_dict_index[findex]; + Dict top_dict(this, td_offset, td_length, errh, "Top DICT"); + if (!top_dict.ok()) + return 0; - if (!font_name) - errh->error("no fonts in CFF"); + Cff::FontParent* fp; + if (top_dict.has_first(oROS)) + fp = new Cff::CIDFont(this, _name_index[findex], top_dict, errh); else - errh->error("font %<%s%> not found", font_name.c_str()); - return 0; + fp = new Cff::Font(this, _name_index[findex], top_dict, errh); + fp->_font_index = findex; + _fonts.push_back(fp); + return fp; } static inline int diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/encoding.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/encoding.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/encoding.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/encoding.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* encoding.{cc,hh} -- 8-bit encodings * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/findmet.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/findmet.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/findmet.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/findmet.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* findmet.{cc,hh} -- find font metrics * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/metrics.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/metrics.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/metrics.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/metrics.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* metrics.{cc,hh} -- generic font metrics * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otf.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otf.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otf.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otf.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* otf.{cc,hh} -- OpenType font basics * - * Copyright (c) 2002-2016 Eddie Kohler + * Copyright (c) 2002-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -747,11 +747,11 @@ FeatureList::lookups(const ScriptList &s * * **************************/ -Coverage::Coverage() throw () +Coverage::Coverage() noexcept { } -Coverage::Coverage(Glyph first, Glyph last) throw () +Coverage::Coverage(Glyph first, Glyph last) noexcept { if (first <= last) { _str = String("\000\002\000\001\000\000\000\000\000\000", 10); @@ -764,7 +764,7 @@ Coverage::Coverage(Glyph first, Glyph la } } -Coverage::Coverage(const Vector &gmap) throw () +Coverage::Coverage(const Vector &gmap) noexcept { int end = gmap.size(); while (end > 0 && !gmap[end - 1]) @@ -790,7 +790,7 @@ Coverage::Coverage(const Vector &g } } -Coverage::Coverage(const String &str, ErrorHandler *errh, bool do_check) throw () +Coverage::Coverage(const String &str, ErrorHandler *errh, bool do_check) noexcept : _str(str) { _str.align(2); @@ -844,7 +844,7 @@ Coverage::check(ErrorHandler *errh) } int -Coverage::size() const throw () +Coverage::size() const noexcept { if (_str.length() == 0) return -1; @@ -861,7 +861,7 @@ Coverage::size() const throw () } int -Coverage::coverage_index(Glyph g) const throw () +Coverage::coverage_index(Glyph g) const noexcept { if (_str.length() == 0) return -1; @@ -906,7 +906,7 @@ Coverage::coverage_index(Glyph g) const } Glyph -Coverage::operator[](int cindex) const throw () +Coverage::operator[](int cindex) const noexcept { if (_str.length() == 0 || cindex < 0) return 0; @@ -935,7 +935,7 @@ Coverage::operator[](int cindex) const t } void -Coverage::unparse(StringAccum &sa) const throw () +Coverage::unparse(StringAccum &sa) const noexcept { const uint8_t *data = _str.udata(); if (_str.length() == 0) @@ -958,7 +958,7 @@ Coverage::unparse(StringAccum &sa) const } String -Coverage::unparse() const throw () +Coverage::unparse() const noexcept { StringAccum sa; unparse(sa); @@ -1237,7 +1237,7 @@ GlyphSet::operator=(const GlyphSet &o) * * **************************/ -ClassDef::ClassDef(const String &str, ErrorHandler *errh) throw () +ClassDef::ClassDef(const String &str, ErrorHandler *errh) noexcept : _str(str) { _str.align(2); @@ -1277,7 +1277,7 @@ ClassDef::check(ErrorHandler *errh) } int -ClassDef::lookup(Glyph g) const throw () +ClassDef::lookup(Glyph g) const noexcept { if (_str.length() == 0) return -1; @@ -1311,7 +1311,7 @@ ClassDef::lookup(Glyph g) const throw () } void -ClassDef::unparse(StringAccum &sa) const throw () +ClassDef::unparse(StringAccum &sa) const noexcept { const uint8_t *data = _str.udata(); if (_str.length() == 0) @@ -1336,7 +1336,7 @@ ClassDef::unparse(StringAccum &sa) const } String -ClassDef::unparse() const throw () +ClassDef::unparse() const noexcept { StringAccum sa; unparse(sa); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfcmap.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfcmap.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfcmap.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfcmap.cc 2018-02-23 12:47:54.080972028 -0500 @@ -2,7 +2,7 @@ /* otfcmap.{cc,hh} -- OpenType cmap table * - * Copyright (c) 2002-2016 Eddie Kohler + * Copyright (c) 2002-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -184,25 +184,27 @@ Cmap::check_table(int t, ErrorHandler *e || (searchRange>>1) > segCountX2/2 || 1 << (entrySelector + 1) != searchRange || rangeShift != segCountX2 - searchRange) - return errh->error("bad table %d segment counts (format 4)", t); + return errh->error("bad table %d segment counts (format %d)", format); uint32_t segCount = segCountX2 >> 1; if (length < 16 + 8 * segCount) - return errh->error("bad table %d length (format %d)", t, format); + return errh->error("bad table %d length (format %d, length %u, need %u)", t, format, length, 16 + 8 * segCount); const uint8_t *endCodes = data + 14; const uint8_t *startCodes = endCodes + 2 + segCountX2; const uint8_t *idDeltas = startCodes + segCountX2; const uint8_t *idRangeOffsets = idDeltas + segCountX2; + uint32_t idRangeOffsetsPos = idRangeOffsets - data; int last_end = 0; for (int i = 0; i < segCountX2; i += 2) { int endCode = USHORT_AT(endCodes + i); int startCode = USHORT_AT(startCodes + i); - /* int idDelta = SHORT_AT(idDeltas + i); // no need to check */ + /* int idDelta = SHORT_AT(idDeltas + i); // not needed */ int idRangeOffset = USHORT_AT(idRangeOffsets + i); if (endCode < startCode || startCode < last_end) return errh->error("bad table %d overlapping range %d (format %d)", t, i/2, format); if (idRangeOffset - && idRangeOffsets + i + idRangeOffset + (endCode - startCode)*2 + 2 > data + length) - return errh->error("bad table %d range %d length (format 4)", t, i/2); + && idRangeOffset != 65535 + && idRangeOffsetsPos + i + idRangeOffset + (endCode - startCode)*2 + 2 > length) + return errh->error("bad table %d range %d length (format %d, range %d-%d, idRangeOffset %d, length %u)", t, i/2, format, startCode, endCode, idRangeOffset, length); last_end = endCode + 1; } if (USHORT_AT(endCodes + segCountX2 - 2) != 0xFFFF) @@ -308,6 +310,8 @@ Cmap::map_table(int t, uint32_t uni, Err int idRangeOffset = USHORT_AT(idRangeOffsets + (m << 1)); if (idRangeOffset == 0) return (idDelta + uni) & 65535; + else if (idRangeOffset == 65535) + return 0; int g = USHORT_AT(idRangeOffsets + (m << 1) + idRangeOffset + ((uni - startCount) << 1)); if (g == 0) return 0; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdata.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdata.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdata.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdata.cc 2018-02-23 12:47:54.081972003 -0500 @@ -2,7 +2,7 @@ /* otfdata.{cc,hh} -- OpenType bounds-checked string type * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,7 +21,7 @@ namespace Efont { namespace OpenType { Data -Data::subtable(unsigned offset) const throw (Bounds) +Data::subtable(unsigned offset) const { if (offset > (unsigned) _str.length()) throw Bounds(); @@ -29,7 +29,7 @@ Data::subtable(unsigned offset) const th } Data -Data::offset_subtable(unsigned offset_offset) const throw (Bounds) +Data::offset_subtable(unsigned offset_offset) const { int offset = u16(offset_offset); if (offset > _str.length()) diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdescrip.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdescrip.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdescrip.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfdescrip.cc 2018-02-23 12:47:54.081972003 -0500 @@ -1,6 +1,6 @@ /* otfdescrip.cc -- descriptions for OpenType tags * - * Copyright (c) 2002-2016 Eddie Kohler + * Copyright (c) 2002-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgpos.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgpos.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgpos.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgpos.cc 2018-02-23 12:47:54.081972003 -0500 @@ -2,7 +2,7 @@ /* otfgpos.{cc,hh} -- OpenType GPOS table * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -32,7 +32,7 @@ namespace Efont { namespace OpenType { * * **************************/ -Gpos::Gpos(const Data &d, ErrorHandler *errh) throw (Error) +Gpos::Gpos(const Data &d, ErrorHandler *errh) { // Fixed Version // Offset ScriptList @@ -79,7 +79,7 @@ const int GposValue::nibble_bitcount_x2[ * * **************************/ -GposLookup::GposLookup(const Data &d) throw (Error) +GposLookup::GposLookup(const Data &d) : _d(d) { if (_d.length() < 6) @@ -143,7 +143,7 @@ GposLookup::unparse_automatics(Vector * * **************************/ -GposPair::GposPair(const Data &d) throw (Error) +GposPair::GposPair(const Data &d) : _d(d) { if (_d[0] != 0 @@ -196,7 +196,7 @@ GposPair::GposPair(const Data &d) throw } Coverage -GposPair::coverage() const throw () +GposPair::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgsub.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgsub.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgsub.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/otfgsub.cc 2018-02-23 12:47:54.081972003 -0500 @@ -2,7 +2,7 @@ /* otfgsub.{cc,hh} -- OpenType GSUB table * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -255,13 +255,13 @@ Substitution::context_in(const GlyphSet } Glyph -Substitution::extract_glyph(const Substitute &s, uint8_t t) throw () +Substitution::extract_glyph(const Substitute &s, uint8_t t) noexcept { return (t == T_GLYPH ? s.gid : 0); } Glyph -Substitution::extract_glyph(const Substitute &s, int which, uint8_t t) throw () +Substitution::extract_glyph(const Substitute &s, int which, uint8_t t) noexcept { switch (t) { case T_GLYPH: @@ -279,7 +279,7 @@ Substitution::extract_glyph(const Substi } bool -Substitution::extract_glyphs(const Substitute &s, uint8_t t, Vector &v, bool coverage_ok) throw () +Substitution::extract_glyphs(const Substitute &s, uint8_t t, Vector &v, bool coverage_ok) noexcept { switch (t) { case T_GLYPH: @@ -302,7 +302,7 @@ Substitution::extract_glyphs(const Subst } Glyph * -Substitution::extract_glyphptr(const Substitute &s, uint8_t t) throw () +Substitution::extract_glyphptr(const Substitute &s, uint8_t t) noexcept { switch (t) { case T_GLYPH: @@ -315,7 +315,7 @@ Substitution::extract_glyphptr(const Sub } int -Substitution::extract_nglyphs(const Substitute &s, uint8_t t, bool coverage_ok) throw () +Substitution::extract_nglyphs(const Substitute &s, uint8_t t, bool coverage_ok) noexcept { switch (t) { case T_GLYPH: @@ -330,7 +330,7 @@ Substitution::extract_nglyphs(const Subs } bool -Substitution::matches(const Substitute &s, uint8_t t, int pos, Glyph g) throw () +Substitution::matches(const Substitute &s, uint8_t t, int pos, Glyph g) noexcept { switch (t) { case T_GLYPH: @@ -461,7 +461,7 @@ Substitution::remove_outer_right() } bool -Substitution::out_alter(const Substitution &o, int pos) throw () +Substitution::out_alter(const Substitution &o, int pos) noexcept { const Glyph *g = out_glyphptr(); int ng = out_nglyphs(); @@ -490,7 +490,7 @@ Substitution::out_alter(const Substituti } static void -unparse_glyphid(StringAccum &sa, Glyph gid, const Vector *gns) throw () +unparse_glyphid(StringAccum &sa, Glyph gid, const Vector *gns) noexcept { if (gid > 0 && gns && gns->size() > gid && (*gns)[gid]) sa << (*gns)[gid]; @@ -499,7 +499,7 @@ unparse_glyphid(StringAccum &sa, Glyph g } void -Substitution::unparse_glyphids(StringAccum &sa, const Substitute &s, uint8_t t, const Vector *gns) throw () +Substitution::unparse_glyphids(StringAccum &sa, const Substitute &s, uint8_t t, const Vector *gns) noexcept { if (t == T_GLYPH) unparse_glyphid(sa, s.gid, gns); @@ -565,7 +565,7 @@ Substitution::unparse(const Vector(s.data()); _key = t1R_cs; for (int i = 0; i < lenIV; i++, d++) - _key = ((*d + _key) * t1C1 + t1C2) & 0xFFFF; + _key = ((*d + _key) * (uint32_t) t1C1 + t1C2) & 0xFFFF; _s = s.substring(lenIV); } } @@ -139,7 +139,7 @@ Type1Charstring::decrypt() const for (int i = 0; i < _s.length(); i++, d++) { uint8_t encrypted = *d; *d = encrypted ^ (r >> 8); - r = ((encrypted + r) * t1C1 + t1C2) & 0xFFFF; + r = ((encrypted + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } _key = -1; } @@ -193,7 +193,7 @@ Type1Charstring::process(CharstringInter } else { // 255: push huge number if (left < 5) goto runoff_error; - int32_t val = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; + int32_t val = ((uint32_t) data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; more = interp.number(val); ahead = 5; } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1csgen.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1csgen.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1csgen.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1csgen.cc 2018-02-23 12:47:54.082971978 -0500 @@ -2,7 +2,7 @@ /* t1csgen.{cc,hh} -- Type 1 charstring generation * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1font.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1font.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1font.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1font.cc 2018-02-23 12:47:54.082971978 -0500 @@ -2,7 +2,7 @@ /* t1font.{cc,hh} -- Type 1 font * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1fontskel.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1fontskel.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1fontskel.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1fontskel.cc 2018-02-23 12:47:54.083971953 -0500 @@ -1,6 +1,6 @@ /* t1fontskel.cc -- Type 1 font skeleton * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc 2018-02-23 12:47:54.083971953 -0500 @@ -2,7 +2,7 @@ /* t1interp.{cc,hh} -- Type 1/2 charstring interpretation * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1item.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1item.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1item.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1item.cc 2018-02-23 12:47:54.083971953 -0500 @@ -2,7 +2,7 @@ /* t1item.{cc,hh} -- items in a Type 1 font * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -731,12 +731,12 @@ Type1Subr::gen(Type1Writer &w) for (int i = 0; i < w.lenIV(); i++) { unsigned char c = (unsigned char)(r >> 8); *t++ = c; - r = ((c + r) * t1C1 + t1C2) & 0xFFFF; + r = ((c + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } for (int i = 0; i < len; i++, data++) { unsigned char c = (*data ^ (r >> 8)); *t++ = c; - r = ((c + r) * t1C1 + t1C2) & 0xFFFF; + r = ((c + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } w.print((char *)buf, len + w.lenIV()); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1mm.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1mm.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1mm.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1mm.cc 2018-02-23 12:47:54.083971953 -0500 @@ -2,7 +2,7 @@ /* t1mm.{cc,hh} -- Type 1 multiple master font information * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1rw.cc 2018-02-23 12:47:54.083971953 -0500 @@ -2,7 +2,7 @@ /* t1rw.{cc,hh} -- Type 1 font reading and writing * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -117,7 +117,7 @@ inline int Type1Reader::eexec(int c) { unsigned char answer = (unsigned char)(c ^ (_r >> 8)); - _r = (((unsigned char)c + _r) * t1C1 + t1C2) & 0xFFFF; + _r = (((unsigned char)c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; return answer; } @@ -439,7 +439,7 @@ inline unsigned char Type1Writer::eexec(int p) { unsigned char c = ((unsigned char)p ^ (_r >> 8)) & 0xFF; - _r = ((c + _r) * t1C1 + t1C2) & 0xFFFF; + _r = ((c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; return c; } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1unparser.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1unparser.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1unparser.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1unparser.cc 2018-02-23 12:47:54.083971953 -0500 @@ -2,7 +2,7 @@ /* t1unparser.{cc,hh} -- debug printing of Type 1 fonts * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfcs.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfcs.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfcs.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfcs.cc 2018-02-23 12:47:54.084971928 -0500 @@ -2,7 +2,7 @@ /* ttfcs.{cc,hh} -- TrueType "charstring" emulation * - * Copyright (c) 2006-2016 Eddie Kohler + * Copyright (c) 2006-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfhead.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfhead.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfhead.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfhead.cc 2018-02-23 12:47:54.084971928 -0500 @@ -2,7 +2,7 @@ /* ttfhead.{cc,hh} -- TrueType head table * - * Copyright (c) 2007-2016 Eddie Kohler + * Copyright (c) 2007-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfkern.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfkern.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfkern.cc.git4166ff9 2016-11-25 13:08:52.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/ttfkern.cc 2018-02-23 12:47:54.084971928 -0500 @@ -2,7 +2,7 @@ /* ttfkern.{cc,hh} -- TrueType kern table * - * Copyright (c) 2009-2016 Eddie Kohler + * Copyright (c) 2009-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -27,7 +27,7 @@ namespace Efont { namespace OpenType { inline Data -KernTable::subtable(uint32_t &off_in_out) const throw (Error) +KernTable::subtable(uint32_t &off_in_out) const { uint32_t off = off_in_out, len; if (_version == 0) { @@ -42,7 +42,7 @@ KernTable::subtable(uint32_t &off_in_out return _d.substring(off, len); } -KernTable::KernTable(const Data &d, ErrorHandler *) throw (Error) +KernTable::KernTable(const Data &d, ErrorHandler *) : _d(d), _error(-1) { // USHORT Version diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/bezier.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/bezier.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/bezier.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/bezier.cc 2018-02-23 12:47:54.084971928 -0500 @@ -2,7 +2,7 @@ /* bezier.{cc,hh} -- cubic Bezier curves * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -23,7 +23,7 @@ // void -Bezier::make_bb() const throw () +Bezier::make_bb() const noexcept { _bb = 0; for (int i = 1; i < 4; i++) { @@ -44,7 +44,7 @@ Bezier::make_bb() const throw () // bool -Bezier::is_flat(double t) const throw () +Bezier::is_flat(double t) const noexcept { return (_p[2].on_segment(_p[0], _p[3], t) && _p[1].on_segment(_p[0], _p[3], t)); @@ -66,7 +66,7 @@ eval_bezier(Point *b_in, int degree, dou } Point -Bezier::eval(double u) const throw () +Bezier::eval(double u) const noexcept { Bezier b = *this; double m = 1.0 - u; @@ -82,7 +82,7 @@ Bezier::eval(double u) const throw () // void -Bezier::halve(Bezier &l, Bezier &r) const throw () +Bezier::halve(Bezier &l, Bezier &r) const noexcept { Point half = Point::midpoint(_p[1], _p[2]); l._p[0] = _p[0]; @@ -100,7 +100,7 @@ Bezier::halve(Bezier &l, Bezier &r) cons // bool -Bezier::in_bb(const Point &p, double tolerance) const throw () +Bezier::in_bb(const Point &p, double tolerance) const noexcept { ensure_bb(); if (bb_right() + tolerance < p.x @@ -114,7 +114,7 @@ Bezier::in_bb(const Point &p, double tol double Bezier::hit_recurse(const Point &p, double tolerance, double leftd, - double rightd, double leftt, double rightt) const throw () + double rightd, double leftt, double rightt) const noexcept { Bezier left, right; double middled, resultt; @@ -146,7 +146,7 @@ Bezier::hit_recurse(const Point &p, doub } bool -Bezier::hit(const Point &p, double tolerance) const throw () +Bezier::hit(const Point &p, double tolerance) const noexcept { double leftd = (_p[0] - p).squared_length(); double rightd = (_p[3] - p).squared_length(); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/clp.c.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/clp.c --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/clp.c.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/clp.c 2018-02-23 12:47:54.084971928 -0500 @@ -2,7 +2,7 @@ /* clp.c - Complete source code for CLP. * This file is part of CLP, the command line parser package. * - * Copyright (c) 1997-2016 Eddie Kohler, ekohler@gmail.com + * Copyright (c) 1997-2018 Eddie Kohler, ekohler@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/error.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/error.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/error.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/error.cc 2018-02-23 12:47:54.085971903 -0500 @@ -4,7 +4,7 @@ * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology - * Copyright (c) 2001-2016 Eddie Kohler + * Copyright (c) 2001-2018 Eddie Kohler * Copyright (c) 2008 Meraki, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -595,7 +595,7 @@ ErrorHandler::vxformat(int default_flags s2 = numbuf + NUMBUF_SIZE; - unsigned long num; + do_number_t num; switch (width_flag) { case 'H': case -8: @@ -651,13 +651,12 @@ ErrorHandler::vxformat(int default_flags default: goto error; } - s1 = do_number(num, (char *)s2, base, flags); + s1 = do_number(num, (char*) s2, base, flags); #if HAVE_INT64_TYPES got_number: #endif - s1 = do_number_flags((char *)s1, (char *)s2, base, flags, - precision, field_width); + s1 = do_number_flags((char*)s1, (char*) s2, base, flags, precision, field_width); break; } @@ -681,7 +680,7 @@ ErrorHandler::vxformat(int default_flags } void* v = va_arg(val, void*); s2 = numbuf + NUMBUF_SIZE; - s1 = do_number((unsigned long) v, (char*) s2, 16, flags); + s1 = do_number((do_number_t) v, (char*) s2, 16, flags); s1 = do_number_flags((char*) s1, (char*) s2, 16, flags | cf_alternate_form, precision, field_width); break; } @@ -828,7 +827,7 @@ ErrorHandler::fatal(const char *fmt, ... { va_list val; va_start(val, fmt); - int r = xmessage(String::make_stable(e_fatal, 4), fmt, val); + (void) xmessage(String::make_stable(e_fatal, 4), fmt, val); va_end(val); abort(); } @@ -881,7 +880,7 @@ ErrorHandler::lfatal(const String &landm va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); - int r = xmessage(String::make_stable(e_fatal, 4) + l, fmt, val); + (void) xmessage(String::make_stable(e_fatal, 4) + l, fmt, val); va_end(val); abort(); } @@ -1091,7 +1090,7 @@ ErrorVeneer::account(int level) ContextErrorHandler::ContextErrorHandler(ErrorHandler *errh, const char *fmt, ...) : ErrorVeneer(errh), _indent(String::make_stable(" ", 2)), - _context_printed(false), _context_landmark("{l:}") + _context_landmark("{l:}"), _context_printed(false) { va_list val; va_start(val, fmt); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/filename.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/filename.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/filename.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/filename.cc 2018-02-23 12:47:54.085971903 -0500 @@ -2,7 +2,7 @@ /* filename.{cc,hh} -- filenames * - * Copyright (c) 1999-2016 Eddie Kohler + * Copyright (c) 1999-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -126,5 +126,5 @@ Filename::open_write(bool binary) const if (_actual || !_path) return _actual; else - return fopen(_path.c_str(), "wb"); + return fopen(_path.c_str(), binary ? "wb" : "w"); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/globmatch.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/globmatch.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/globmatch.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/globmatch.cc 2018-02-23 12:47:54.085971903 -0500 @@ -2,7 +2,7 @@ /* globmatch.{cc,hh} -- glob_match() function for shell globbing * - * Copyright (c) 2000-2016 Eddie Kohler + * Copyright (c) 2000-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/landmark.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/landmark.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/landmark.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/landmark.cc 2018-02-23 12:47:54.085971903 -0500 @@ -2,7 +2,7 @@ /* landmark.{cc,hh} -- FILE:LINE type landmarks * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/permstr.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/permstr.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/permstr.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/permstr.cc 2018-02-23 12:47:54.086971878 -0500 @@ -2,7 +2,7 @@ /* permstr.{cc,hh} -- permanent strings * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/point.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/point.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/point.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/point.cc 2018-02-23 12:47:54.087971853 -0500 @@ -2,7 +2,7 @@ /* point.{cc,hh} -- 2D points * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -19,7 +19,7 @@ #include Point -Point::rotated(double rotation) const throw () +Point::rotated(double rotation) const noexcept { double r = length(); double theta = angle() + rotation; @@ -27,13 +27,13 @@ Point::rotated(double rotation) const th } Point -Point::midpoint(const Point &a, const Point &b) throw () +Point::midpoint(const Point &a, const Point &b) noexcept { return Point((a.x + b.x)/2, (a.y + b.y)/2); } bool -Point::on_line(const Point &a, const Point &b, double tolerance) const throw () +Point::on_line(const Point &a, const Point &b, double tolerance) const noexcept { Point c = b - a; double d = c.x * (y - a.y) - c.y * (x - a.x); @@ -41,7 +41,7 @@ Point::on_line(const Point &a, const Poi } bool -Point::on_segment(const Point &a, const Point &b, double t) const throw () +Point::on_segment(const Point &a, const Point &b, double t) const noexcept { double tt; Point c = b - a; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/slurper.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/slurper.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/slurper.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/slurper.cc 2018-02-23 12:47:54.087971853 -0500 @@ -2,7 +2,7 @@ /* slurper.{cc,hh} -- reading from files a line at a time * - * Copyright (c) 1998-2016 Eddie Kohler + * Copyright (c) 1998-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/straccum.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/straccum.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/straccum.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/straccum.cc 2018-02-23 12:47:54.087971853 -0500 @@ -4,7 +4,7 @@ * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology - * Copyright (c) 2001-2016 Eddie Kohler + * Copyright (c) 2001-2018 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -61,7 +61,7 @@ StringAccum::assign_out_of_memory() { assert(_cap >= 0); if (_cap > 0) - delete[] (_s - MEMO_SPACE); + delete[] (_s - MEMO_SPACE); _s = reinterpret_cast(const_cast(String::out_of_memory_data())); _cap = -1; _len = 0; @@ -72,25 +72,25 @@ StringAccum::grow(int want) { // can't append to out-of-memory strings if (_cap < 0) { - errno = ENOMEM; - return 0; + errno = ENOMEM; + return 0; } int ncap = (_cap ? (_cap + MEMO_SPACE) * 2 : 128) - MEMO_SPACE; while (ncap <= want) - ncap = (ncap + MEMO_SPACE) * 2 - MEMO_SPACE; + ncap = (ncap + MEMO_SPACE) * 2 - MEMO_SPACE; unsigned char *n = new unsigned char[ncap + MEMO_SPACE]; if (!n) { - assign_out_of_memory(); - errno = ENOMEM; - return 0; + assign_out_of_memory(); + errno = ENOMEM; + return 0; } n += MEMO_SPACE; if (_s) { - memcpy(n, _s, _len); - delete[] (_s - MEMO_SPACE); + memcpy(n, _s, _len); + delete[] (_s - MEMO_SPACE); } _s = n; _cap = ncap; @@ -102,10 +102,10 @@ StringAccum::resize(int len) { assert(len >= 0); if (len > _cap && !grow(len)) - return -ENOMEM; + return -ENOMEM; else { - _len = len; - return 0; + _len = len; + return 0; } } @@ -114,7 +114,7 @@ StringAccum::hard_extend(int nadjust, in { char *x = grow(_len + nadjust + nreserve); if (x) - _len += nadjust; + _len += nadjust; return x; } @@ -122,7 +122,7 @@ const char * StringAccum::c_str() { if (_len < _cap || grow(_len)) - _s[_len] = '\0'; + _s[_len] = '\0'; return reinterpret_cast(_s); } @@ -130,28 +130,28 @@ void StringAccum::append_fill(int c, int len) { if (char *s = extend(len)) - memset(s, c, len); + memset(s, c, len); } void StringAccum::append_utf8_hard(unsigned ch) { if (ch < 0x80) - append((unsigned char) ch); + append((unsigned char) ch); else if (ch < 0x800) { - append((unsigned char) (0xC0 + ((ch >> 6) & 0x1F))); - append((unsigned char) (0x80 + (ch & 0x3F))); + append((unsigned char) (0xC0 + ((ch >> 6) & 0x1F))); + append((unsigned char) (0x80 + (ch & 0x3F))); } else if (ch < 0x10000) { - append((unsigned char) (0xE0 + ((ch >> 12) & 0x0F))); - append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); - append((unsigned char) (0x80 + (ch & 0x3F))); + append((unsigned char) (0xE0 + ((ch >> 12) & 0x0F))); + append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); + append((unsigned char) (0x80 + (ch & 0x3F))); } else if (ch < 0x110000) { - append((unsigned char) (0xF0 + ((ch >> 18) & 0x07))); - append((unsigned char) (0x80 + ((ch >> 12) & 0x3F))); - append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); - append((unsigned char) (0x80 + (ch & 0x3F))); + append((unsigned char) (0xF0 + ((ch >> 18) & 0x07))); + append((unsigned char) (0x80 + ((ch >> 12) & 0x3F))); + append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); + append((unsigned char) (0x80 + (ch & 0x3F))); } else - append((unsigned char) '?'); + append((unsigned char) '?'); } void @@ -161,27 +161,29 @@ StringAccum::hard_append(const char *s, // a naive implementation might use sa's data after freeing it. const char *my_s = reinterpret_cast(_s); - if (_len + len <= _cap) { + if (len <= 0) { + // do nothing + } else if (_len + len <= _cap) { success: - memcpy(_s + _len, s, len); - _len += len; + memcpy(_s + _len, s, len); + _len += len; } else if (s < my_s || s >= my_s + _cap) { - if (grow(_len + len)) - goto success; + if (grow(_len + len)) + goto success; } else { - unsigned char *old_s = _s; - int old_len = _len; + unsigned char *old_s = _s; + int old_len = _len; - _s = 0; - _len = 0; - _cap = 0; - - if (char *new_s = extend(old_len + len)) { - memcpy(new_s, old_s, old_len); - memcpy(new_s + old_len, s, len); - } + _s = 0; + _len = 0; + _cap = 0; + + if (char *new_s = extend(old_len + len)) { + memcpy(new_s, old_s, old_len); + memcpy(new_s + old_len, s, len); + } - delete[] (old_s - MEMO_SPACE); + delete[] (old_s - MEMO_SPACE); } } @@ -198,14 +200,14 @@ StringAccum::take_string() int cap = _cap; char *str = reinterpret_cast(_s); if (len > 0) { - _s = 0; - _len = _cap = 0; - return String::make_claim(str, len, cap); + _s = 0; + _len = _cap = 0; + return String::make_claim(str, len, cap); } else if (!out_of_memory()) - return String(); + return String(); else { - clear(); - return String::make_out_of_memory(); + clear(); + return String::make_out_of_memory(); } } @@ -227,8 +229,8 @@ StringAccum & operator<<(StringAccum &sa, long i) { if (char *x = sa.reserve(24)) { - int len = sprintf(x, "%ld", i); - sa.adjust_length(len); + int len = sprintf(x, "%ld", i); + sa.adjust_length(len); } return sa; } @@ -240,8 +242,8 @@ StringAccum & operator<<(StringAccum &sa, unsigned long u) { if (char *x = sa.reserve(24)) { - int len = sprintf(x, "%lu", u); - sa.adjust_length(len); + int len = sprintf(x, "%lu", u); + sa.adjust_length(len); } return sa; } @@ -250,8 +252,8 @@ StringAccum & operator<<(StringAccum &sa, double d) { if (char *x = sa.reserve(256)) { - int len = sprintf(x, "%.12g", d); - sa.adjust_length(len); + int len = sprintf(x, "%.12g", d); + sa.adjust_length(len); } return sa; } @@ -263,12 +265,12 @@ StringAccum::snprintf(int n, const char va_start(val, format); if (char *x = reserve(n + 1)) { #if HAVE_VSNPRINTF - int len = vsnprintf(x, n + 1, format, val); + int len = vsnprintf(x, n + 1, format, val); #else - int len = vsprintf(x, format, val); - assert(len <= n); + int len = vsprintf(x, format, val); + assert(len <= n); #endif - adjust_length(len); + adjust_length(len); } va_end(val); return *this; @@ -278,27 +280,27 @@ void StringAccum::append_break_lines(const String& text, int linelen, const String &leftmargin) { if (text.length() == 0) - return; + return; const char* line = text.begin(); const char* ends = text.end(); linelen -= leftmargin.length(); for (const char* s = line; s < ends; s++) { - const char* start = s; - while (s < ends && isspace((unsigned char) *s)) - s++; - const char* word = s; - while (s < ends && !isspace((unsigned char) *s)) - s++; - if (s - line > linelen && start > line) { - *this << leftmargin; - append(line, start - line); - *this << '\n'; - line = word; - } + const char* start = s; + while (s < ends && isspace((unsigned char) *s)) + s++; + const char* word = s; + while (s < ends && !isspace((unsigned char) *s)) + s++; + if (s - line > linelen && start > line) { + *this << leftmargin; + append(line, start - line); + *this << '\n'; + line = word; + } } if (line < text.end()) { - *this << leftmargin; - append(line, text.end() - line); - *this << '\n'; + *this << leftmargin; + append(line, text.end() - line); + *this << '\n'; } } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/string.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/string.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/string.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/string.cc 2018-02-23 12:47:54.087971853 -0500 @@ -4,7 +4,7 @@ * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology - * Copyright (c) 2001-2016 Eddie Kohler + * Copyright (c) 2001-2018 Eddie Kohler * Copyright (c) 2008-2009 Meraki, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/transform.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/transform.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/transform.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/transform.cc 2018-02-23 12:47:54.087971853 -0500 @@ -2,7 +2,7 @@ /* transform.{cc,hh} -- planar affine transformations * - * Copyright (c) 2000-2016 Eddie Kohler + * Copyright (c) 2000-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/vectorv.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/vectorv.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/vectorv.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/liblcdf/vectorv.cc 2018-02-23 12:47:54.087971853 -0500 @@ -36,11 +36,11 @@ Vector & Vector::operator=(const Vector &o) { if (&o != this) { - _n = 0; - if (reserve(o._n)) { - _n = o._n; - memcpy(_l, o._l, sizeof(void *) * _n); - } + _n = 0; + if (reserve(o._n)) { + _n = o._n; + memcpy(_l, o._l, sizeof(void *) * _n); + } } return *this; } @@ -57,15 +57,17 @@ bool Vector::reserve(int want) { if (want < 0) - want = (_capacity > 0 ? _capacity * 2 : 4); + want = (_capacity > 0 ? _capacity * 2 : 4); if (want <= _capacity) - return true; + return true; void **new_l = new void*[want]; if (!new_l) - return false; + return false; - memcpy(new_l, _l, sizeof(void*) * _n); + if (_n) { + memcpy(new_l, _l, sizeof(void*) * _n); + } delete[] _l; _l = new_l; @@ -77,21 +79,21 @@ Vector::iterator Vector::erase(iterator a, iterator b) { if (b > a) { - assert(a >= begin() && b <= end()); - memmove(a, b, (end() - b) * sizeof(void*)); - _n -= b - a; - return a; + assert(a >= begin() && b <= end()); + memmove(a, b, (end() - b) * sizeof(void*)); + _n -= b - a; + return a; } else - return b; + return b; } void Vector::resize(int nn, void *e) { if (nn <= _capacity || reserve(nn)) { - for (int i = _n; i < nn; i++) - _l[i] = e; - _n = nn; + for (int i = _n; i < nn; i++) + _l[i] = e; + _n = nn; } } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/main.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/main.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/main.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/main.cc 2018-02-23 12:47:54.088971828 -0500 @@ -1,6 +1,6 @@ /* main.cc -- driver for mmafm program * - * Copyright (c) 1997-2016 Eddie Kohler + * Copyright (c) 1997-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -322,7 +322,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("mmafm (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 1997-2016 Eddie Kohler\n\ + printf("Copyright (C) 1997-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/mmafm.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/mmafm.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/mmafm.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmafm/mmafm.1 2018-02-23 12:47:54.088971828 -0500 @@ -1,5 +1,5 @@ .\" -*-nroff-*- -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/main.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/main.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/main.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/main.cc 2018-02-23 12:47:54.088971828 -0500 @@ -1,6 +1,6 @@ /* main.cc -- driver for mmpfb program * - * Copyright (c) 1997-2016 Eddie Kohler + * Copyright (c) 1997-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -355,7 +355,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("mmpfb (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 1997-2016 Eddie Kohler\n\ + printf("Copyright (C) 1997-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/mmpfb.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/mmpfb.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/mmpfb.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/mmpfb.1 2018-02-23 12:47:54.088971828 -0500 @@ -1,5 +1,5 @@ .\" -*-nroff-*- -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/myfont.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/myfont.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/myfont.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/myfont.cc 2018-02-23 12:47:54.088971828 -0500 @@ -1,6 +1,6 @@ /* myfont.cc -- general multiple- to single-master conversion * - * Copyright (c) 1997-2016 Eddie Kohler + * Copyright (c) 1997-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1minimize.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1minimize.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1minimize.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1minimize.cc 2018-02-23 12:47:54.088971828 -0500 @@ -1,6 +1,6 @@ /* t1minimize.cc -- make minimal copy of a Type 1 font * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1rewrit.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1rewrit.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1rewrit.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/mmpfb/t1rewrit.cc 2018-02-23 12:47:54.088971828 -0500 @@ -1,6 +1,6 @@ /* t1rewrit.cc -- routines for multiple- to single-master charstring conversion * - * Copyright (c) 1997-2016 Eddie Kohler + * Copyright (c) 1997-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/NEWS.md.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/NEWS.md --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/NEWS.md.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/NEWS.md 2018-02-23 12:47:54.089971803 -0500 @@ -1,6 +1,15 @@ LCDF Typetools NEWS =================== +## Version 2.107 – 22.Feb.2018 + +* Some corrections to output of `--math-spacing`. + +* Reduce undefined behavior. + +* Handle some incorrect fonts more gracefully. + + ## Version 2.106 – 21.Jun.2016 * Minor updates, mostly involving licensing of Adobe code and data. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.1 2018-02-23 12:47:54.089971803 -0500 @@ -1,5 +1,5 @@ '\"t -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otfinfo/otfinfo.cc 2018-02-23 12:47:54.089971803 -0500 @@ -1,6 +1,6 @@ /* otfinfo.cc -- driver for reporting information about OpenType fonts * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -528,7 +528,7 @@ do_query_unicode(const OpenType::Font& o sprintf(name, "uni%04X", it->first); else sprintf(name, "u%X", it->first); - if ((size_t) it->second < glyph_names.size()) + if (it->second < glyph_names.size()) result_errh->message("%s %d %s\n", name, it->second, glyph_names[it->second].c_str()); else result_errh->message("%s %d\n", name, it->second); @@ -645,7 +645,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("otfinfo (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2003-2016 Eddie Kohler\n\ + printf("Copyright (C) 2003-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -721,5 +721,6 @@ particular purpose.\n"); do_info(otf, &cerrh, result_errh); } + Clp_DeleteParser(clp); return (errh->nerrors() == 0 ? 0 : 1); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc 2018-02-23 12:47:54.089971803 -0500 @@ -1,6 +1,6 @@ /* automatic.{cc,hh} -- code for automatic mode and interfacing with kpathsea * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -39,10 +39,6 @@ #include #ifdef WIN32 -#ifdef _MSC_VER -# include -# include -#endif # define mkdir(dir, access) mkdir(dir) # define COPY_CMD "copy" # define CMD_SEP "&" @@ -93,7 +89,7 @@ static const struct { static String odir_kpathsea[NUMODIR]; static bool writable_texdir_tried = false; -static String writable_texdir; // always ends with directory separator +static String writable_texdir; // always ends with directory separator static int tds_1_1 = -1; static bool mktexupd_tried = false; @@ -112,41 +108,30 @@ look_for_writable_texdir(const char *pat { String path = kpsei_string(kpsei_path_expand(path_variable)); while (path && !writable_texdir) { - const char* colon = std::find(path.begin(), path.end(), kpsei_env_sep_char); - String texdir = path.substring(path.begin(), colon); - path = path.substring(colon + 1, path.end()); - if (access(texdir.c_str(), W_OK) >= 0) - writable_texdir = texdir; - else if (create && errno != EACCES && mkdir(texdir.c_str(), 0777) >= 0) - // create file if it doesn't exist already - writable_texdir = texdir; + const char* colon = std::find(path.begin(), path.end(), kpsei_env_sep_char); + String texdir = path.substring(path.begin(), colon); + path = path.substring(colon + 1, path.end()); + if (access(texdir.c_str(), W_OK) >= 0) + writable_texdir = texdir; + else if (create && errno != EACCES && mkdir(texdir.c_str(), 0777) >= 0) + // create file if it doesn't exist already + writable_texdir = texdir; } if (writable_texdir && writable_texdir.back() != '/') - writable_texdir += "/"; + writable_texdir += "/"; } static void find_writable_texdir(ErrorHandler *errh, const char *) { -#if defined(W32TEX) -// W32TeX does not have TEXMFVAR - char *p = kpsei_var_value("TEXMFVAR"); - if (p == NULL) // W32TeX - look_for_writable_texdir("$TEXMFLOCAL", true); - else { // TeXLive - free (p); - look_for_writable_texdir("$TEXMFVAR", true); - } -#else look_for_writable_texdir("$TEXMFVAR", true); -#endif if (!writable_texdir) - look_for_writable_texdir("$VARTEXMF", false); + look_for_writable_texdir("$VARTEXMF", false); if (!writable_texdir) - look_for_writable_texdir("$TEXMF", false); + look_for_writable_texdir("$TEXMF", false); if (!writable_texdir) { - errh->warning("no writable directory found in $TEXMFVAR or $TEXMF"); - errh->message("(You probably need to set your TEXMF environment variable; see\n\ + errh->warning("no writable directory found in $TEXMFVAR or $TEXMF"); + errh->message("(You probably need to set your TEXMF environment variable; see\n\ the manual for more information. The current TEXMF path is\n\ %<%s%>.)", kpsei_string(kpsei_path_expand("$TEXMF")).c_str()); } @@ -179,7 +164,7 @@ set_typeface(const String &s, bool overr { bool had = (bool) typeface; if (!had || override) - typeface = s; + typeface = s; return !had; } @@ -189,91 +174,93 @@ getodir(int o, ErrorHandler *errh) assert(o >= 0 && o < NUMODIR); if (!odir[o] && automatic && odir_info[o].envvar) - odir[o] = getenv(odir_info[o].envvar); + odir[o] = getenv(odir_info[o].envvar); #if HAVE_KPATHSEA if (!odir[o] && automatic && !writable_texdir_tried) - find_writable_texdir(errh, odir_info[o].name); + find_writable_texdir(errh, odir_info[o].name); if (!odir[o] && automatic && writable_texdir) { - String suffix = odir_info[o].texdir; + String suffix = odir_info[o].texdir; + + // May need to behave differently on TDS 1.1 rather than TDS 1.0. + if (suffix[0] == '#') { + // check type of TDS + if (tds_1_1 < 0) { + // using a procedure suggested by Olaf Weber + String encfonts = kpsei_string(kpsei_path_expand("$TEXMFMAIN/fonts/enc")); + if (!encfonts) + encfonts = kpsei_string(kpsei_path_expand("$TEXMFDIST/fonts/enc")); + tds_1_1 = (encfonts != String()); + } + if (tds_1_1 == 0) + suffix = suffix.substring(std::find(suffix.begin() + 1, suffix.end(), '#') + 1, suffix.end()); + else + suffix = suffix.substring(suffix.begin() + 1, std::find(suffix.begin() + 1, suffix.end(), '#')); + } + + String dir = writable_texdir + suffix; + + if (dir.back() == '%') + dir = dir.substring(0, -1) + get_vendor() + "/" + get_typeface(); + else if (dir.back() == '@') + dir = dir.substring(0, -1) + get_vendor(); + + // create parent directories as appropriate + int slash = writable_texdir.length() - 1; + while (access(dir.c_str(), F_OK) < 0 && slash < dir.length()) { + if ((slash = dir.find_left('/', slash + 1)) < 0) + slash = dir.length(); + String subdir = dir.substring(0, slash); + if (access(subdir.c_str(), F_OK) < 0 + && !no_create + && mkdir(subdir.c_str(), 0777) < 0) + goto kpathsea_done; + } - // May need to behave differently on TDS 1.1 rather than TDS 1.0. - if (suffix[0] == '#') { - // check type of TDS - if (tds_1_1 < 0) { - // using a procedure suggested by Olaf Weber - String encfonts = kpsei_string(kpsei_path_expand("$TEXMFMAIN/fonts/enc")); - if (!encfonts) - encfonts = kpsei_string(kpsei_path_expand("$TEXMFDIST/fonts/enc")); - tds_1_1 = (encfonts != String()); - } - if (tds_1_1 == 0) - suffix = suffix.substring(std::find(suffix.begin() + 1, suffix.end(), '#') + 1, suffix.end()); - else - suffix = suffix.substring(suffix.begin() + 1, std::find(suffix.begin() + 1, suffix.end(), '#')); - } - - String dir = writable_texdir + suffix; - - if (dir.back() == '%') - dir = dir.substring(0, -1) + get_vendor() + "/" + get_typeface(); - else if (dir.back() == '@') - dir = dir.substring(0, -1) + get_vendor(); - - // create parent directories as appropriate - int slash = writable_texdir.length() - 1; - while (access(dir.c_str(), F_OK) < 0 && slash < dir.length()) { - if ((slash = dir.find_left('/', slash + 1)) < 0) - slash = dir.length(); - String subdir = dir.substring(0, slash); - if (access(subdir.c_str(), F_OK) < 0 - && !no_create - && mkdir(subdir.c_str(), 0777) < 0) - goto kpathsea_done; - } - - // that's our answer - odir[o] = dir; - odir_kpathsea[o] = dir; + // that's our answer + odir[o] = dir; + odir_kpathsea[o] = dir; } kpathsea_done: #endif if (!odir[o]) { - if (automatic) { - errh->warning("%s not specified, placing %s files in %<.%>", odir_info[o].envvar, odir_info[o].name); + if (automatic) { + errh->warning("%s not specified, placing %s files in %<.%>", odir_info[o].envvar, odir_info[o].name); #if !HAVE_KPATHSEA - static int kpathsea_warning = 0; - if (++kpathsea_warning == 1) - errh->message("(This version of otftotfm lacks $TEXMF directory support.)"); + static int kpathsea_warning = 0; + if (++kpathsea_warning == 1) + errh->message("(This version of otftotfm lacks $TEXMF directory support.)"); #endif - } - odir[o] = "."; + } + odir[o] = "."; } while (odir[o].length() && odir[o].back() == '/') - odir[o] = odir[o].substring(0, -1); + odir[o] = odir[o].substring(0, -1); if (verbose) - errh->message("placing %s files in %<%s%>", odir_info[o].name, odir[o].c_str()); + errh->message("placing %s files in %<%s%>", odir_info[o].name, odir[o].c_str()); return odir[o]; } -bool +void setodir(int o, const String &value) { assert(o >= 0 && o < NUMODIR); - bool had = (bool) odir[o]; odir[o] = value; - return !had; } const char * odirname(int o) { - assert(o >= 0 && o < NUMODIR); - return odir_info[o].name; + if (o == NUMODIR) { + return "default"; + } else { + assert(o >= 0 && o < NUMODIR); + return odir_info[o].name; + } } #if HAVE_KPATHSEA @@ -281,9 +268,9 @@ static bool file_in_kpathsea_odir(int o, const String &file) { return odir_kpathsea[o] - && file.length() > odir[o].length() - && memcmp(file.data(), odir[o].data(), odir[o].length()) == 0 - && file[odir[o].length()] == '/'; + && file.length() > odir[o].length() + && memcmp(file.data(), odir[o].data(), odir[o].length()) == 0 + && file[odir[o].length()] == '/'; } #endif @@ -293,68 +280,64 @@ update_odir(int o, String file, ErrorHan assert(o >= 0 && o < NUMODIR); #if HAVE_KPATHSEA if (file.find_left('/') < 0) - file = odir[o] + "/" + file; + file = odir[o] + "/" + file; // exit if this directory was not found via kpathsea, or the file is not // in the kpathsea directory if (!file_in_kpathsea_odir(o, file)) - return; + return; assert(writable_texdir && writable_texdir.length() <= odir[o].length() - && memcmp(file.data(), writable_texdir.data(), writable_texdir.length()) == 0); + && memcmp(file.data(), writable_texdir.data(), writable_texdir.length()) == 0); // divide the filename into portions // file == writable_texdir + directory + file file = file.substring(writable_texdir.length()); while (file && file[0] == '/') - file = file.substring(1); + file = file.substring(1); int last_slash = file.find_right('/'); String directory = (last_slash >= 0 ? file.substring(0, last_slash) : String()); file = file.substring(last_slash >= 0 ? last_slash + 1 : 0); - if (!file) // no filename to update - return; + if (!file) // no filename to update + return; // return if nocreate if (no_create) { - errh->message("would update %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); - return; + errh->message("would update %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); + return; } else if (verbose) - errh->message("updating %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); + errh->message("updating %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); // try to update ls-R ourselves, rather than running mktexupd -- // mktexupd's runtime is painful: a half second to update a file String ls_r = writable_texdir + "ls-R"; bool success = false; if (access(ls_r.c_str(), R_OK) >= 0) // make sure it already exists - if (FILE *f = fopen(ls_r.c_str(), "ab")) { - fprintf(f, "./%s:\n%s\n", directory.c_str(), file.c_str()); - success = true; - fclose(f); - } + if (FILE *f = fopen(ls_r.c_str(), "a")) { + fprintf(f, "./%s:\n%s\n", directory.c_str(), file.c_str()); + success = true; + fclose(f); + } // otherwise, run mktexupd if (!success && writable_texdir.find_left('\'') < 0 && directory.find_left('\'') < 0 && file.find_left('\'') < 0) { - // look for mktexupd script - if (!mktexupd_tried) { -#ifdef _WIN32 - mktexupd = "mktexupd"; -#else - mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C)); -#endif - mktexupd_tried = true; - } + // look for mktexupd script + if (!mktexupd_tried) { + mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C)); + mktexupd_tried = true; + } - // run script - if (mktexupd) { - String command = mktexupd + " " + shell_quote(writable_texdir + directory) + " " + shell_quote(file); - int retval = system(command.c_str()); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - } + // run script + if (mktexupd) { + String command = mktexupd + " " + shell_quote(writable_texdir + directory) + " " + shell_quote(file); + int retval = system(command.c_str()); + if (retval == 127) + errh->error("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (retval != 0) + errh->error("%<%s%> failed", command.c_str()); + } } #else (void) file, (void) errh; @@ -375,25 +358,25 @@ installed_type1(const String &otf_filena (void) otf_filename, (void) allow_generate, (void) errh; if (!ps_fontname) - return String(); + return String(); #if HAVE_KPATHSEA # if HAVE_AUTO_CFFTOT1 if (!(force && allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh))) { # endif - // look for .pfb and .pfa - String file, path; - if ((file = ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) - || (file = ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } + // look for .pfb and .pfa + String file, path; + if ((file = ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) + || (file = ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { + if (path == "./" + file || path == file) { + if (verbose) + errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); + } else { + if (verbose) + errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); + return path; + } + } # if HAVE_AUTO_CFFTOT1 } # endif @@ -402,21 +385,21 @@ installed_type1(const String &otf_filena #if HAVE_AUTO_CFFTOT1 // if not found, and can generate on the fly, run cfftot1 if (allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh)) { - String pfb_filename = odir[O_TYPE1] + "/" + ps_fontname + ".pfb"; - if (pfb_filename.find_left('\'') >= 0 || otf_filename.find_left('\'') >= 0) - return String(); - String command = "cfftot1 " + shell_quote(otf_filename) + " -n " + shell_quote(ps_fontname) + " " + shell_quote(pfb_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - if (retval == 0) { - update_odir(O_TYPE1, pfb_filename, errh); - return pfb_filename; - } + String pfb_filename = odir[O_TYPE1] + "/" + ps_fontname + ".pfb"; + if (pfb_filename.find_left('\'') >= 0 || otf_filename.find_left('\'') >= 0) + return String(); + String command = "cfftot1 " + shell_quote(otf_filename) + " -n " + shell_quote(ps_fontname) + " " + shell_quote(pfb_filename); + int retval = mysystem(command.c_str(), errh); + if (retval == 127) + errh->error("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (retval != 0) + errh->error("%<%s%> failed", command.c_str()); + if (retval == 0) { + update_odir(O_TYPE1, pfb_filename, errh); + return pfb_filename; + } } #endif @@ -429,9 +412,9 @@ installed_type1_dotlessj(const String &o (void) otf_filename, (void) allow_generate, (void) errh; if (!ps_fontname) - return String(); + return String(); if (verbose) - errh->message("searching for dotless-j font for %s", ps_fontname.c_str()); + errh->message("searching for dotless-j font for %s", ps_fontname.c_str()); String j_ps_fontname = ps_fontname + "LCDFJ"; @@ -439,20 +422,20 @@ installed_type1_dotlessj(const String &o # if HAVE_AUTO_T1DOTLESSJ if (!(force && allow_generate && getodir(O_TYPE1, errh))) { # endif - // look for existing .pfb or .pfa - String file, path; - if ((file = j_ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) - || (file = j_ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { - // ignore versions in the current directory - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } + // look for existing .pfb or .pfa + String file, path; + if ((file = j_ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) + || (file = j_ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { + // ignore versions in the current directory + if (path == "./" + file || path == file) { + if (verbose) + errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); + } else { + if (verbose) + errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); + return path; + } + } # if HAVE_AUTO_T1DOTLESSJ } # endif @@ -461,26 +444,26 @@ installed_type1_dotlessj(const String &o #if HAVE_AUTO_T1DOTLESSJ // if not found, and can generate on the fly, try running t1dotlessj if (allow_generate && getodir(O_TYPE1, errh)) { - if (String base_filename = installed_type1(otf_filename, ps_fontname, allow_generate, errh)) { - String pfb_filename = odir[O_TYPE1] + "/" + j_ps_fontname + ".pfb"; - if (pfb_filename.find_left('\'') >= 0 || base_filename.find_left('\'') >= 0) - return String(); - String command = "t1dotlessj " + shell_quote(base_filename) + " -n " + shell_quote(j_ps_fontname) + " " + shell_quote(pfb_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->warning("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (WEXITSTATUS(retval) == T1DOTLESSJ_EXIT_J_NODOT) - return String("\0", 1); - else if (retval != 0) - errh->warning("%<%s%> failed (%d)", command.c_str(), retval); - if (retval == 0) { - update_odir(O_TYPE1, pfb_filename, errh); - return pfb_filename; - } else - errh->warning("output font will not contain a dotless-j character"); - } + if (String base_filename = installed_type1(otf_filename, ps_fontname, allow_generate, errh)) { + String pfb_filename = odir[O_TYPE1] + "/" + j_ps_fontname + ".pfb"; + if (pfb_filename.find_left('\'') >= 0 || base_filename.find_left('\'') >= 0) + return String(); + String command = "t1dotlessj " + shell_quote(base_filename) + " -n " + shell_quote(j_ps_fontname) + " " + shell_quote(pfb_filename); + int retval = mysystem(command.c_str(), errh); + if (retval == 127) + errh->warning("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (WEXITSTATUS(retval) == T1DOTLESSJ_EXIT_J_NODOT) + return String("\0", 1); + else if (retval != 0) + errh->warning("%<%s%> failed (%d)", command.c_str(), retval); + if (retval == 0) { + update_odir(O_TYPE1, pfb_filename, errh); + return pfb_filename; + } else + errh->warning("output font will not contain a dotless-j character"); + } } #endif @@ -494,45 +477,45 @@ installed_truetype(const String &ttf_fil #if HAVE_KPATHSEA if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh))) { - if (String path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TRUETYPE))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring TrueType file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("TrueType file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } + if (String path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TRUETYPE))) { + if (path == "./" + file || path == file) { + if (verbose) + errh->message("ignoring TrueType file %s found with kpathsea in %<.%>", path.c_str()); + } else { + if (verbose) + errh->message("TrueType file %s found with kpathsea at %s", file.c_str(), path.c_str()); + return path; + } + } } #endif // perhaps generate type 42 in the future, for now just copy if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh)) { - String installed_ttf_filename = odir[O_TRUETYPE] + "/" + file; - if (installed_ttf_filename.find_left('\'') >= 0 || installed_ttf_filename.find_left('\"') >= 0) - return String(); - - int retval; - if (!same_filename(ttf_filename, installed_ttf_filename)) { - String command = COPY_CMD " " + shell_quote(ttf_filename) + " " + shell_quote(installed_ttf_filename); - retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - } else { - if (verbose) - errh->message("TrueType file %s already located in output directory", installed_ttf_filename.c_str()); - retval = 0; - } - - if (retval == 0) { - update_odir(O_TRUETYPE, installed_ttf_filename, errh); - return installed_ttf_filename; - } + String installed_ttf_filename = odir[O_TRUETYPE] + "/" + file; + if (installed_ttf_filename.find_left('\'') >= 0 || installed_ttf_filename.find_left('\"') >= 0) + return String(); + + int retval; + if (!same_filename(ttf_filename, installed_ttf_filename)) { + String command = COPY_CMD " " + shell_quote(ttf_filename) + " " + shell_quote(installed_ttf_filename); + retval = mysystem(command.c_str(), errh); + if (retval == 127) + errh->error("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (retval != 0) + errh->error("%<%s%> failed", command.c_str()); + } else { + if (verbose) + errh->message("TrueType file %s already located in output directory", installed_ttf_filename.c_str()); + retval = 0; + } + + if (retval == 0) { + update_odir(O_TRUETYPE, installed_ttf_filename, errh); + return installed_ttf_filename; + } } return String(); @@ -544,24 +527,24 @@ installed_type42(const String &ttf_filen (void) allow_generate, (void) ttf_filename, (void) errh; if (!ps_fontname) - return String(); + return String(); #if HAVE_KPATHSEA # if HAVE_AUTO_TTFTOTYPE42 if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh))) { # endif - // look for .pfb and .pfa - String file, path; - if ((file = ps_fontname + ".t42", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE42)))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 42 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 42 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } + // look for .pfb and .pfa + String file, path; + if ((file = ps_fontname + ".t42", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE42)))) { + if (path == "./" + file || path == file) { + if (verbose) + errh->message("ignoring Type 42 file %s found with kpathsea in %<.%>", path.c_str()); + } else { + if (verbose) + errh->message("Type 42 file %s found with kpathsea at %s", file.c_str(), path.c_str()); + return path; + } + } # if HAVE_AUTO_TTFTOTYPE42 } # endif @@ -570,21 +553,21 @@ installed_type42(const String &ttf_filen #if HAVE_AUTO_TTFTOTYPE42 // if not found, and can generate on the fly, run ttftotype42 if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh)) { - String t42_filename = odir[O_TYPE42] + "/" + ps_fontname + ".t42"; - if (t42_filename.find_left('\'') >= 0 || ttf_filename.find_left('\'') >= 0) - return String(); - String command = "ttftotype42 " + shell_quote(ttf_filename) + " " + shell_quote(t42_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - if (retval == 0) { - update_odir(O_TYPE42, t42_filename, errh); - return t42_filename; - } + String t42_filename = odir[O_TYPE42] + "/" + ps_fontname + ".t42"; + if (t42_filename.find_left('\'') >= 0 || ttf_filename.find_left('\'') >= 0) + return String(); + String command = "ttftotype42 " + shell_quote(ttf_filename) + " " + shell_quote(t42_filename); + int retval = mysystem(command.c_str(), errh); + if (retval == 127) + errh->error("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (retval != 0) + errh->error("%<%s%> failed", command.c_str()); + if (retval == 0) { + update_odir(O_TYPE42, t42_filename, errh); + return t42_filename; + } } #endif @@ -596,94 +579,94 @@ update_autofont_map(const String &fontna { #if HAVE_KPATHSEA if (automatic && !map_file && getodir(O_MAP, errh)) - map_file = odir[O_MAP] + "/" + get_vendor() + ".map"; + map_file = odir[O_MAP] + "/" + get_vendor() + ".map"; #endif if (map_file == "" || map_file == "-") - fputs(mapline.c_str(), stdout); + fputs(mapline.c_str(), stdout); else { - // report no_create/verbose - if (no_create) { - errh->message("would update %s for %s", map_file.c_str(), String(fontname).c_str()); - return 0; - } else if (verbose) - errh->message("updating %s for %s", map_file.c_str(), String(fontname).c_str()); - - int fd = open(map_file.c_str(), O_RDWR | O_CREAT, 0666); - if (fd < 0) - return errh->lerror(map_file, "%s", strerror(errno)); - FILE *f = fdopen(fd, "r+"); - // NB: also change encoding logic if you change this code + // report no_create/verbose + if (no_create) { + errh->message("would update %s for %s", map_file.c_str(), String(fontname).c_str()); + return 0; + } else if (verbose) + errh->message("updating %s for %s", map_file.c_str(), String(fontname).c_str()); + + int fd = open(map_file.c_str(), O_RDWR | O_CREAT, 0666); + if (fd < 0) + return errh->lerror(map_file, "%s", strerror(errno)); + FILE *f = fdopen(fd, "r+"); + // NB: also change encoding logic if you change this code #if defined(F_SETLKW) && defined(HAVE_FTRUNCATE) - { - struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - int result; - while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) - /* try again */; - if (result < 0) { - result = errno; - fclose(f); - return errh->error("locking %s: %s", map_file.c_str(), strerror(result)); - } - } -#endif - - // read old data from map file - StringAccum sa; - int amt; - do { - if (char *x = sa.reserve(8192)) { - amt = fread(x, 1, 8192, f); - sa.adjust_length(amt); - } else - amt = 0; - } while (amt != 0); - if (!feof(f)) - return errh->error("%s: %s", map_file.c_str(), strerror(errno)); - String text = sa.take_string(); - - // add comment if necessary - bool created = (!text); - if (created) - text = "% Automatically maintained by otftotfm or other programs. Do not edit.\n\n"; - if (text.back() != '\n') - text += "\n"; - - // append old encodings - int fl = 0; - int nl = text.find_left('\n') + 1; - bool changed = created; - while (fl < text.length()) { - if (fl + fontname.length() + 1 < nl - && memcmp(text.data() + fl, fontname.data(), fontname.length()) == 0 - && text[fl + fontname.length()] == ' ') { - // found the old name - if (text.substring(fl, nl - fl) == mapline) { - // duplicate of old name, don't change it - fclose(f); - if (verbose) - errh->message("%s unchanged", map_file.c_str()); - return 0; - } else { - text = text.substring(0, fl) + text.substring(nl); - nl = fl; - changed = true; - } - } - fl = nl; - nl = text.find_left('\n', fl) + 1; - } + { + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + int result; + while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) + /* try again */; + if (result < 0) { + result = errno; + fclose(f); + return errh->error("locking %s: %s", map_file.c_str(), strerror(result)); + } + } +#endif + + // read old data from map file + StringAccum sa; + int amt; + do { + if (char *x = sa.reserve(8192)) { + amt = fread(x, 1, 8192, f); + sa.adjust_length(amt); + } else + amt = 0; + } while (amt != 0); + if (!feof(f)) + return errh->error("%s: %s", map_file.c_str(), strerror(errno)); + String text = sa.take_string(); + + // add comment if necessary + bool created = (!text); + if (created) + text = "% Automatically maintained by otftotfm or other programs. Do not edit.\n\n"; + if (text.back() != '\n') + text += "\n"; + + // append old encodings + int fl = 0; + int nl = text.find_left('\n') + 1; + bool changed = created; + while (fl < text.length()) { + if (fl + fontname.length() + 1 < nl + && memcmp(text.data() + fl, fontname.data(), fontname.length()) == 0 + && text[fl + fontname.length()] == ' ') { + // found the old name + if (text.substring(fl, nl - fl) == mapline) { + // duplicate of old name, don't change it + fclose(f); + if (verbose) + errh->message("%s unchanged", map_file.c_str()); + return 0; + } else { + text = text.substring(0, fl) + text.substring(nl); + nl = fl; + changed = true; + } + } + fl = nl; + nl = text.find_left('\n', fl) + 1; + } - if (!mapline && !changed) { + if (!mapline && !changed) { // special case: empty mapline, unchanged file - if (verbose) - errh->message("%s unchanged", map_file.c_str()); - } else { + if (verbose) + errh->message("%s unchanged", map_file.c_str()); + } else { // add our text text += mapline; @@ -694,7 +677,7 @@ update_autofont_map(const String &fontna #endif { fclose(f); - f = fopen(map_file.c_str(), "wb"); + f = fopen(map_file.c_str(), "w"); fd = fileno(f); } @@ -702,87 +685,78 @@ update_autofont_map(const String &fontna ignore_result(fwrite(text.data(), 1, text.length(), f)); } - fclose(f); + fclose(f); - // inform about the new file if necessary - if (created) - update_odir(O_MAP, map_file, errh); + // inform about the new file if necessary + if (created) + update_odir(O_MAP, map_file, errh); #if HAVE_KPATHSEA && !WIN32 - // run 'updmap' if present - String updmap_dir, updmap_file; - if (automatic && (output_flags & G_UPDMAP)) - updmap_dir = getodir(O_MAP_PARENT, errh); - if (updmap_dir && (updmap_file = updmap_dir + "/updmap") - && access(updmap_file.c_str(), X_OK) >= 0) { - // want to run 'updmap' from its directory, can't use system() - if (verbose) - errh->message("running %s", updmap_file.c_str()); - - pid_t child = fork(); - if (child < 0) - errh->fatal("%s during fork", strerror(errno)); - else if (child == 0) { - // change to updmap directory, run it - if (chdir(updmap_dir.c_str()) < 0) - errh->fatal("%s: %s during chdir", updmap_dir.c_str(), strerror(errno)); - if (execl("./updmap", updmap_file.c_str(), (const char*) 0) < 0) - errh->fatal("%s: %s during exec", updmap_file.c_str(), strerror(errno)); - exit(1); // should never get here - } + // run 'updmap' if present + String updmap_dir, updmap_file; + if (automatic && (output_flags & G_UPDMAP)) + updmap_dir = getodir(O_MAP_PARENT, errh); + if (updmap_dir && (updmap_file = updmap_dir + "/updmap") + && access(updmap_file.c_str(), X_OK) >= 0) { + // want to run 'updmap' from its directory, can't use system() + if (verbose) + errh->message("running %s", updmap_file.c_str()); + + pid_t child = fork(); + if (child < 0) + errh->fatal("%s during fork", strerror(errno)); + else if (child == 0) { + // change to updmap directory, run it + if (chdir(updmap_dir.c_str()) < 0) + errh->fatal("%s: %s during chdir", updmap_dir.c_str(), strerror(errno)); + if (execl("./updmap", updmap_file.c_str(), (const char*) 0) < 0) + errh->fatal("%s: %s during exec", updmap_file.c_str(), strerror(errno)); + exit(1); // should never get here + } # if HAVE_WAITPID - // wait for updmap to finish - int status; - while (1) { - pid_t answer = waitpid(child, &status, 0); - if (answer >= 0) - break; - else if (errno != EINTR) - errh->fatal("%s during wait", strerror(errno)); - } - if (!WIFEXITED(status)) - errh->warning("%s exited abnormally", updmap_file.c_str()); - else if (WEXITSTATUS(status) != 0) - errh->warning("%s exited with status %d", updmap_file.c_str(), WEXITSTATUS(status)); + // wait for updmap to finish + int status; + while (1) { + pid_t answer = waitpid(child, &status, 0); + if (answer >= 0) + break; + else if (errno != EINTR) + errh->fatal("%s during wait", strerror(errno)); + } + if (!WIFEXITED(status)) + errh->warning("%s exited abnormally", updmap_file.c_str()); + else if (WEXITSTATUS(status) != 0) + errh->warning("%s exited with status %d", updmap_file.c_str(), WEXITSTATUS(status)); # else # error "need waitpid() support: report this bug to the maintainer" # endif - goto ran_updmap; - } + goto ran_updmap; + } # if HAVE_AUTO_UPDMAP - // run system updmap - if (output_flags & G_UPDMAP) { - String filename = map_file; - int slash = filename.find_right('/'); - if (slash >= 0) - filename = filename.substring(slash + 1); + // run system updmap + if (output_flags & G_UPDMAP) { + String filename = map_file; + int slash = filename.find_right('/'); + if (slash >= 0) + filename = filename.substring(slash + 1); String redirect = verbose ? " 1>&2" : " >" DEV_NULL " 2>&1"; -#if defined(W32TEX) -// jtex_filetype is defined only in W32TeX - char *p = kpsei_var_value("jtex_filetype"); - if (p != NULL) { // W32TeX - free(p); - String option = "--add "; - } else // TeXLive -#endif - String option = "--enable Map "; - String command = "updmap --nomkmap " + option + shell_quote(filename) + redirect + String command = "updmap --nomkmap --enable Map " + shell_quote(filename) + redirect + CMD_SEP " updmap" + redirect; - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->warning("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->warning("%<%s%> exited with status %d;\nrun it manually to check for errors", command.c_str(), WEXITSTATUS(retval)); - goto ran_updmap; - } + int retval = mysystem(command.c_str(), errh); + if (retval == 127) + errh->warning("could not run %<%s%>", command.c_str()); + else if (retval < 0) + errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); + else if (retval != 0) + errh->warning("%<%s%> exited with status %d;\nrun it manually to check for errors", command.c_str(), WEXITSTATUS(retval)); + goto ran_updmap; + } # endif - if (verbose) - errh->message("not running updmap"); + if (verbose) + errh->message("not running updmap"); ran_updmap: ; #endif @@ -795,27 +769,27 @@ String locate_encoding(String encfile, ErrorHandler *errh, bool literal) { if (!encfile || encfile == "-") - return encfile; + return encfile; if (!literal) { - int slash = encfile.find_right('/'); - int dot = encfile.find_left('.', slash >= 0 ? slash : 0); - if (dot < 0) - if (String file = locate_encoding(encfile + ".enc", errh, true)) - return file; + int slash = encfile.find_right('/'); + int dot = encfile.find_left('.', slash >= 0 ? slash : 0); + if (dot < 0) + if (String file = locate_encoding(encfile + ".enc", errh, true)) + return file; } #if HAVE_KPATHSEA if (String file = kpsei_string(kpsei_find_file(encfile.c_str(), KPSEI_FMT_ENCODING))) { - if (verbose) - errh->message("encoding file %s found with kpathsea at %s", encfile.c_str(), file.c_str()); - return file; + if (verbose) + errh->message("encoding file %s found with kpathsea at %s", encfile.c_str(), file.c_str()); + return file; } else if (verbose) - errh->message("encoding file %s not found with kpathsea", encfile.c_str()); + errh->message("encoding file %s not found with kpathsea", encfile.c_str()); #endif if (access(encfile.c_str(), R_OK) >= 0) - return encfile; + return encfile; else - return String(); + return String(); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.hh 2018-02-23 12:47:54.090971778 -0500 @@ -3,13 +3,15 @@ #include class ErrorHandler; -enum { O_ENCODING = 0, O_TFM, O_PL, O_VF, O_VPL, O_TYPE1, O_MAP, O_MAP_PARENT, - O_TRUETYPE, O_OPENTYPE, O_TYPE42, NUMODIR }; +enum { + O_ENCODING = 0, O_TFM, O_PL, O_VF, O_VPL, O_TYPE1, O_MAP, O_MAP_PARENT, + O_TRUETYPE, O_OPENTYPE, O_TYPE42, NUMODIR +}; extern bool automatic; extern bool no_create; String getodir(int o, ErrorHandler *); -bool setodir(int o, const String &); +void setodir(int o, const String &); bool set_vendor(const String &); bool set_typeface(const String &, bool override); bool set_map_file(const String &); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.cc 2018-02-23 12:47:54.090971778 -0500 @@ -1,6 +1,6 @@ /* dvipsencoding.{cc,hh} -- store a DVIPS encoding * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -35,90 +35,90 @@ static Vector glyphmap; static PermString::Initializer perm_initializer; PermString DvipsEncoding::dot_notdef(".notdef"); -#define NEXT_GLYPH_NAME(gn) ("/" + (gn)) +#define NEXT_GLYPH_NAME(gn) ("/" + (gn)) void DvipsEncoding::add_glyphlist(String text) { const char *s = text.begin(), *end = text.end(); while (s != end) { - // move to first nonblank - while (s != end && isspace((unsigned char) *s)) - ++s; - // ignore comments - if (s != end && *s == '#') { - skip_to_end_of_line: - while (s != end && *s != '\n' && *s != '\r') - ++s; - continue; - } - // parse glyph name - const char *name_start = s; - while (s != end && !isspace((unsigned char) *s) && *s != ';') - ++s; - if (s == name_start) - goto skip_to_end_of_line; - String glyph_name = text.substring(name_start, s).compact(); - int map_pos = glyphmap.size(); - // parse Unicodes - while (1) { - while (s != end && (*s == ' ' || *s == '\t')) - ++s; - if (s == end || *s == '\n' || *s == '\r' || *s == '#' - || (map_pos == glyphmap.size() && *s != ';' && *s != ',')) - break; - if (*s == ';' || *s == ',') { - ++s; - while (s != end && (*s == ' ' || *s == '\t')) - ++s; - if (s == end || !isxdigit((unsigned char) *s)) - goto skip_to_end_of_line; - if (map_pos != glyphmap.size()) - glyphmap.push_back(GLYPHLIST_ALTERNATIVE); - } - uint32_t u = 0; - while (s != end && isxdigit((unsigned char) *s)) { - if (*s >= '0' && *s <= '9') - u = (u << 4) + *s - '0'; - else if (*s >= 'A' && *s <= 'F') - u = (u << 4) + *s - 'A' + 10; - else - u = (u << 4) + *s - 'a' + 10; - ++s; - } - if (u == 0 || u > 0x10FFFF) - goto skip_to_end_of_line; - glyphmap.push_back(u); - if (s != end && !isspace((unsigned char) *s) && *s != ',' && *s != ';') - break; - } - // store result - if (map_pos == glyphmap.size() - 1) { - glyphlist.insert(glyph_name, glyphmap.back()); - glyphmap.pop_back(); - } else { - glyphlist.insert(glyph_name, map_pos | GLYPHLIST_USEMAP); - glyphmap.push_back(0); - } - goto skip_to_end_of_line; + // move to first nonblank + while (s != end && isspace((unsigned char) *s)) + ++s; + // ignore comments + if (s != end && *s == '#') { + skip_to_end_of_line: + while (s != end && *s != '\n' && *s != '\r') + ++s; + continue; + } + // parse glyph name + const char *name_start = s; + while (s != end && !isspace((unsigned char) *s) && *s != ';') + ++s; + if (s == name_start) + goto skip_to_end_of_line; + String glyph_name = text.substring(name_start, s).compact(); + int map_pos = glyphmap.size(); + // parse Unicodes + while (1) { + while (s != end && (*s == ' ' || *s == '\t')) + ++s; + if (s == end || *s == '\n' || *s == '\r' || *s == '#' + || (map_pos == glyphmap.size() && *s != ';' && *s != ',')) + break; + if (*s == ';' || *s == ',') { + ++s; + while (s != end && (*s == ' ' || *s == '\t')) + ++s; + if (s == end || !isxdigit((unsigned char) *s)) + goto skip_to_end_of_line; + if (map_pos != glyphmap.size()) + glyphmap.push_back(GLYPHLIST_ALTERNATIVE); + } + uint32_t u = 0; + while (s != end && isxdigit((unsigned char) *s)) { + if (*s >= '0' && *s <= '9') + u = (u << 4) + *s - '0'; + else if (*s >= 'A' && *s <= 'F') + u = (u << 4) + *s - 'A' + 10; + else + u = (u << 4) + *s - 'a' + 10; + ++s; + } + if (u == 0 || u > 0x10FFFF) + goto skip_to_end_of_line; + glyphmap.push_back(u); + if (s != end && !isspace((unsigned char) *s) && *s != ',' && *s != ';') + break; + } + // store result + if (map_pos == glyphmap.size() - 1) { + glyphlist.insert(glyph_name, glyphmap.back()); + glyphmap.pop_back(); + } else { + glyphlist.insert(glyph_name, map_pos | GLYPHLIST_USEMAP); + glyphmap.push_back(0); + } + goto skip_to_end_of_line; } } static void unicode_add_suffix(Vector &prefix, - int prefix_starting_from, - const Vector &suffix) + int prefix_starting_from, + const Vector &suffix) { int prefix_size = prefix.size(); for (Vector::const_iterator it = suffix.begin(); - it != suffix.end() && *it != 0; - ++it) - if (*it == GLYPHLIST_ALTERNATIVE) { - prefix.push_back(*it); - for (int i = prefix_starting_from; i < prefix_size; ++i) - prefix.push_back(prefix[i]); - } else - prefix.push_back(*it); + it != suffix.end() && *it != 0; + ++it) + if (*it == GLYPHLIST_ALTERNATIVE) { + prefix.push_back(*it); + for (int i = prefix_starting_from; i < prefix_size; ++i) + prefix.push_back(prefix[i]); + } else + prefix.push_back(*it); } bool @@ -129,7 +129,7 @@ DvipsEncoding::glyphname_unicode(String // drop all characters to the right of the first dot String::iterator dot = std::find(gn.begin(), gn.end(), '.'); if (dot > gn.begin() && dot < gn.end()) - gn = gn.substring(gn.begin(), dot); + gn = gn.substring(gn.begin(), dot); // map the first component, handle later components recursively String::iterator underscore = std::find(gn.begin(), gn.end(), '_'); @@ -137,47 +137,47 @@ DvipsEncoding::glyphname_unicode(String int prefix_start = 0; Vector suffix; if (String gn_suffix = gn.substring(underscore + 1, gn.end())) { - if (!glyphname_unicode(gn_suffix, suffix)) - return false; + if (!glyphname_unicode(gn_suffix, suffix)) + return false; } // check glyphlist int value = glyphlist[component]; uint32_t uval; if (value >= 0 && !(value & GLYPHLIST_USEMAP)) - unis.push_back(value); + unis.push_back(value); else if (value >= 0) { - for (int i = (value & ~GLYPHLIST_USEMAP); - glyphmap[i]; - ++i) - if (glyphmap[i] == GLYPHLIST_ALTERNATIVE) { - unicode_add_suffix(unis, prefix_start, suffix); - unis.push_back(GLYPHLIST_ALTERNATIVE); - prefix_start = unis.size(); - } else - unis.push_back(glyphmap[i]); + for (int i = (value & ~GLYPHLIST_USEMAP); + glyphmap[i]; + ++i) + if (glyphmap[i] == GLYPHLIST_ALTERNATIVE) { + unicode_add_suffix(unis, prefix_start, suffix); + unis.push_back(GLYPHLIST_ALTERNATIVE); + prefix_start = unis.size(); + } else + unis.push_back(glyphmap[i]); } else if (component.length() >= 7 - && (component.length() % 4) == 3 - && (memcmp(component.data(), "uni", 3) == 0 - // 16.Aug.2008: Some texnansx.enc have incorrect "Uni" - // prefix, but we might as well understand it. - || memcmp(component.data(), "Uni", 3) == 0)) { - for (const char *s = component.begin() + 3; - s < component.end(); - s += 4) - if (parse_unicode_number(s, s + 4, -1, uval)) - unis.push_back(uval); - else { - unis.resize(unis_first_size); - return false; - } + && (component.length() % 4) == 3 + && (memcmp(component.data(), "uni", 3) == 0 + // 16.Aug.2008: Some texnansx.enc have incorrect "Uni" + // prefix, but we might as well understand it. + || memcmp(component.data(), "Uni", 3) == 0)) { + for (const char *s = component.begin() + 3; + s < component.end(); + s += 4) + if (parse_unicode_number(s, s + 4, -1, uval)) + unis.push_back(uval); + else { + unis.resize(unis_first_size); + return false; + } } else if (component.length() >= 5 - && component.length() <= 7 - && component[0] == 'u' - && parse_unicode_number(component.begin() + 1, component.end(), -1, uval)) - unis.push_back(uval); + && component.length() <= 7 + && component[0] == 'u' + && parse_unicode_number(component.begin() + 1, component.end(), -1, uval)) + unis.push_back(uval); else - return false; + return false; unicode_add_suffix(unis, prefix_start, suffix); return true; @@ -194,7 +194,7 @@ void DvipsEncoding::encode(int e, PermString what) { if (e >= _e.size()) - _e.resize(e + 1, dot_notdef); + _e.resize(e + 1, dot_notdef); _e[e] = what; } @@ -203,21 +203,21 @@ DvipsEncoding::encoding_of(PermString wh { int slot = -1; for (int i = 0; i < _e.size(); i++) - if (_e[i] == what) { - slot = i; - goto use_slot; - } else if (!_e[i] || _e[i] == dot_notdef) - slot = i; + if (_e[i] == what) { + slot = i; + goto use_slot; + } else if (!_e[i] || _e[i] == dot_notdef) + slot = i; if (what == "||") - return _boundary_char; + return _boundary_char; else if (!encoding_required || slot < 0) - return -1; + return -1; use_slot: if (encoding_required) { - if (slot >= _encoding_required.size()) - _encoding_required.resize(slot + 1, false); - _encoding_required[slot] = true; - this->encode(slot, what); + if (slot >= _encoding_required.size()) + _encoding_required.resize(slot + 1, false); + _encoding_required[slot] = true; + this->encode(slot, what); } return slot; } @@ -229,51 +229,51 @@ tokenize(const String &s, int &pos_in, i int len = s.length(); int pos = pos_in; while (1) { - // skip whitespace - while (pos < len && isspace((unsigned char) data[pos])) { - if (data[pos] == '\n') - line++; - else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) - line++; - pos++; - } - - if (pos >= len) { - pos_in = len; - return String(); - } else if (data[pos] == '%') { - for (pos++; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) - /* nada */; - } else if (data[pos] == '[' || data[pos] == ']' || data[pos] == '{' || data[pos] == '}') { - pos_in = pos + 1; - return s.substring(pos, 1); - } else if (data[pos] == '(') { - int first = pos, nest = 0; - for (pos++; pos < len && (data[pos] != ')' || nest); pos++) - switch (data[pos]) { - case '(': nest++; break; - case ')': nest--; break; - case '\\': - if (pos + 1 < len) - pos++; - break; - case '\n': line++; break; - case '\r': - if (pos + 1 == len || data[pos+1] != '\n') - line++; - break; - } - pos_in = (pos < len ? pos + 1 : len); - return s.substring(first, pos_in - first); - } else { - int first = pos; - while (pos < len && data[pos] == '/') - pos++; - while (pos < len && data[pos] != '/' && !isspace((unsigned char) data[pos]) && data[pos] != '[' && data[pos] != ']' && data[pos] != '%' && data[pos] != '(' && data[pos] != '{' && data[pos] != '}') - pos++; - pos_in = pos; - return s.substring(first, pos - first); - } + // skip whitespace + while (pos < len && isspace((unsigned char) data[pos])) { + if (data[pos] == '\n') + line++; + else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) + line++; + pos++; + } + + if (pos >= len) { + pos_in = len; + return String(); + } else if (data[pos] == '%') { + for (pos++; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) + /* nada */; + } else if (data[pos] == '[' || data[pos] == ']' || data[pos] == '{' || data[pos] == '}') { + pos_in = pos + 1; + return s.substring(pos, 1); + } else if (data[pos] == '(') { + int first = pos, nest = 0; + for (pos++; pos < len && (data[pos] != ')' || nest); pos++) + switch (data[pos]) { + case '(': nest++; break; + case ')': nest--; break; + case '\\': + if (pos + 1 < len) + pos++; + break; + case '\n': line++; break; + case '\r': + if (pos + 1 == len || data[pos+1] != '\n') + line++; + break; + } + pos_in = (pos < len ? pos + 1 : len); + return s.substring(first, pos_in - first); + } else { + int first = pos; + while (pos < len && data[pos] == '/') + pos++; + while (pos < len && data[pos] != '/' && !isspace((unsigned char) data[pos]) && data[pos] != '[' && data[pos] != ']' && data[pos] != '%' && data[pos] != '(' && data[pos] != '{' && data[pos] != '}') + pos++; + pos_in = pos; + return s.substring(first, pos - first); + } } } @@ -285,43 +285,43 @@ comment_tokenize(const String &s, int &p int len = s.length(); int pos = pos_in; while (1) { - while (pos < len && data[pos] != '%' && data[pos] != '(') { - if (data[pos] == '\n') - line++; - else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) - line++; - pos++; - } - - if (pos >= len) { - pos_in = len; - return String(); - } else if (data[pos] == '%') { - for (pos++; pos < len && (data[pos] == ' ' || data[pos] == '\t'); pos++) - /* nada */; - int first = pos; - for (; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) - /* nada */; - pos_in = pos; - if (pos > first) - return s.substring(first, pos - first); - } else { - int nest = 0; - for (pos++; pos < len && (data[pos] != ')' || nest); pos++) - switch (data[pos]) { - case '(': nest++; break; - case ')': nest--; break; - case '\\': - if (pos + 1 < len) - pos++; - break; - case '\n': line++; break; - case '\r': - if (pos + 1 == len || data[pos+1] != '\n') - line++; - break; - } - } + while (pos < len && data[pos] != '%' && data[pos] != '(') { + if (data[pos] == '\n') + line++; + else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) + line++; + pos++; + } + + if (pos >= len) { + pos_in = len; + return String(); + } else if (data[pos] == '%') { + for (pos++; pos < len && (data[pos] == ' ' || data[pos] == '\t'); pos++) + /* nada */; + int first = pos; + for (; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) + /* nada */; + pos_in = pos; + if (pos > first) + return s.substring(first, pos - first); + } else { + int nest = 0; + for (pos++; pos < len && (data[pos] != ')' || nest); pos++) + switch (data[pos]) { + case '(': nest++; break; + case ')': nest--; break; + case '\\': + if (pos + 1 < len) + pos++; + break; + case '\n': line++; break; + case '\r': + if (pos + 1 == len || data[pos+1] != '\n') + line++; + break; + } + } } } @@ -329,7 +329,7 @@ static bool retokenize_isword(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') - || (c >= '0' && c <= '9') || c == '.' || c == '_'; + || (c >= '0' && c <= '9') || c == '.' || c == '_'; } @@ -352,8 +352,8 @@ static int find_ligkern_op(const String &s) { for (int i = 0; ligkern_ops[i].s; i++) - if (ligkern_ops[i].s == s) - return ligkern_ops[i].v; + if (ligkern_ops[i].s == s) + return ligkern_ops[i].v; return 0; } @@ -368,16 +368,16 @@ DvipsEncoding::add_ligkern(const Ligatur { Ligature *old = std::find(_lig.begin(), _lig.end(), l); if (old == _lig.end()) - _lig.push_back(l); + _lig.push_back(l); else { - if ((l.join & JT_KERN) && (override > 0 || !(old->join & JT_KERN))) { - old->join |= JT_KERN; - old->k = l.k; - } - if ((l.join & JT_LIG) && (override > 0 || !(old->join & JT_LIG))) { - old->join = (old->join & JT_KERN) | (l.join & JT_LIGALL); - old->d = l.d; - } + if ((l.join & JT_KERN) && (override > 0 || !(old->join & JT_KERN))) { + old->join |= JT_KERN; + old->k = l.k; + } + if ((l.join & JT_LIG) && (override > 0 || !(old->join & JT_LIG))) { + old->join = (old->join & JT_KERN) | (l.join & JT_LIGALL); + old->d = l.d; + } } } @@ -389,107 +389,107 @@ DvipsEncoding::parse_ligkern_words(Vecto long l; char *endptr; if (v.size() == 3) { - // empty string fails - if (!v[0]) - return -1; - // boundary char setting - if (v[0] == "||" && v[1] == "=") { - char *endptr; - if (override > 0 || _boundary_char < 0) - _boundary_char = strtol(v[2].c_str(), &endptr, 10); - if (*endptr == 0 && _boundary_char < _e.size()) - return 0; - else - return errh->error("parse error in boundary character assignment"); - } - // altselector char setting - if (v[0] == "^^" && v[1] == "=") { - char *endptr; - if (override > 0 || _altselector_char < 0) - _altselector_char = strtol(v[2].c_str(), &endptr, 10); - if (*endptr == 0 && _altselector_char < _e.size()) - return 0; - else - return errh->error("parse error in altselector character assignment"); - } - // encoding - l = strtol(v[0].c_str(), &endptr, 0); - if (endptr == v[0].end() && v[1] == "=") { - if (l >= 0 && l < 256) { - if (override > 0 || !_e[l]) - encode(l, v[2]); - return 0; - } else - return errh->error("encoding value %<%d%> out of range", l); - } - - // kern operation - if (v[1].length() >= 3 && v[1][0] == '{' && v[1].back() == '}') { - String middle = v[1].substring(1, v[1].length() - 2); - l = strtol(middle.c_str(), &endptr, 0); - if (endptr == middle.end()) { - op = JT_KERN; - goto found_kernop; - } - } - op = find_ligkern_op(v[1]); - if (!op || (op & JT_ADDLIG)) - return -1; + // empty string fails + if (!v[0]) + return -1; + // boundary char setting + if (v[0] == "||" && v[1] == "=") { + char *endptr; + if (override > 0 || _boundary_char < 0) + _boundary_char = strtol(v[2].c_str(), &endptr, 10); + if (*endptr == 0 && _boundary_char < _e.size()) + return 0; + else + return errh->error("parse error in boundary character assignment"); + } + // altselector char setting + if (v[0] == "^^" && v[1] == "=") { + char *endptr; + if (override > 0 || _altselector_char < 0) + _altselector_char = strtol(v[2].c_str(), &endptr, 10); + if (*endptr == 0 && _altselector_char < _e.size()) + return 0; + else + return errh->error("parse error in altselector character assignment"); + } + // encoding + l = strtol(v[0].c_str(), &endptr, 0); + if (endptr == v[0].end() && v[1] == "=") { + if (l >= 0 && l < 256) { + if (override > 0 || !_e[l]) + encode(l, v[2]); + return 0; + } else + return errh->error("encoding value %<%d%> out of range", l); + } + + // kern operation + if (v[1].length() >= 3 && v[1][0] == '{' && v[1].back() == '}') { + String middle = v[1].substring(1, v[1].length() - 2); + l = strtol(middle.c_str(), &endptr, 0); + if (endptr == middle.end()) { + op = JT_KERN; + goto found_kernop; + } + } + op = find_ligkern_op(v[1]); + if (!op || (op & JT_ADDLIG)) + return -1; found_kernop: - int av = (v[0] == "*" ? J_ALL : encoding_of(v[0])); - if (av < 0) - return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[0].c_str()); - int bv = (v[2] == "*" ? J_ALL : encoding_of(v[2])); - if (bv < 0) - return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[2].c_str()); - if ((op & JT_KERN) && l && (av == J_ALL || bv == J_ALL)) - return errh->warning("%<%s %s %s%> illegal, only {0} works with *", v[0].c_str(), v[1].c_str(), v[2].c_str()); - Ligature lig = { av, bv, op, static_cast(l), 0 }; - add_ligkern(lig, override); - return 0; + int av = (v[0] == "*" ? J_ALL : encoding_of(v[0])); + if (av < 0) + return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[0].c_str()); + int bv = (v[2] == "*" ? J_ALL : encoding_of(v[2])); + if (bv < 0) + return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[2].c_str()); + if ((op & JT_KERN) && l && (av == J_ALL || bv == J_ALL)) + return errh->warning("%<%s %s %s%> illegal, only {0} works with *", v[0].c_str(), v[1].c_str(), v[2].c_str()); + Ligature lig = { av, bv, op, static_cast(l), 0 }; + add_ligkern(lig, override); + return 0; } else if (v.size() == 4 && ((op = find_ligkern_op(v[2])) & JT_ADDLIG)) { - int av = encoding_of(v[0], override > 0); - if (av < 0) - return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[0].c_str()) : -1); - int bv = encoding_of(v[1], override > 0); - if (bv < 0) - return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[1].c_str()) : -1); - int cv = encoding_of(v[3], override > 0); - if (cv < 0) - return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[3].c_str()) : -1); - Ligature lig = { av, bv, op, 0, cv }; - add_ligkern(lig, override); - return 0; + int av = encoding_of(v[0], override > 0); + if (av < 0) + return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[0].c_str()) : -1); + int bv = encoding_of(v[1], override > 0); + if (bv < 0) + return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[1].c_str()) : -1); + int cv = encoding_of(v[3], override > 0); + if (cv < 0) + return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[3].c_str()) : -1); + Ligature lig = { av, bv, op, 0, cv }; + add_ligkern(lig, override); + return 0; } else - return -EPARSE; + return -EPARSE; } int DvipsEncoding::parse_position_words(Vector &v, int override, ErrorHandler *errh) { if (v.size() != 4) - return -EPARSE; + return -EPARSE; int c = encoding_of(v[0]); if (c < 0) - return (override > 0 ? errh->warning("bad positioning (%<%s%> has no encoding)", v[0].c_str()) : -1); + return (override > 0 ? errh->warning("bad positioning (%<%s%> has no encoding)", v[0].c_str()) : -1); char *endptr; int pdx, pdy, adx; if (!v[1] || !v[2] || !v[3] - || (pdx = strtol(v[1].c_str(), &endptr, 10), *endptr) - || (pdy = strtol(v[2].c_str(), &endptr, 10), *endptr) - || (adx = strtol(v[3].c_str(), &endptr, 10), *endptr)) - return errh->error("parse error in POSITION"); + || (pdx = strtol(v[1].c_str(), &endptr, 10), *endptr) + || (pdy = strtol(v[2].c_str(), &endptr, 10), *endptr) + || (adx = strtol(v[3].c_str(), &endptr, 10), *endptr)) + return errh->error("parse error in POSITION"); Ligature l = { c, pdx, pdy, adx, 0 }; Ligature *old = std::find(_pos.begin(), _pos.end(), l); if (old == _pos.end()) - _pos.push_back(l); + _pos.push_back(l); else if (override > 0) - *old = l; + *old = l; return 0; } @@ -498,31 +498,31 @@ DvipsEncoding::parse_unicoding_words(Vec { int av; if (v.size() < 2 || (v[1] != "=" && v[1] != "=:" && v[1] != ":=")) - return -EPARSE; + return -EPARSE; else if (v[0] == "||" || (av = encoding_of(v[0])) < 0) - return errh->warning("bad UNICODING (%<%s%> has no encoding)", v[0].c_str()); + return errh->warning("bad UNICODING (%<%s%> has no encoding)", v[0].c_str()); int original_size = _unicoding.size(); if (v.size() == 2 || (v.size() == 3 && v[2] == dot_notdef)) - /* no warnings to delete a glyph */; + /* no warnings to delete a glyph */; else { - for (int i = 2; i < v.size(); i++) { - if (_unicoding.size() != original_size) - _unicoding.push_back(GLYPHLIST_ALTERNATIVE); - if (!glyphname_unicode(v[i], _unicoding)) { - errh->warning("can%,t map %<%s%> to Unicode", v[i].c_str()); - if (i == v.size() - 1 && _unicoding.size() == original_size) - errh->warning("target %<%s%> will be deleted from encoding", v[0].c_str()); - else if (_unicoding.size() != original_size) - _unicoding.pop_back(); - } - } + for (int i = 2; i < v.size(); i++) { + if (_unicoding.size() != original_size) + _unicoding.push_back(GLYPHLIST_ALTERNATIVE); + if (!glyphname_unicode(v[i], _unicoding)) { + errh->warning("can%,t map %<%s%> to Unicode", v[i].c_str()); + if (i == v.size() - 1 && _unicoding.size() == original_size) + errh->warning("target %<%s%> will be deleted from encoding", v[0].c_str()); + else if (_unicoding.size() != original_size) + _unicoding.pop_back(); + } + } } _unicoding.push_back(0); if (override > 0 || _unicoding_map[v[0]] < 0) - _unicoding_map.insert(v[0], original_size); + _unicoding_map.insert(v[0], original_size); return 0; } @@ -536,31 +536,31 @@ void DvipsEncoding::parse_word_group(Vector &words, int override, int wt, ErrorHandler *errh) { if (words.size() > 0) { - int (DvipsEncoding::*method)(Vector &, int, ErrorHandler *) = word_types[wt].parsefunc; - if ((this->*method)(words, override, errh) == -EPARSE) { - Vector rewords; - for (String *sp = words.begin(); sp != words.end(); sp++) { - const char *s = sp->begin(), *ends = sp->end(); - while (s != ends) { - const char *word = s; - if (*s == '{') { - for (s++; s != ends && *s != '}'; s++) - /* nada */; - if (s != ends) - s++; - } else { - bool x = retokenize_isword(*s); - for (s++; s != ends && x == retokenize_isword(*s); s++) - /* nada */; - } - rewords.push_back(sp->substring(word, s)); - } - } - if ((this->*method)(rewords, override, errh) == -EPARSE) - errh->error("parse error in %s", word_types[wt].name); + int (DvipsEncoding::*method)(Vector &, int, ErrorHandler *) = word_types[wt].parsefunc; + if ((this->*method)(words, override, errh) == -EPARSE) { + Vector rewords; + for (String *sp = words.begin(); sp != words.end(); sp++) { + const char *s = sp->begin(), *ends = sp->end(); + while (s != ends) { + const char *word = s; + if (*s == '{') { + for (s++; s != ends && *s != '}'; s++) + /* nada */; + if (s != ends) + s++; + } else { + bool x = retokenize_isword(*s); + for (s++; s != ends && x == retokenize_isword(*s); s++) + /* nada */; + } + rewords.push_back(sp->substring(word, s)); + } + } + if ((this->*method)(rewords, override, errh) == -EPARSE) + errh->error("parse error in %s", word_types[wt].name); - } - words.clear(); + } + words.clear(); } } @@ -571,16 +571,16 @@ DvipsEncoding::parse_words(const String const char *data = s.data(); const char *end = s.end(); while (data < end) { - while (data < end && isspace((unsigned char) *data)) - data++; - const char *first = data; - while (data < end && !isspace((unsigned char) *data) && *data != ';') - data++; - if (data == first) { - data++; // step past semicolon (or harmlessly past EOS) - parse_word_group(words, override, wt, errh); - } else - words.push_back(s.substring(first, data)); + while (data < end && isspace((unsigned char) *data)) + data++; + const char *first = data; + while (data < end && !isspace((unsigned char) *data) && *data != ';') + data++; + if (data == first) { + data++; // step past semicolon (or harmlessly past EOS) + parse_word_group(words, override, wt, errh); + } else + words.push_back(s.substring(first, data)); } parse_word_group(words, override, wt, errh); return 0; @@ -598,14 +598,14 @@ static String trim_space(const String &s, int pos) { while (pos < s.length() && isspace((unsigned char) s[pos])) - pos++; + pos++; int epos = s.length(); for (int x = 0; x < 2; x++) { - while (epos > pos && isspace((unsigned char) s[epos - 1])) - epos--; - if (epos == pos || s[epos - 1] != ';') - break; - epos--; + while (epos > pos && isspace((unsigned char) s[epos - 1])) + epos--; + if (epos == pos || s[epos - 1] != ';') + break; + epos--; } return s.substring(pos, epos - pos); } @@ -616,7 +616,7 @@ DvipsEncoding::parse(String filename, bo int before = errh->nerrors(); String s = read_file(filename, errh); if (errh->nerrors() != before) - return -1; + return -1; _filename = filename; _printable_filename = printable_filename(filename); _file_had_ligkern = false; @@ -625,15 +625,15 @@ DvipsEncoding::parse(String filename, bo // parse text String token = tokenize(s, pos, line); if (!token || token[0] != '/') - return errh->lerror(landmark(line), "parse error, expected name"); + return errh->lerror(landmark(line), "parse error, expected name"); _name = token.substring(1); _initial_comment = s.substring(0, pos - token.length()); if (tokenize(s, pos, line) != "[") - return errh->lerror(landmark(line), "parse error, expected ["); + return errh->lerror(landmark(line), "parse error, expected ["); while ((token = tokenize(s, pos, line)) && token[0] == '/') - _e.push_back(token.substring(1)); + _e.push_back(token.substring(1)); _final_text = token + s.substring(pos); @@ -642,59 +642,59 @@ DvipsEncoding::parse(String filename, bo Vector words; LandmarkErrorHandler lerrh(errh, ""); while ((token = comment_tokenize(s, pos, line))) - if (token.length() >= 8 - && memcmp(token.data(), "LIGKERN", 7) == 0 - && isspace((unsigned char) token[7]) - && !ignore_ligkern) { - lerrh.set_landmark(landmark(line)); - parse_words(token.substring(8), 1, WT_LIGKERN, &lerrh); - - } else if (token.length() >= 9 - && memcmp(token.data(), "LIGKERNX", 8) == 0 - && isspace((unsigned char) token[8]) - && !ignore_ligkern) { - lerrh.set_landmark(landmark(line)); - parse_words(token.substring(9), 1, WT_LIGKERN, &lerrh); - - } else if (token.length() >= 10 - && memcmp(token.data(), "UNICODING", 9) == 0 - && isspace((unsigned char) token[9]) - && !ignore_other) { - lerrh.set_landmark(landmark(line)); - parse_words(token.substring(10), 1, WT_UNICODING, &lerrh); - - } else if (token.length() >= 9 - && memcmp(token.data(), "POSITION", 8) == 0 - && isspace((unsigned char) token[8]) - && !ignore_other) { - lerrh.set_landmark(landmark(line)); - parse_words(token.substring(9), 1, WT_POSITION, &lerrh); - - } else if (token.length() >= 13 - && memcmp(token.data(), "CODINGSCHEME", 12) == 0 - && isspace((unsigned char) token[12]) - && !ignore_other) { - _coding_scheme = trim_space(token, 13); - if (_coding_scheme.length() > 39) - lerrh.lwarning(landmark(line), "only first 39 chars of CODINGSCHEME are significant"); - if (std::find(_coding_scheme.begin(), _coding_scheme.end(), '(') < _coding_scheme.end() - || std::find(_coding_scheme.begin(), _coding_scheme.end(), ')') < _coding_scheme.end()) { - lerrh.lerror(landmark(line), "CODINGSCHEME cannot contain parentheses"); - _coding_scheme = String(); - } - - } else if (token.length() >= 11 - && memcmp(token.data(), "WARNMISSING", 11) == 0 - && (token.length() == 11 || isspace((unsigned char) token[11])) - && !ignore_other) { - String value = trim_space(token, 11); - if (value == "1" || value == "yes" || value == "true" || !value) - _warn_missing = true; - else if (value == "0" || value == "no" || value == "false") - _warn_missing = false; - else - lerrh.lerror(landmark(line), "WARNMISSING command not understood"); - } + if (token.length() >= 8 + && memcmp(token.data(), "LIGKERN", 7) == 0 + && isspace((unsigned char) token[7]) + && !ignore_ligkern) { + lerrh.set_landmark(landmark(line)); + parse_words(token.substring(8), 1, WT_LIGKERN, &lerrh); + + } else if (token.length() >= 9 + && memcmp(token.data(), "LIGKERNX", 8) == 0 + && isspace((unsigned char) token[8]) + && !ignore_ligkern) { + lerrh.set_landmark(landmark(line)); + parse_words(token.substring(9), 1, WT_LIGKERN, &lerrh); + + } else if (token.length() >= 10 + && memcmp(token.data(), "UNICODING", 9) == 0 + && isspace((unsigned char) token[9]) + && !ignore_other) { + lerrh.set_landmark(landmark(line)); + parse_words(token.substring(10), 1, WT_UNICODING, &lerrh); + + } else if (token.length() >= 9 + && memcmp(token.data(), "POSITION", 8) == 0 + && isspace((unsigned char) token[8]) + && !ignore_other) { + lerrh.set_landmark(landmark(line)); + parse_words(token.substring(9), 1, WT_POSITION, &lerrh); + + } else if (token.length() >= 13 + && memcmp(token.data(), "CODINGSCHEME", 12) == 0 + && isspace((unsigned char) token[12]) + && !ignore_other) { + _coding_scheme = trim_space(token, 13); + if (_coding_scheme.length() > 39) + lerrh.lwarning(landmark(line), "only first 39 chars of CODINGSCHEME are significant"); + if (std::find(_coding_scheme.begin(), _coding_scheme.end(), '(') < _coding_scheme.end() + || std::find(_coding_scheme.begin(), _coding_scheme.end(), ')') < _coding_scheme.end()) { + lerrh.lerror(landmark(line), "CODINGSCHEME cannot contain parentheses"); + _coding_scheme = String(); + } + + } else if (token.length() >= 11 + && memcmp(token.data(), "WARNMISSING", 11) == 0 + && (token.length() == 11 || isspace((unsigned char) token[11])) + && !ignore_other) { + String value = trim_space(token, 11); + if (value == "1" || value == "yes" || value == "true" || !value) + _warn_missing = true; + else if (value == "0" || value == "no" || value == "false") + _warn_missing = false; + else + lerrh.lerror(landmark(line), "WARNMISSING command not understood"); + } return 0; } @@ -721,23 +721,23 @@ void DvipsEncoding::bad_codepoint(int code, Metrics &metrics, HashMap &unencoded) { for (int i = 0; i < _lig.size(); i++) { - Ligature &l = _lig[i]; - if (l.c1 == code || l.c2 == code) - l.join = 0; - else if ((l.join & JT_ADDLIG) && l.d == code) - l.join &= ~JT_LIGALL; + Ligature &l = _lig[i]; + if (l.c1 == code || l.c2 == code) + l.join = 0; + else if ((l.join & JT_ADDLIG) && l.d == code) + l.join &= ~JT_LIGALL; } if (_warn_missing) { - Vector garbage; - bool unicodes_explicit = x_unicodes(_e[code], garbage); - if (!unicodes_explicit || garbage.size() > 0) { - Vector v; - v.push_back(Setting(Setting::RULE, 500, 500)); - v.push_back(Setting(Setting::SPECIAL, String("Warning: missing glyph '") + _e[code] + "'")); - metrics.encode_virtual(code, _e[code], 0, v, true); - unencoded.insert(_e[code], 1); - } + Vector garbage; + bool unicodes_explicit = x_unicodes(_e[code], garbage); + if (!unicodes_explicit || garbage.size() > 0) { + Vector v; + v.push_back(Setting(Setting::RULE, 500, 500)); + v.push_back(Setting(Setting::SPECIAL, String("Warning: missing glyph '") + _e[code] + "'")); + metrics.encode_virtual(code, _e[code], 0, v, true); + unencoded.insert(_e[code], 1); + } } } @@ -745,9 +745,9 @@ static inline Efont::OpenType::Glyph map_uni(uint32_t uni, const Efont::OpenType::Cmap &cmap, const Metrics &m) { if (uni == U_EMPTYSLOT) - return m.emptyslot_glyph(); + return m.emptyslot_glyph(); else - return cmap.map_uni(uni); + return cmap.map_uni(uni); } bool @@ -755,12 +755,12 @@ DvipsEncoding::x_unicodes(PermString chn { int i = _unicoding_map[chname]; if (i >= 0) { - for (; _unicoding[i] > 0; i++) - unicodes.push_back(_unicoding[i]); - return true; + for (; _unicoding[i] > 0; i++) + unicodes.push_back(_unicoding[i]); + return true; } else { - glyphname_unicode(chname, unicodes); - return false; + glyphname_unicode(chname, unicodes); + return false; } } @@ -770,144 +770,144 @@ DvipsEncoding::make_metrics(Metrics &met { // first pass: without secondaries for (int code = 0; code < _e.size(); code++) { - PermString chname = _e[code]; + PermString chname = _e[code]; - // common case: skip .notdef - if (chname == dot_notdef) - continue; - - // find first single Unicode glyph supported by the font - Efont::OpenType::Glyph glyph = 0; - uint32_t glyph_uni = 0; - { - Vector unicodes; - (void) x_unicodes(chname, unicodes); - Vector::iterator u = unicodes.begin(); - while (u != unicodes.end() && glyph <= 0) { - uint32_t this_uni = u[0]; - ++u; - if (u != unicodes.end()) { - if (*u != GLYPHLIST_ALTERNATIVE) - break; - ++u; - } - - glyph = map_uni(this_uni, *finfo.cmap, metrics); - if (glyph_uni == 0 || glyph > 0) - glyph_uni = this_uni; - } - } + // common case: skip .notdef + if (chname == dot_notdef) + continue; + + // find first single Unicode glyph supported by the font + Efont::OpenType::Glyph glyph = 0; + uint32_t glyph_uni = 0; + { + Vector unicodes; + (void) x_unicodes(chname, unicodes); + Vector::iterator u = unicodes.begin(); + while (u != unicodes.end() && glyph <= 0) { + uint32_t this_uni = u[0]; + ++u; + if (u != unicodes.end()) { + if (*u != GLYPHLIST_ALTERNATIVE) + break; + ++u; + } + + glyph = map_uni(this_uni, *finfo.cmap, metrics); + if (glyph_uni == 0 || glyph > 0) + glyph_uni = this_uni; + } + } - // find named glyph, if any - Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); + // find named glyph, if any + Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); #if 0 - // 2.May.2008: ff, fi, fl, ffi, and ffl might map to f_f, f_i, f_l, - // f_f_i, and f_f_l - if (!named_glyph && chname.length() > 0 && chname.length() <= 3 - && chname[0] == 'f') { - if (chname.equals("ff", 2)) - named_glyph = finfo.glyphid("f_f"); - else if (chname.equals("fi", 2)) - named_glyph = finfo.glyphid("f_i"); - else if (chname.equals("fl", 2)) - named_glyph = finfo.glyphid("f_l"); - else if (chname.equals("ffi", 2)) - named_glyph = finfo.glyphid("f_f_i"); - else if (chname.equals("ffl", 2)) - named_glyph = finfo.glyphid("f_f_l"); - } + // 2.May.2008: ff, fi, fl, ffi, and ffl might map to f_f, f_i, f_l, + // f_f_i, and f_f_l + if (!named_glyph && chname.length() > 0 && chname.length() <= 3 + && chname[0] == 'f') { + if (chname.equals("ff", 2)) + named_glyph = finfo.glyphid("f_f"); + else if (chname.equals("fi", 2)) + named_glyph = finfo.glyphid("f_i"); + else if (chname.equals("fl", 2)) + named_glyph = finfo.glyphid("f_l"); + else if (chname.equals("ffi", 2)) + named_glyph = finfo.glyphid("f_f_i"); + else if (chname.equals("ffl", 2)) + named_glyph = finfo.glyphid("f_f_l"); + } #endif - // do not use a Unicode-mapped glyph if literal - if (literal) - glyph = named_glyph; - - // If we found a glyph, maybe use its named_glyph variant. - if (glyph > 0 && named_glyph > 0 - && std::find(chname.begin(), chname.end(), '.') < chname.end()) - glyph = named_glyph; - - // assign slot - if (glyph > 0) - metrics.encode(code, glyph_uni, glyph); + // do not use a Unicode-mapped glyph if literal + if (literal) + glyph = named_glyph; + + // If we found a glyph, maybe use its named_glyph variant. + if (glyph > 0 && named_glyph > 0 + && std::find(chname.begin(), chname.end(), '.') < chname.end()) + glyph = named_glyph; + + // assign slot + if (glyph > 0) + metrics.encode(code, glyph_uni, glyph); } // second pass: with secondaries for (int code = 0; code < _e.size(); code++) { - // skip already-encoded characters and .notdef - if (literal || metrics.glyph(code) > 0 || _e[code] == dot_notdef) - continue; - - PermString chname = _e[code]; - - // find all Unicodes - Vector unicodes; - bool unicodes_explicit = x_unicodes(chname, unicodes); - - // find named glyph, if any - Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); - - // 1. We were not able to find the glyph using Unicode. - // 2. There might be a named_glyph. - // May need to try secondaries later. Store this slot. - // Try secondaries, if there's explicit unicoding or no named_glyph. - if (unicodes_explicit || named_glyph <= 0) - for (uint32_t *u = unicodes.begin(); u != unicodes.end(); ) { - uint32_t *endu = u + 1; - while (endu != unicodes.end() && *endu != GLYPHLIST_ALTERNATIVE) - ++endu; - if (secondary->encode_uni(code, chname, u, endu, metrics, errh)) - goto encoded; - u = (endu == unicodes.end() ? endu : endu + 1); - } - - // 1. We were not able to find the glyph using Unicode or secondaries. - // 2. There might be a named_glyph. - // Use named glyph, if any. Special case for "UNICODING foo =: ;", - // which should turn off the character (even if a named_glyph exists), - // UNLESS the glyph was explicitly requested. - if (named_glyph > 0 - && (!unicodes_explicit - || unicodes.size() > 0 - || (_encoding_required.size() > code && _encoding_required[code]))) { - uint32_t uni = 0; - if (unicodes.size() == 1 || (unicodes.size() > 0 && unicodes[1] == GLYPHLIST_ALTERNATIVE)) - uni = unicodes[0]; - metrics.encode(code, uni, named_glyph); - } + // skip already-encoded characters and .notdef + if (literal || metrics.glyph(code) > 0 || _e[code] == dot_notdef) + continue; + + PermString chname = _e[code]; + + // find all Unicodes + Vector unicodes; + bool unicodes_explicit = x_unicodes(chname, unicodes); + + // find named glyph, if any + Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); + + // 1. We were not able to find the glyph using Unicode. + // 2. There might be a named_glyph. + // May need to try secondaries later. Store this slot. + // Try secondaries, if there's explicit unicoding or no named_glyph. + if (unicodes_explicit || named_glyph <= 0) + for (uint32_t *u = unicodes.begin(); u != unicodes.end(); ) { + uint32_t *endu = u + 1; + while (endu != unicodes.end() && *endu != GLYPHLIST_ALTERNATIVE) + ++endu; + if (secondary->encode_uni(code, chname, u, endu, metrics, errh)) + goto encoded; + u = (endu == unicodes.end() ? endu : endu + 1); + } + + // 1. We were not able to find the glyph using Unicode or secondaries. + // 2. There might be a named_glyph. + // Use named glyph, if any. Special case for "UNICODING foo =: ;", + // which should turn off the character (even if a named_glyph exists), + // UNLESS the glyph was explicitly requested. + if (named_glyph > 0 + && (!unicodes_explicit + || unicodes.size() > 0 + || (_encoding_required.size() > code && _encoding_required[code]))) { + uint32_t uni = 0; + if (unicodes.size() == 1 || (unicodes.size() > 0 && unicodes[1] == GLYPHLIST_ALTERNATIVE)) + uni = unicodes[0]; + metrics.encode(code, uni, named_glyph); + } encoded: - /* all set */; + /* all set */; } // add altselector if (_altselector_char >= 0 && _altselector_char < _e.size()) { - metrics.add_altselector_code(_altselector_char, 0); - if (metrics.glyph(_altselector_char) <= 0 && !literal) - (void) secondary->encode_uni(_altselector_char, "altselector", U_ALTSELECTOR, metrics, errh); + metrics.add_altselector_code(_altselector_char, 0); + if (metrics.glyph(_altselector_char) <= 0 && !literal) + (void) secondary->encode_uni(_altselector_char, "", U_ALTSELECTOR, metrics, errh); } // final pass: complain HashMap unencoded_map; for (int code = 0; code < _e.size(); code++) - if (_e[code] != dot_notdef && metrics.glyph(code) <= 0) - bad_codepoint(code, metrics, unencoded_map); + if (_e[code] != dot_notdef && metrics.glyph(code) <= 0) + bad_codepoint(code, metrics, unencoded_map); Vector unencoded; for (HashMap::iterator it = unencoded_map.begin(); it; ++it) - unencoded.push_back(it.key()); + unencoded.push_back(it.key()); if (unencoded.size() == 1) { - errh->warning("%<%s%> glyph not found in font", unencoded[0].c_str()); - errh->message("(This glyph will appear as a blot and cause warnings if used.)"); + errh->warning("%<%s%> glyph not found in font", unencoded[0].c_str()); + errh->message("(This glyph will appear as a blot and cause warnings if used.)"); } else if (unencoded.size() > 1) { - std::sort(unencoded.begin(), unencoded.end()); - StringAccum sa; - for (const String* a = unencoded.begin(); a < unencoded.end(); a++) - sa << *a << ' '; - sa.pop_back(); - sa.append_break_lines(sa.take_string(), 68, " "); - sa.pop_back(); - errh->warning("%d glyphs not found in font:", unencoded.size()); - errh->message("%s\n(These glyphs will appear as blots and cause warnings if used.)", sa.c_str()); + std::sort(unencoded.begin(), unencoded.end()); + StringAccum sa; + for (const String* a = unencoded.begin(); a < unencoded.end(); a++) + sa << *a << ' '; + sa.pop_back(); + sa.append_break_lines(sa.take_string(), 68, " "); + sa.pop_back(); + errh->warning("%d glyphs not found in font:", unencoded.size()); + errh->message("%s\n(These glyphs will appear as blots and cause warnings if used.)", sa.c_str()); } metrics.set_coding_scheme(_coding_scheme); @@ -918,19 +918,19 @@ DvipsEncoding::make_base_mappings(Vector { mappings.clear(); for (int code = 0; code < _e.size(); code++) { - PermString chname = _e[code]; + PermString chname = _e[code]; - // common case: skip .notdef - if (chname == dot_notdef) - continue; - - // find named glyph - Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); - if (named_glyph > 0) { - if (mappings.size() <= named_glyph) - mappings.resize(named_glyph + 1, -1); - mappings[named_glyph] = code; - } + // common case: skip .notdef + if (chname == dot_notdef) + continue; + + // find named glyph + Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); + if (named_glyph > 0) { + if (mappings.size() <= named_glyph) + mappings.resize(named_glyph + 1, -1); + mappings[named_glyph] = code; + } } } @@ -940,24 +940,24 @@ DvipsEncoding::apply_ligkern_lig(Metrics { assert((int)J_ALL == (int)Metrics::CODE_ALL); for (const Ligature *l = _lig.begin(); l < _lig.end(); l++) { - if (l->c1 < 0 || l->c2 < 0 || l->join < 0 || !(l->join & JT_LIG)) - continue; - metrics.remove_ligatures(l->c1, l->c2); - if (!(l->join & JT_ADDLIG)) - /* nada */; - else if ((l->join & JT_LIGALL) == JL_LIG) - metrics.add_ligature(l->c1, l->c2, l->d); - else if ((l->join & JT_LIGALL) == JL_LIGC) - metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->d, l->c2)); - else if ((l->join & JT_LIGALL) == JL_CLIG) - metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->c1, l->d)); - else { - static int complex_join_warning = 0; - if (!complex_join_warning) { - errh->warning("complex LIGKERN ligature removed (I only support %<=:%>, %<=:|%>, and %<|=:%>)"); - complex_join_warning = 1; - } - } + if (l->c1 < 0 || l->c2 < 0 || l->join < 0 || !(l->join & JT_LIG)) + continue; + metrics.remove_ligatures(l->c1, l->c2); + if (!(l->join & JT_ADDLIG)) + /* nada */; + else if ((l->join & JT_LIGALL) == JL_LIG) + metrics.add_ligature(l->c1, l->c2, l->d); + else if ((l->join & JT_LIGALL) == JL_LIGC) + metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->d, l->c2)); + else if ((l->join & JT_LIGALL) == JL_CLIG) + metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->c1, l->d)); + else { + static int complex_join_warning = 0; + if (!complex_join_warning) { + errh->warning("complex LIGKERN ligature removed (I only support %<=:%>, %<=:|%>, and %<|=:%>)"); + complex_join_warning = 1; + } + } } } @@ -966,14 +966,14 @@ DvipsEncoding::apply_ligkern_kern(Metric { assert((int)J_ALL == (int)Metrics::CODE_ALL); for (const Ligature *l = _lig.begin(); l < _lig.end(); l++) - if (l->c1 >= 0 && l->c2 >= 0 && (l->join & JT_KERN)) - metrics.set_kern(l->c1, l->c2, l->k); + if (l->c1 >= 0 && l->c2 >= 0 && (l->join & JT_KERN)) + metrics.set_kern(l->c1, l->c2, l->k); } void DvipsEncoding::apply_position(Metrics &metrics, ErrorHandler *) const { for (const Ligature *l = _pos.begin(); l < _pos.end(); l++) - if (l->c1 >= 0) - metrics.add_single_positioning(l->c1, l->c2, l->join, l->k); + if (l->c1 >= 0) + metrics.add_single_positioning(l->c1, l->c2, l->join, l->k); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/dvipsencoding.hh 2018-02-23 12:47:54.090971778 -0500 @@ -13,27 +13,27 @@ class DvipsEncoding { public: static void add_glyphlist(String); - operator bool() const { return _e.size() > 0; } - const String &name() const { return _name; } - const String &filename() const { return _filename; } - int boundary_char() const { return _boundary_char; } - const String &coding_scheme() const { return _coding_scheme; } - void set_coding_scheme(const String &s) { _coding_scheme = s; } - void set_warn_missing(bool wm) { _warn_missing = wm; } + operator bool() const { return _e.size() > 0; } + const String &name() const { return _name; } + const String &filename() const { return _filename; } + int boundary_char() const { return _boundary_char; } + const String &coding_scheme() const { return _coding_scheme; } + void set_coding_scheme(const String &s) { _coding_scheme = s; } + void set_warn_missing(bool wm) { _warn_missing = wm; } void encode(int, PermString); inline int encoding_of(PermString) const; int encoding_of(PermString, bool encode); inline bool encoded(int e) const; inline PermString encoding(int e) const; - int encoding_size() const { return _e.size(); } + int encoding_size() const { return _e.size(); } int parse(String filename, bool ignore_ligkern, bool ignore_other, ErrorHandler *); int parse_ligkern(const String &ligkern_text, int override, ErrorHandler *); int parse_position(const String &ligkern_text, int override, ErrorHandler *); int parse_unicoding(const String &unicoding_text, int override, ErrorHandler *); - bool file_had_ligkern() const { return _file_had_ligkern; } + bool file_had_ligkern() const { return _file_had_ligkern; } // also modifies 'this': void make_metrics(Metrics &, const FontInfo &, Secondary *, bool literal, ErrorHandler *); @@ -44,17 +44,17 @@ class DvipsEncoding { public: void apply_position(Metrics &, ErrorHandler *) const; enum { JT_KERN = 32, JT_LIG = 64, JT_ADDLIG = 128, JT_LIGALL = 199, - JL_LIG = JT_LIG | JT_ADDLIG, JL_CLIG = JL_LIG | 1, - JL_CLIG_S = JL_LIG | 2, JL_LIGC = JL_LIG | 3, - JL_LIGC_S = JL_LIG | 4, JL_CLIGC = JL_LIG | 5, - JL_CLIGC_S = JL_LIG | 6, JL_CLIGC_SS = JL_LIG | 7, - JT_NOLIGKERN = JT_KERN | JT_LIG, - J_ALL = 0x7FFFFFFF }; // also see nokern_names in dvipsencoding.cc + JL_LIG = JT_LIG | JT_ADDLIG, JL_CLIG = JL_LIG | 1, + JL_CLIG_S = JL_LIG | 2, JL_LIGC = JL_LIG | 3, + JL_LIGC_S = JL_LIG | 4, JL_CLIGC = JL_LIG | 5, + JL_CLIGC_S = JL_LIG | 6, JL_CLIGC_SS = JL_LIG | 7, + JT_NOLIGKERN = JT_KERN | JT_LIG, + J_ALL = 0x7FFFFFFF }; // also see nokern_names in dvipsencoding.cc private: struct Ligature { - int c1, c2, join, k, d; + int c1, c2, join, k, d; }; Vector _e; @@ -79,8 +79,8 @@ class DvipsEncoding { public: bool _warn_missing; struct WordType { - const char *name; - int (DvipsEncoding::*parsefunc)(Vector&, int, ErrorHandler*); + const char *name; + int (DvipsEncoding::*parsefunc)(Vector&, int, ErrorHandler*); }; static const WordType word_types[]; enum { WT_LIGKERN = 0, WT_POSITION, WT_UNICODING }; @@ -114,9 +114,9 @@ inline PermString DvipsEncoding::encoding(int e) const { if (encoded(e)) - return _e[e]; + return _e[e]; else - return PermString(); + return PermString(); } inline int diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.cc 2018-02-23 12:47:54.090971778 -0500 @@ -1,6 +1,6 @@ /* glyphfilter.{cc,hh} -- define subsets of characters * - * Copyright (c) 2004-2016 Eddie Kohler + * Copyright (c) 2004-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -30,7 +30,7 @@ GlyphFilter::allow(Efont::OpenType::Glyp { // out-of-range glyphs never match if (glyph < 0 || glyph >= glyph_names.size()) - return false; + return false; String glyph_name = glyph_names[glyph]; int uniprop = -1; @@ -39,32 +39,32 @@ GlyphFilter::allow(Efont::OpenType::Glyp // loop over patterns for (const Pattern* p = _patterns.begin(); p < _patterns.end(); p++) { - // check pattern type - if ((p->type & ~T_TYPEMASK) != ptype) - continue; - // check include/exclude - if ((p->type & T_EXCLUDE) == 0) { - if (included) - continue; - any_includes = true; - } - // check if there's a match - bool match; - if (p->data == D_NAME) - match = glob_match(glyph_name, p->pattern); - else if (p->data == D_UNIPROP) { - if (uniprop < 0) - uniprop = UnicodeProperty::property(unicode); - match = ((uniprop & p->u.uniprop.mask) == p->u.uniprop.value); - } else - match = (unicode >= p->u.unirange.low && unicode <= p->u.unirange.high); - // act if match - if (match == ((p->type & T_NEGATE) == 0)) { - if ((p->type & T_EXCLUDE) == 0) - included = true; - else - return false; - } + // check pattern type + if ((p->type & ~T_TYPEMASK) != ptype) + continue; + // check include/exclude + if ((p->type & T_EXCLUDE) == 0) { + if (included) + continue; + any_includes = true; + } + // check if there's a match + bool match; + if (p->data == D_NAME) + match = glob_match(glyph_name, p->pattern); + else if (p->data == D_UNIPROP) { + if (uniprop < 0) + uniprop = UnicodeProperty::property(unicode); + match = ((uniprop & p->u.uniprop.mask) == p->u.uniprop.value); + } else + match = (unicode >= p->u.unirange.low && unicode <= p->u.unirange.high); + // act if match + if (match == ((p->type & T_NEGATE) == 0)) { + if ((p->type & T_EXCLUDE) == 0) + included = true; + else + return false; + } } return !any_includes || included; @@ -83,13 +83,13 @@ GlyphFilter::Pattern::compare(const Glyp { int cmp = a.type - b.type; if (cmp == 0) - cmp = a.data - b.data; + cmp = a.data - b.data; if (cmp == 0) - cmp = (int) (a.u.unirange.low - b.u.unirange.low); + cmp = (int) (a.u.unirange.low - b.u.unirange.low); if (cmp == 0) - cmp = (int) (a.u.unirange.high - b.u.unirange.high); + cmp = (int) (a.u.unirange.high - b.u.unirange.high); if (cmp == 0) - cmp = String::compare(a.pattern, b.pattern); + cmp = String::compare(a.pattern, b.pattern); return cmp; } @@ -101,59 +101,59 @@ GlyphFilter::add_pattern(const String& p const char* begin = pattern.begin(); const char* end = pattern.end(); while (begin < end && isspace((unsigned char) *begin)) - begin++; + begin++; if (begin >= end) - errh->error("missing pattern"); + errh->error("missing pattern"); while (begin < end) { - const char* word = begin; - while (word < end && !isspace((unsigned char) *word)) - word++; - bool negated = false; - if (begin < word && begin[0] == '!') - negated = true, begin++; - - // actually parse clause - Pattern p(ptype + (negated ? T_NEGATE : 0)); - - // unicode property - if (begin + 3 <= word && begin[0] == '<' && word[-1] == '>') { - p.data = D_UNIPROP; - if (UnicodeProperty::parse_property(pattern.substring(begin + 1, word - 1), p.u.uniprop.value, p.u.uniprop.mask)) - _patterns.push_back(p); - else if (errh) - errh->error("unknown Unicode property %<%s%>", pattern.c_str()); - goto next_clause; - } - - // unicode values - { - const char* dash = std::find(begin, word, '-'); - if (parse_unicode_number(begin, dash, 2, p.u.unirange.low)) { - if (dash == word) - p.u.unirange.high = p.u.unirange.low; - else if (dash == word - 1) - p.u.unirange.high = 0xFFFFFFFFU; - else if (parse_unicode_number(dash + 1, word, (begin[0] == 'U' ? 1 : 0), p.u.unirange.high)) - /* do nothing */; - else - goto name_pattern; // assume it's a name - p.data = D_UNIRANGE; - _patterns.push_back(p); - goto next_clause; - } - } + const char* word = begin; + while (word < end && !isspace((unsigned char) *word)) + word++; + bool negated = false; + if (begin < word && begin[0] == '!') + negated = true, begin++; + + // actually parse clause + Pattern p(ptype + (negated ? T_NEGATE : 0)); + + // unicode property + if (begin + 3 <= word && begin[0] == '<' && word[-1] == '>') { + p.data = D_UNIPROP; + if (UnicodeProperty::parse_property(pattern.substring(begin + 1, word - 1), p.u.uniprop.value, p.u.uniprop.mask)) + _patterns.push_back(p); + else if (errh) + errh->error("unknown Unicode property %<%s%>", pattern.c_str()); + goto next_clause; + } + + // unicode values + { + const char* dash = std::find(begin, word, '-'); + if (parse_unicode_number(begin, dash, 2, p.u.unirange.low)) { + if (dash == word) + p.u.unirange.high = p.u.unirange.low; + else if (dash == word - 1) + p.u.unirange.high = 0xFFFFFFFFU; + else if (parse_unicode_number(dash + 1, word, (begin[0] == 'U' ? 1 : 0), p.u.unirange.high)) + /* do nothing */; + else + goto name_pattern; // assume it's a name + p.data = D_UNIRANGE; + _patterns.push_back(p); + goto next_clause; + } + } - // otherwise must be name pattern + // otherwise must be name pattern name_pattern: - p.data = D_NAME; - p.pattern = pattern.substring(begin, word); - _patterns.push_back(p); + p.data = D_NAME; + p.pattern = pattern.substring(begin, word); + _patterns.push_back(p); - // move to next clause + // move to next clause next_clause: - for (begin = word; begin < end && isspace((unsigned char) *begin); begin++) - /* nada */; + for (begin = word; begin < end && isspace((unsigned char) *begin); begin++) + /* nada */; } } @@ -176,7 +176,7 @@ GlyphFilter::operator+=(const GlyphFilte _patterns.reserve(gf._patterns.size()); const Pattern* end = gf._patterns.end(); for (const Pattern* p = gf._patterns.begin(); p < end; p++) - _patterns.push_back(*p); + _patterns.push_back(*p); return *this; } @@ -184,9 +184,9 @@ GlyphFilter operator+(const GlyphFilter& a, const GlyphFilter& b) { if (!b) - return a; + return a; if (!a) - return b; + return b; GlyphFilter x(a); x += b; return x; @@ -196,14 +196,14 @@ bool operator==(const GlyphFilter& a, const GlyphFilter& b) { if (&a == &b) - return true; + return true; if (a._patterns.size() != b._patterns.size()) - return false; + return false; const GlyphFilter::Pattern* pa = a._patterns.begin(); const GlyphFilter::Pattern* pb = b._patterns.begin(); for (; pa < a._patterns.end(); pa++, pb++) - if (!(*pa == *pb)) - return false; + if (!(*pa == *pb)) + return false; return true; } @@ -211,10 +211,10 @@ void GlyphFilter::sort() { if (!_sorted) { - std::sort(_patterns.begin(), _patterns.end()); - Pattern* true_end = std::unique(_patterns.begin(), _patterns.end()); - _patterns.erase(true_end, _patterns.end()); - _sorted = true; + std::sort(_patterns.begin(), _patterns.end()); + Pattern* true_end = std::unique(_patterns.begin(), _patterns.end()); + _patterns.erase(true_end, _patterns.end()); + _sorted = true; } } @@ -222,15 +222,15 @@ void GlyphFilter::unparse(StringAccum& sa) const { for (const Pattern* p = _patterns.begin(); p < _patterns.end(); p++) { - sa << (p->type & T_DST ? 'D' : 'S') << (p->type & T_NEGATE ? "!" : "") << (p->type & T_EXCLUDE ? "X" : ""); - if (p->data == D_NAME) - sa << '<' << p->pattern << '>'; - else if (p->data == D_UNIPROP) - sa << "[UNIPROP:" << p->u.uniprop.mask << '=' << p->u.uniprop.value << ']'; - else - sa.snprintf(20, "[U+%02x-U+%02x]", p->u.unirange.low, p->u.unirange.high); - sa << ' '; + sa << (p->type & T_DST ? 'D' : 'S') << (p->type & T_NEGATE ? "!" : "") << (p->type & T_EXCLUDE ? "X" : ""); + if (p->data == D_NAME) + sa << '<' << p->pattern << '>'; + else if (p->data == D_UNIPROP) + sa << "[UNIPROP:" << p->u.uniprop.mask << '=' << p->u.uniprop.value << ']'; + else + sa.snprintf(20, "[U+%02x-U+%02x]", p->u.unirange.low, p->u.unirange.high); + sa << ' '; } if (_patterns.size()) - sa.pop_back(); + sa.pop_back(); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/glyphfilter.hh 2018-02-23 12:47:54.091971753 -0500 @@ -6,9 +6,9 @@ class Metrics; class GlyphFilter { public: - GlyphFilter() : _sorted(true) { } + GlyphFilter() : _sorted(true) { } - operator bool() const { return _patterns.size() != 0; } + operator bool() const { return _patterns.size() != 0; } inline bool allow_substitution(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const; inline bool allow_alternate(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const; @@ -17,34 +17,34 @@ class GlyphFilter { public: void add_alternate_filter(const String&, bool is_exclude, ErrorHandler*); friend bool operator==(const GlyphFilter&, const GlyphFilter&); - inline bool check_eq(GlyphFilter&); // may alter both GlyphFilters + inline bool check_eq(GlyphFilter&); // may alter both GlyphFilters GlyphFilter& operator+=(const GlyphFilter&); void unparse(StringAccum&) const; struct Pattern { - uint16_t type; - uint16_t data; - union { - struct { - int mask; - int value; - } uniprop; - struct { - uint32_t low; - uint32_t high; - } unirange; - } u; - String pattern; - Pattern(uint16_t type); - static int compare(const Pattern&, const Pattern&); + uint16_t type; + uint16_t data; + union { + struct { + int mask; + int value; + } uniprop; + struct { + uint32_t low; + uint32_t high; + } unirange; + } u; + String pattern; + Pattern(uint16_t type); + static int compare(const Pattern&, const Pattern&); }; private: enum { T_EXCLUDE = 1, T_NEGATE = 2, T_TYPEMASK = 3, - T_SRC = 0, T_DST = 4 }; + T_SRC = 0, T_DST = 4 }; enum { D_NAME, D_UNIPROP, D_UNIRANGE }; Vector _patterns; diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.c.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.c --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.c.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.c 2018-02-23 12:47:54.091971753 -0500 @@ -1,6 +1,6 @@ /* kpseinterface.{c,h} -- interface with the kpathsea library * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,9 +21,6 @@ #include #include #include -#ifdef W32TEX -#include -#endif #include "kpseinterface.h" int kpsei_env_sep_char = ENV_SEP; @@ -89,11 +86,3 @@ kpsei_set_debug_flags(unsigned flags) { kpathsea_debug = flags; } - -#ifdef W32TEX -char* -kpsei_var_value(const char *name) -{ - return kpse_var_value(name); -} -#endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.h.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.h --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.h.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/kpseinterface.h 2018-02-23 12:47:54.091971753 -0500 @@ -13,10 +13,6 @@ enum { KPSEI_FMT_WEB2C, KPSEI_FMT_ENCODI char* kpsei_find_file(const char* name, int format); void kpsei_set_debug_flags(unsigned flags); -#ifdef W32TEX -char* kpsei_var_value(const char *name); -#endif - #ifdef __cplusplus } #endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/Makefile.am.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/Makefile.am --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/Makefile.am.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/Makefile.am 2018-02-23 12:47:54.091971753 -0500 @@ -11,6 +11,7 @@ otftotfm_SOURCES = \ metrics.cc metrics.hh \ otftotfm.cc otftotfm.hh \ secondary.cc secondary.hh \ + setting.hh \ uniprop.cc uniprop.hh \ util.cc util.hh EXTRA_otftotfm_SOURCES = kpseinterface.c kpseinterface.h diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.cc 2018-02-23 12:47:54.092971728 -0500 @@ -1,6 +1,6 @@ /* metrics.{cc,hh} -- an encoding during and after OpenType features * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -35,7 +35,7 @@ Metrics::Metrics(const Efont::Charstring Metrics::~Metrics() { for (Char *c = _encoding.begin(); c != _encoding.end(); c++) - delete c->virtual_char; + delete c->virtual_char; } int @@ -54,36 +54,36 @@ Metrics::check() const // 2. all 'ligatures' entries with 'in1 == c' are in '_encoding[c].ligs' // 3. 'virtual_char' SHOW operations point to valid non-virtual chars for (int code = 0; code < _encoding.size(); code++) { - const Char *ch = &_encoding[code]; - assert((ch->virtual_char != 0) == (ch->glyph == VIRTUAL_GLYPH)); - for (const Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) - assert(valid_code(l->in2) && valid_code(l->out)); - for (const Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) - assert(valid_code(k->in2)); - if (const VirtualChar *vc = ch->virtual_char) { - assert(vc->name); - int font_number = 0; - for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) { - assert(s->valid_op()); - if (s->op == Setting::SHOW && font_number == 0) - assert(nonvirtual_code(s->x)); - else if (s->op == Setting::FONT) - font_number = s->x; - } - } - assert(ch->built_in1 < 0 || valid_code(ch->built_in1)); - assert(ch->built_in2 < 0 || valid_code(ch->built_in2)); - assert((ch->built_in1 >= 0) == (ch->built_in2 >= 0)); - assert(ch->base_code < 0 || valid_code(ch->base_code)); - if (valid_code(ch->base_code)) { - const Char *ch2 = &_encoding[ch->base_code]; - assert((!ch->virtual_char && ch->glyph) - || (!ch2->virtual_char && ch2->glyph)); - } - if (ch->flag(Char::CONTEXT_ONLY)) - assert(ch->virtual_char && ch->built_in1 >= 0 && ch->built_in2 >= 0); - if (ch->flag(Char::CONTEXT_ONLY)) - assert(ch->flag(Char::LIVE)); + const Char *ch = &_encoding[code]; + assert((ch->virtual_char != 0) == (ch->glyph == VIRTUAL_GLYPH)); + for (const Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) + assert(valid_code(l->in2) && valid_code(l->out)); + for (const Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) + assert(valid_code(k->in2)); + if (const VirtualChar *vc = ch->virtual_char) { + assert(vc->name); + int font_number = 0; + for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) { + assert(s->valid_op()); + if (s->op == Setting::SHOW && font_number == 0) + assert(nonvirtual_code(s->x)); + else if (s->op == Setting::FONT) + font_number = s->x; + } + } + assert(ch->built_in1 < 0 || valid_code(ch->built_in1)); + assert(ch->built_in2 < 0 || valid_code(ch->built_in2)); + assert((ch->built_in1 >= 0) == (ch->built_in2 >= 0)); + assert(ch->base_code < 0 || valid_code(ch->base_code)); + if (valid_code(ch->base_code)) { + const Char *ch2 = &_encoding[ch->base_code]; + assert((!ch->virtual_char && ch->glyph) + || (!ch2->virtual_char && ch2->glyph)); + } + if (ch->flag(Char::CONTEXT_ONLY)) + assert(ch->virtual_char && ch->built_in1 >= 0 && ch->built_in2 >= 0); + if (ch->flag(Char::CONTEXT_ONLY)) + assert(ch->flag(Char::LIVE)); } } @@ -91,32 +91,32 @@ PermString Metrics::code_name(Code code) const { if (code < 0 || code >= _encoding.size()) - return permprintf("", code); + return permprintf("", code); else { - const Char &ch = _encoding[code]; - if (ch.virtual_char) - return ch.virtual_char->name; - else if (ch.glyph == _boundary_glyph) - return ""; - else if (ch.glyph == _emptyslot_glyph) - return ""; - else if (ch.glyph >= 0 && ch.glyph < _mapped_fonts[0]->nglyphs()) - return _mapped_fonts[0]->glyph_name(ch.glyph); - else - return permprintf("", ch.glyph); + const Char &ch = _encoding[code]; + if (ch.virtual_char) + return ch.virtual_char->name; + else if (ch.glyph == _boundary_glyph) + return ""; + else if (ch.glyph == _emptyslot_glyph) + return ""; + else if (ch.glyph >= 0 && ch.glyph < _mapped_fonts[0]->nglyphs()) + return _mapped_fonts[0]->glyph_name(ch.glyph); + else + return permprintf("", ch.glyph); } } /*****************************************************************************/ -/* encoding */ +/* encoding */ Metrics::Code Metrics::unicode_encoding(uint32_t uni) const { for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) - if (ch->unicode == uni) - return ch - _encoding.begin(); + if (ch->unicode == uni) + return ch - _encoding.begin(); return -1; } @@ -124,15 +124,15 @@ Metrics::Code Metrics::hard_encoding(Glyph g, Code after) const { if (g < 0) - return -1; + return -1; int answer = -1, n = 0; for (int i = _encoding.size() - 1; i >= after; i--) - if (_encoding[i].glyph == g) - answer = i, n++; + if (_encoding[i].glyph == g) + answer = i, n++; if (n < 2 && after == 0) { - if (g >= _emap.size()) - _emap.resize(g + 1, -2); - _emap[g] = answer; + if (g >= _emap.size()) + _emap.resize(g + 1, -2); + _emap[g] = answer; } return answer; } @@ -143,15 +143,15 @@ Metrics::force_encoding(Glyph g, int loo assert(g >= 0); int e = encoding(g, 0); if (e >= 0) - return e; + return e; else { - Char ch; - ch.glyph = g; - ch.base_code = _encoding.size(); - ch.lookup_source = lookup_source; - _encoding.push_back(ch); - assign_emap(g, ch.base_code); - return ch.base_code; + Char ch; + ch.glyph = g; + ch.base_code = _encoding.size(); + ch.lookup_source = lookup_source; + _encoding.push_back(ch); + assign_emap(g, ch.base_code); + return ch.base_code; } } @@ -160,11 +160,11 @@ Metrics::encode(Code code, uint32_t uni, { assert(code >= 0 && g >= 0 && g != VIRTUAL_GLYPH); if (code >= _encoding.size()) - _encoding.resize(code + 1, Char()); + _encoding.resize(code + 1, Char()); _encoding[code].unicode = uni; _encoding[code].glyph = g; if (g > 0) - _encoding[code].base_code = code; + _encoding[code].base_code = code; assert(!_encoding[code].virtual_char); assign_emap(g, code); } @@ -174,20 +174,20 @@ Metrics::encode_virtual(Code code, PermS { assert(code >= 0 && v.size() > 0); if (code >= _encoding.size()) - _encoding.resize(code + 1, Char()); + _encoding.resize(code + 1, Char()); _encoding[code].unicode = uni; _encoding[code].glyph = VIRTUAL_GLYPH; if (base_char) - _encoding[code].flags |= Char::BASE_REP; + _encoding[code].flags |= Char::BASE_REP; assert(!_encoding[code].virtual_char); VirtualChar *vc = _encoding[code].virtual_char = new VirtualChar; vc->name = name; vc->setting = v; int font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) { - assert(s->valid_op() && (s->op != Setting::SHOW || font_number != 0 || nonvirtual_code(s->x))); - if (s->op == Setting::FONT) - font_number = s->x; + assert(s->valid_op() && (s->op != Setting::SHOW || font_number != 0 || nonvirtual_code(s->x))); + if (s->op == Setting::FONT) + font_number = s->x; } } @@ -196,28 +196,28 @@ Metrics::apply_base_encoding(const Strin { int font_number = -1; for (Char *c = _encoding.begin(); c != _encoding.end(); c++) - if (c->glyph > 0 && !c->virtual_char && c->glyph < mapping.size() - && mapping[c->glyph] >= 0) { - if (font_number < 0) - font_number = add_mapped_font(mapped_font(0), font_name); - VirtualChar *vc = c->virtual_char = new VirtualChar; - vc->name = dvipsenc.encoding(mapping[c->glyph]); - vc->setting.push_back(Setting(Setting::FONT, font_number)); - vc->setting.push_back(Setting(Setting::SHOW, mapping[c->glyph], c->glyph)); - c->glyph = VIRTUAL_GLYPH; - c->base_code = -1; - c->flags = (c->flags & ~Char::BASE_LIVE) | Char::BASE_REP; - } + if (c->glyph > 0 && !c->virtual_char && c->glyph < mapping.size() + && mapping[c->glyph] >= 0) { + if (font_number < 0) + font_number = add_mapped_font(mapped_font(0), font_name); + VirtualChar *vc = c->virtual_char = new VirtualChar; + vc->name = dvipsenc.encoding(mapping[c->glyph]); + vc->setting.push_back(Setting(Setting::FONT, font_number)); + vc->setting.push_back(Setting(Setting::SHOW, mapping[c->glyph], c->glyph)); + c->glyph = VIRTUAL_GLYPH; + c->base_code = -1; + c->flags = (c->flags & ~Char::BASE_LIVE) | Char::BASE_REP; + } } void Metrics::add_altselector_code(Code code, int altselector_type) { for (Kern *k = _altselectors.begin(); k != _altselectors.end(); k++) - if (k->in2 == code) { - k->kern = altselector_type; - return; - } + if (k->in2 == code) { + k->kern = altselector_type; + return; + } _altselectors.push_back(Kern(code, altselector_type)); } @@ -227,16 +227,16 @@ Metrics::base_glyphs(Vector &v, i bool any = false; v.assign(_encoding.size(), 0); for (const Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) - if (ch->base_code >= 0 && ch->base_code < size) { - v[ch->base_code] = ch->glyph; - any = true; - } + if (ch->base_code >= 0 && ch->base_code < size) { + v[ch->base_code] = ch->glyph; + any = true; + } return any; } /*****************************************************************************/ -/* Char methods */ +/* Char methods */ void Metrics::Char::clear() @@ -260,7 +260,7 @@ Metrics::Char::swap(Char &c) std::swap(glyph, c.glyph); // NB: only a partial switch of base_code!! if (base_code < 0) - base_code = c.base_code; + base_code = c.base_code; c.base_code = -1; std::swap(unicode, c.unicode); ligatures.swap(c.ligatures); @@ -277,7 +277,7 @@ Metrics::Char::swap(Char &c) /*****************************************************************************/ -/* manipulating ligature lists */ +/* manipulating ligature lists */ Metrics::Ligature * Metrics::ligature_obj(Code code1, Code code2) @@ -285,8 +285,8 @@ Metrics::ligature_obj(Code code1, Code c assert(valid_code(code1) && valid_code(code2)); Char &ch = _encoding[code1]; for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) - if (l->in2 == code2) - return l; + if (l->in2 == code2) + return l; return 0; } @@ -307,39 +307,39 @@ void Metrics::add_ligature(Code in1, Code in2, Code out) { if (Ligature *l = ligature_obj(in1, in2)) { - Char &ch = _encoding[l->out]; - if (ch.flags & Char::BUILT) { - // move old ligatures to point to the true ligature - for (Ligature *ll = ch.ligatures.begin(); ll != ch.ligatures.end(); ll++) - add_ligature(out, ll->in2, ll->out); - repoint_ligature(in1, l, out); - } + Char &ch = _encoding[l->out]; + if (ch.flags & Char::BUILT) { + // move old ligatures to point to the true ligature + for (Ligature *ll = ch.ligatures.begin(); ll != ch.ligatures.end(); ll++) + add_ligature(out, ll->in2, ll->out); + repoint_ligature(in1, l, out); + } } else - new_ligature(in1, in2, out); + new_ligature(in1, in2, out); } Metrics::Code Metrics::pair_code(Code in1, Code in2, int lookup_source) { if (const Ligature *l = ligature_obj(in1, in2)) { - if (lookup_source < 0) - _encoding[l->out].flags &= ~Char::INTERMEDIATE; - return l->out; + if (lookup_source < 0) + _encoding[l->out].flags &= ~Char::INTERMEDIATE; + return l->out; } else { - Char ch; - ch.glyph = VIRTUAL_GLYPH; - ch.flags = Char::BUILT | (lookup_source >= 0 ? Char::INTERMEDIATE : 0); - VirtualChar *vc = ch.virtual_char = new VirtualChar; - vc->name = permprintf("%s__%s", code_str(in1), code_str(in2)); - setting(in1, vc->setting, SET_INTERMEDIATE); - vc->setting.push_back(Setting(Setting::KERN)); - setting(in2, vc->setting, SET_INTERMEDIATE); - ch.built_in1 = in1; - ch.built_in2 = in2; - ch.lookup_source = lookup_source; - _encoding.push_back(ch); - new_ligature(in1, in2, _encoding.size() - 1); - return _encoding.size() - 1; + Char ch; + ch.glyph = VIRTUAL_GLYPH; + ch.flags = Char::BUILT | (lookup_source >= 0 ? Char::INTERMEDIATE : 0); + VirtualChar *vc = ch.virtual_char = new VirtualChar; + vc->name = permprintf("%s__%s", code_str(in1), code_str(in2)); + setting(in1, vc->setting, SET_INTERMEDIATE); + vc->setting.push_back(Setting(Setting::KERN)); + setting(in2, vc->setting, SET_INTERMEDIATE); + ch.built_in1 = in1; + ch.built_in2 = in2; + ch.lookup_source = lookup_source; + _encoding.push_back(ch); + new_ligature(in1, in2, _encoding.size() - 1); + return _encoding.size() - 1; } } @@ -347,22 +347,22 @@ void Metrics::remove_ligatures(Code in1, Code in2) { if (in1 == CODE_ALL) { - for (in1 = 0; in1 < _encoding.size(); in1++) - remove_ligatures(in1, in2); + for (in1 = 0; in1 < _encoding.size(); in1++) + remove_ligatures(in1, in2); } else { - Char &ch = _encoding[in1]; - if (in2 == CODE_ALL) - ch.ligatures.clear(); - else if (Ligature *l = ligature_obj(in1, in2)) { - *l = ch.ligatures.back(); - ch.ligatures.pop_back(); - } + Char &ch = _encoding[in1]; + if (in2 == CODE_ALL) + ch.ligatures.clear(); + else if (Ligature *l = ligature_obj(in1, in2)) { + *l = ch.ligatures.back(); + ch.ligatures.pop_back(); + } } } /*****************************************************************************/ -/* manipulating kern lists */ +/* manipulating kern lists */ Metrics::Kern * Metrics::kern_obj(Code in1, Code in2) @@ -370,8 +370,8 @@ Metrics::kern_obj(Code in1, Code in2) assert(valid_code(in1) && valid_code(in2)); Char &ch = _encoding[in1]; for (Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) - if (k->in2 == in2) - return k; + if (k->in2 == in2) + return k; return 0; } @@ -381,8 +381,8 @@ Metrics::kern(Code in1, Code in2) const assert(valid_code(in1) && valid_code(in2)); const Char &ch = _encoding[in1]; for (const Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) - if (k->in2 == in2) - return k->kern; + if (k->in2 == in2) + return k->kern; return 0; } @@ -390,30 +390,30 @@ void Metrics::add_kern(Code in1, Code in2, int kern) { if (Kern *k = kern_obj(in1, in2)) - k->kern += kern; + k->kern += kern; else - _encoding[in1].kerns.push_back(Kern(in2, kern)); + _encoding[in1].kerns.push_back(Kern(in2, kern)); } void Metrics::set_kern(Code in1, Code in2, int kern) { if (in1 == CODE_ALL) { - for (in1 = 0; in1 < _encoding.size(); in1++) - set_kern(in1, in2, kern); + for (in1 = 0; in1 < _encoding.size(); in1++) + set_kern(in1, in2, kern); } else { - Char &ch = _encoding[in1]; - if (in2 == CODE_ALL) { - assert(kern == 0); - ch.kerns.clear(); - } else if (Kern *k = kern_obj(in1, in2)) { - if (kern == 0) { - *k = ch.kerns.back(); - ch.kerns.pop_back(); - } else - k->kern = kern; - } else if (kern != 0) - ch.kerns.push_back(Kern(in2, kern)); + Char &ch = _encoding[in1]; + if (in2 == CODE_ALL) { + assert(kern == 0); + ch.kerns.clear(); + } else if (Kern *k = kern_obj(in1, in2)) { + if (kern == 0) { + *k = ch.kerns.back(); + ch.kerns.pop_back(); + } else + k->kern = kern; + } else if (kern != 0) + ch.kerns.push_back(Kern(in2, kern)); } } @@ -422,38 +422,38 @@ Metrics::reencode_right_ligkern(Code old { int nchanges = 0; for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) { - for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) - if (l->in2 == old_in2) { - if (new_in2 >= 0) - l->in2 = new_in2; - else { - *l = ch->ligatures.back(); - ch->ligatures.pop_back(); - l--; - } - nchanges++; - } - for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) - if (k->in2 == old_in2) { - if (new_in2 >= 0) - k->in2 = new_in2; - else { - *k = ch->kerns.back(); - ch->kerns.pop_back(); - k--; - } - nchanges++; - } - // XXX? - if (ch->context_setting(-1, old_in2) && new_in2 >= 0 && ch->built_in1 >= 0) - ch->built_in2 = new_in2; + for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) + if (l->in2 == old_in2) { + if (new_in2 >= 0) + l->in2 = new_in2; + else { + *l = ch->ligatures.back(); + ch->ligatures.pop_back(); + l--; + } + nchanges++; + } + for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) + if (k->in2 == old_in2) { + if (new_in2 >= 0) + k->in2 = new_in2; + else { + *k = ch->kerns.back(); + ch->kerns.pop_back(); + k--; + } + nchanges++; + } + // XXX? + if (ch->context_setting(-1, old_in2) && new_in2 >= 0 && ch->built_in1 >= 0) + ch->built_in2 = new_in2; } return nchanges; } /*****************************************************************************/ -/* positioning */ +/* positioning */ void Metrics::add_single_positioning(Code c, int pdx, int pdy, int adx) @@ -467,7 +467,7 @@ Metrics::add_single_positioning(Code c, /*****************************************************************************/ -/* changed_context structure */ +/* changed_context structure */ class Metrics::ChangedContext { public: ChangedContext(int ncodes); @@ -498,35 +498,35 @@ Metrics::ChangedContext::ChangedContext( Metrics::ChangedContext::~ChangedContext() { for (Vector **v = _v.begin(); v != _v.end(); v++) - if (*v != &_all_sentinel) - delete *v; + if (*v != &_all_sentinel) + delete *v; } inline void Metrics::ChangedContext::ensure_all(Code c) const { if (c >= 0 && (c >> 5) >= _all_sentinel.size()) - _all_sentinel.resize((c >> 5) + 1, 0xFFFFFFFFU); + _all_sentinel.resize((c >> 5) + 1, 0xFFFFFFFFU); } inline bool Metrics::ChangedContext::bit(const Vector &v, Code c) { if (c < 0 || (c >> 5) >= v.size()) - return false; + return false; else - return (v[c >> 5] & (1 << (c & 0x1F))) != 0; + return (v[c >> 5] & (1 << (c & 0x1F))) != 0; } bool Metrics::ChangedContext::allowed(Code c, bool left_context) const { if (c < 0) - return false; + return false; else if (c >= _v.size()) - return left_context; + return left_context; else - return (_v[c] != &_all_sentinel); + return (_v[c] != &_all_sentinel); } bool @@ -534,11 +534,11 @@ Metrics::ChangedContext::pair_allowed(Co { ensure_all(c2); if (c1 < 0 || c2 < 0) - return false; + return false; else if (c1 >= _v.size() || c2 >= _v.size() || !_v[c1]) - return true; + return true; else - return !bit(*_v[c1], c2); + return !bit(*_v[c1], c2); } bool @@ -552,10 +552,10 @@ Metrics::ChangedContext::disallow(Code c { assert(c >= 0); if (c >= _v.size()) - _v.resize(c + 1, 0); + _v.resize(c + 1, 0); if (_v[c] != &_all_sentinel) { - delete _v[c]; - _v[c] = &_all_sentinel; + delete _v[c]; + _v[c] = &_all_sentinel; } } @@ -564,60 +564,60 @@ Metrics::ChangedContext::disallow_pair(C { assert(c1 >= 0 && c2 >= 0); if (c1 >= _v.size()) - _v.resize(c1 + 1, 0); + _v.resize(c1 + 1, 0); if (!_v[c1]) - _v[c1] = new Vector; + _v[c1] = new Vector; if (_v[c1] != &_all_sentinel) { - if ((c2 >> 5) >= _v[c1]->size()) - _v[c1]->resize((c2 >> 5) + 1, 0); - (*_v[c1])[c2 >> 5] |= 1 << (c2 & 0x1F); + if ((c2 >> 5) >= _v[c1]->size()) + _v[c1]->resize((c2 >> 5) + 1, 0); + (*_v[c1])[c2 >> 5] |= 1 << (c2 & 0x1F); } } /*****************************************************************************/ -/* applying GSUB substitutions */ +/* applying GSUB substitutions */ void Metrics::apply_single(Code cin, const Substitution *s, int lookup, - ChangedContext &ctx, const GlyphFilter &glyph_filter, - const Vector &glyph_names) + ChangedContext &ctx, const GlyphFilter &glyph_filter, + const Vector &glyph_names) { // check if encoded if (!ctx.allowed(cin, false)) - /* not encoded before this substitution began, or completely changed; - ingore */ - return; + /* not encoded before this substitution began, or completely changed; + ingore */ + return; // check if substitution of this code allowed if (!glyph_filter.allow_substitution(s->in_glyph(), glyph_names, unicode(cin))) - return; + return; // look for an allowed alternate Glyph out = -1; for (int i = 0; out < 0 && i < s->out_nglyphs(); i++) - if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, unicode(cin))) - out = s->out_glyph(i); - if (out < 0) // no allowed alternate - return; + if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, unicode(cin))) + out = s->out_glyph(i); + if (out < 0) // no allowed alternate + return; // apply substitution if (ctx.virgin(cin)) { - // no one has changed this glyph yet, change it unilaterally - assign_emap(s->in_glyph(), -2); - assign_emap(out, cin); - assert(!_encoding[cin].virtual_char); - _encoding[cin].glyph = out; + // no one has changed this glyph yet, change it unilaterally + assign_emap(s->in_glyph(), -2); + assign_emap(out, cin); + assert(!_encoding[cin].virtual_char); + _encoding[cin].glyph = out; } else { - // some contextual substitutions have changed this glyph, add - // contextual substitutions for the remaining possibilities - Code cout = force_encoding(out, lookup); - for (Code right = 0; right < _encoding.size(); right++) - if (_encoding[right].visible() && !_encoding[right].flag(Char::BUILT) && ctx.pair_allowed(cin, right)) { - Code pair = pair_code(cout, right, lookup); - _encoding[cout].flags &= ~Char::INTERMEDIATE; - add_ligature(cin, right, pair); - } + // some contextual substitutions have changed this glyph, add + // contextual substitutions for the remaining possibilities + Code cout = force_encoding(out, lookup); + for (Code right = 0; right < _encoding.size(); right++) + if (_encoding[right].visible() && !_encoding[right].flag(Char::BUILT) && ctx.pair_allowed(cin, right)) { + Code pair = pair_code(cout, right, lookup); + _encoding[cout].flags &= ~Char::INTERMEDIATE; + add_ligature(cin, right, pair); + } } // no more substitutions for cin @@ -630,7 +630,7 @@ Metrics::apply_ligature(const Vectorall_out_glyphs(out); int cout = -1; for (Glyph *outp = out.begin(); outp < out.end(); outp++) { - *outp = force_encoding(*outp, lookup); - cout = (cout < 0 ? *outp : pair_code(cout, *outp, lookup)); + *outp = force_encoding(*outp, lookup); + cout = (cout < 0 ? *outp : pair_code(cout, *outp, lookup)); } _encoding[cout].flags &= ~Char::INTERMEDIATE; // check for replacing a fake ligature int old_out = -1; if (Ligature *l = ligature_obj(cin1, cin2)) { - if (l->out == cout) // already created this same ligature - return; - if (_encoding[l->out].flags & Char::BUILT) - old_out = l->out; + if (l->out == cout) // already created this same ligature + return; + if (_encoding[l->out].flags & Char::BUILT) + old_out = l->out; } // make the final ligature @@ -659,35 +659,39 @@ Metrics::apply_ligature(const Vector= 0) - for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) - for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) - if (l->out == old_out) - repoint_ligature(ch - _encoding.begin(), l, cout); + for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) + for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) + if (l->out == old_out) + repoint_ligature(ch - _encoding.begin(), l, cout); } void Metrics::apply_simple_context_ligature(const Vector &codes, - const Substitution *s, int lookup, ChangedContext &ctx) + const Substitution *s, int lookup, ChangedContext &ctx, + const GlyphFilter &glyph_filter, + const Vector& glyph_names) { int nleft = s->left_nglyphs(), nin = s->in_nglyphs(); assert(codes.size() >= 2); // check if context allows substitutions - for (const Code *inp = codes.begin(); inp < codes.end(); ++inp) - if (!ctx.allowed(*inp, inp - codes.begin() < nleft)) - return; + for (int i = 0; i < codes.size(); ++i) { + if (!ctx.allowed(codes[i], i < nleft) + || !glyph_filter.allow_substitution(s->in_glyph(i), glyph_names, unicode(codes[i]))) + return; + } // check if any part of the combination has already changed int ncheck = nleft + (nin > 2 ? 2 : nin); if (ncheck == codes.size()) - --ncheck; + --ncheck; for (const Code *inp = codes.begin(); inp < codes.begin() + ncheck; ++inp) - if (!ctx.pair_allowed(inp[0], inp[1])) - return; + if (!ctx.pair_allowed(inp[0], inp[1])) + return; // mark this combination as changed if appropriate if (codes.size() == 2 && nin == 1) - ctx.disallow_pair(codes[0], codes[1]); + ctx.disallow_pair(codes[0], codes[1]); // actually apply ligature apply_ligature(codes, s, lookup); @@ -697,18 +701,18 @@ bool Metrics::next_encoding(Vector &codes, const Vector &glyphs) const { if (!codes.size()) { - codes.assign(glyphs.size(), 0); - for (int i = 0; i < glyphs.size(); ++i) - if ((codes[i] = encoding(glyphs[i], 0)) < 0) - return false; - return true; + codes.assign(glyphs.size(), 0); + for (int i = 0; i < glyphs.size(); ++i) + if ((codes[i] = encoding(glyphs[i], 0)) < 0) + return false; + return true; } else { - for (int i = 0; i < glyphs.size(); ++i) - if ((codes[i] = encoding(glyphs[i], codes[i] + 1)) >= 0) - return true; - else - codes[i] = encoding(glyphs[i], 0); - return false; + for (int i = 0; i < glyphs.size(); ++i) + if ((codes[i] = encoding(glyphs[i], codes[i] + 1)) >= 0) + return true; + else + codes[i] = encoding(glyphs[i], 0); + return false; } } @@ -724,20 +728,20 @@ Metrics::apply(const Vectoris_single() || s->is_alternate(); - bool is_apply_single = is_single && allow_single; - bool is_apply_simple_context_ligature = !is_single && !s->is_multiple() && s->is_simple_context(); - - if (is_apply_single || is_apply_simple_context_ligature) { - s->all_in_glyphs(glyphs); - for (codes.clear(); next_encoding(codes, glyphs); ) { - if (is_apply_single) - apply_single(codes[0], s, lookup, ctx, glyph_filter, glyph_names); - else - apply_simple_context_ligature(codes, s, lookup, ctx); - } - } else - failures++; + bool is_single = s->is_single() || s->is_alternate(); + bool is_apply_single = is_single && allow_single; + bool is_apply_simple_context_ligature = !is_single && !s->is_multiple() && s->is_simple_context(); + + if (is_apply_single || is_apply_simple_context_ligature) { + s->all_in_glyphs(glyphs); + for (codes.clear(); next_encoding(codes, glyphs); ) { + if (is_apply_single) + apply_single(codes[0], s, lookup, ctx, glyph_filter, glyph_names); + else + apply_simple_context_ligature(codes, s, lookup, ctx, glyph_filter, glyph_names); + } + } else + failures++; } return sv.size() - failures; @@ -745,42 +749,42 @@ Metrics::apply(const Vector &glyph_names) + const GlyphFilter &glyph_filter, + const Vector &glyph_names) { for (const Kern *as = _altselectors.begin(); as != _altselectors.end(); as++) - if (as->kern == 0) { - Code last = cin; - uint32_t u = unicode(cin); - for (int i = 0; i < s->out_nglyphs(); i++) - if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, u)) { - Code out = force_encoding(s->out_glyph(i), lookup); - add_ligature(last, as->in2, out); - last = out; - } - } else if (as->kern <= s->out_nglyphs()) { - Code out = force_encoding(s->out_glyph(as->kern - 1), lookup); - add_ligature(cin, as->in2, out); - } + if (as->kern == 0) { + Code last = cin; + uint32_t u = unicode(cin); + for (int i = 0; i < s->out_nglyphs(); i++) + if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, u)) { + Code out = force_encoding(s->out_glyph(i), lookup); + add_ligature(last, as->in2, out); + last = out; + } + } else if (as->kern <= s->out_nglyphs()) { + Code out = force_encoding(s->out_glyph(as->kern - 1), lookup); + add_ligature(cin, as->in2, out); + } } void Metrics::apply_alternates_ligature(const Vector &codes, - const Substitution *s, int lookup, - const GlyphFilter &glyph_filter, - const Vector &glyph_names) + const Substitution *s, int lookup, + const GlyphFilter &glyph_filter, + const Vector &glyph_names) { // check whether the output character is allowed if (!glyph_filter.allow_alternate(s->out_glyph(), glyph_names, 0)) - return; + return; // find alternate selector and apply ligature if appropriate for (const Kern *as = _altselectors.begin(); as != _altselectors.end(); as++) - if (as->kern == 0) { - Vector lig(codes); - lig.insert(lig.begin() + 1, as->in2); - apply_ligature(lig, s, lookup); - } + if (as->kern == 0) { + Vector lig(codes); + lig.insert(lig.begin() + 1, as->in2); + apply_ligature(lig, s, lookup); + } } void @@ -790,36 +794,36 @@ Metrics::apply_alternates(const Vector codes; for (const Substitution *s = sv.begin(); s != sv.end(); s++) { - bool is_single = s->is_single() || s->is_alternate(); - if (is_single || s->is_ligature()) { - s->all_in_glyphs(glyphs); - for (codes.clear(); next_encoding(codes, glyphs); ) { - if (is_single) - apply_alternates_single(codes[0], s, lookup, glyph_filter, glyph_names); - else - apply_alternates_ligature(codes, s, lookup, glyph_filter, glyph_names); - } - } + bool is_single = s->is_single() || s->is_alternate(); + if (is_single || s->is_ligature()) { + s->all_in_glyphs(glyphs); + for (codes.clear(); next_encoding(codes, glyphs); ) { + if (is_single) + apply_alternates_single(codes[0], s, lookup, glyph_filter, glyph_names); + else + apply_alternates_ligature(codes, s, lookup, glyph_filter, glyph_names); + } + } } } /*****************************************************************************/ -/* applying GPOS positionings */ +/* applying GPOS positionings */ -static bool // returns old value +static bool // returns old value assign_bitvec(int*& bitvec, int e, int n) { if (e >= 0 && e < n) { - if (!bitvec) { - bitvec = new int[((n - 1) >> 5) + 1]; - memset(bitvec, 0, sizeof(int) * (((n - 1) >> 5) + 1)); - } - bool result = (bitvec[e >> 5] & (1 << (e & 0x1F))) != 0; - bitvec[e >> 5] |= (1 << (e & 0x1F)); - return result; + if (!bitvec) { + bitvec = new int[((n - 1) >> 5) + 1]; + memset(bitvec, 0, sizeof(int) * (((n - 1) >> 5) + 1)); + } + bool result = (bitvec[e >> 5] & (1 << (e & 0x1F))) != 0; + bitvec[e >> 5] |= (1 << (e & 0x1F)); + return result; } else - return false; + return false; } int @@ -834,33 +838,33 @@ Metrics::apply(const Vector // loop over substitutions int success = 0; for (const Positioning *p = pv.begin(); p != pv.end(); p++) { - bool is_single = p->is_single(); - if (is_single || p->is_pairkern()) { - p->all_in_glyphs(glyphs); - for (codes.clear(); next_encoding(codes, glyphs); ) - if (is_single) { - if (!assign_bitvec(single_changed, codes[0], _encoding.size())) { - _encoding[codes[0]].pdx += p->left().pdx; - _encoding[codes[0]].pdy += p->left().pdy; - _encoding[codes[0]].adx += p->left().adx; - } - } else { - if (!assign_bitvec(pair_changed[codes[0]], codes[1], _encoding.size())) - add_kern(codes[0], codes[1], p->left().adx); - } - success++; - } + bool is_single = p->is_single(); + if (is_single || p->is_pairkern()) { + p->all_in_glyphs(glyphs); + for (codes.clear(); next_encoding(codes, glyphs); ) + if (is_single) { + if (!assign_bitvec(single_changed, codes[0], _encoding.size())) { + _encoding[codes[0]].pdx += p->left().pdx; + _encoding[codes[0]].pdy += p->left().pdy; + _encoding[codes[0]].adx += p->left().adx; + } + } else { + if (!assign_bitvec(pair_changed[codes[0]], codes[1], _encoding.size())) + add_kern(codes[0], codes[1], p->left().adx); + } + success++; + } } delete[] single_changed; for (int i = 0; i < pair_changed.size(); i++) - delete[] pair_changed[i]; + delete[] pair_changed[i]; return success; } /*****************************************************************************/ -/* liveness marking, Ligature3s */ +/* liveness marking, Ligature3s */ String Metrics::Ligature3::unparse(const Metrics& m) const { StringAccum sa; @@ -874,11 +878,11 @@ operator<(const Metrics::Ligature3 &l1, { // topological < : is l1's output one of l2's inputs? if (l1.out == l2.in1 || l1.out == l2.in2) - return true; + return true; else - return l1.in1 < l2.in1 - || (l1.in1 == l2.in1 && (l1.in2 < l2.in2 - || (l1.in2 == l2.in2 && l1.out < l2.out))); + return l1.in1 < l2.in1 + || (l1.in1 == l2.in1 && (l1.in2 < l2.in2 + || (l1.in2 == l2.in2 && l1.out < l2.out))); } void @@ -887,8 +891,8 @@ Metrics::all_ligatures(Vector /* Develop a topologically-sorted ligature list. */ all_ligs.clear(); for (Code code = 0; code < _encoding.size(); code++) - for (const Ligature *l = _encoding[code].ligatures.begin(); l != _encoding[code].ligatures.end(); l++) - all_ligs.push_back(Ligature3(code, l->in2, l->out)); + for (const Ligature *l = _encoding[code].ligatures.begin(); l != _encoding[code].ligatures.end(); l++) + all_ligs.push_back(Ligature3(code, l->in2, l->out)); std::sort(all_ligs.begin(), all_ligs.end()); } @@ -901,86 +905,86 @@ Metrics::mark_liveness(int size, const V // make sure we have ligatures Vector my_ligs; if (!all_ligs) { - all_ligatures(my_ligs); - all_ligs = &my_ligs; + all_ligatures(my_ligs); + all_ligs = &my_ligs; } /* Characters below 'size' are in both virtual and base encodings. */ for (Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) - if (ch->visible()) - ch->flags |= Char::LIVE | (ch->virtual_char ? 0 : Char::BASE_LIVE); + if (ch->visible()) + ch->flags |= Char::LIVE | (ch->virtual_char ? 0 : Char::BASE_LIVE); /* Characters reachable from live chars by live ligatures are live. */ redo_live_reachable: for (const Ligature3 *l = all_ligs->begin(); l != all_ligs->end(); l++) - if (_encoding[l->in1].flag(Char::LIVE) && _encoding[l->in2].flag(Char::LIVE)) { - Char &ch = _encoding[l->out]; - if (!ch.flag(Char::LIVE)) - ch.flags |= Char::LIVE | Char::CONTEXT_ONLY | (ch.virtual_char ? 0 : Char::BASE_LIVE); - if (ch.flag(Char::CONTEXT_ONLY) && !ch.context_setting(l->in1, l->in2)) - ch.flags &= ~Char::CONTEXT_ONLY; - } + if (_encoding[l->in1].flag(Char::LIVE) && _encoding[l->in2].flag(Char::LIVE)) { + Char &ch = _encoding[l->out]; + if (!ch.flag(Char::LIVE)) + ch.flags |= Char::LIVE | Char::CONTEXT_ONLY | (ch.virtual_char ? 0 : Char::BASE_LIVE); + if (ch.flag(Char::CONTEXT_ONLY) && !ch.context_setting(l->in1, l->in2)) + ch.flags &= ~Char::CONTEXT_ONLY; + } /* Characters reachable from context-only ligatures are live. */ changed = false; for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) - if (ch->flag(Char::CONTEXT_ONLY)) { - Char &ch1 = _encoding[ch->built_in1]; - Char &ch2 = _encoding[ch->built_in2]; - if (!ch1.flag(Char::LIVE) || !ch2.flag(Char::LIVE)) { - ch1.flags |= Char::LIVE; - ch2.flags |= Char::LIVE; - changed = true; - } - } + if (ch->flag(Char::CONTEXT_ONLY)) { + Char &ch1 = _encoding[ch->built_in1]; + Char &ch2 = _encoding[ch->built_in2]; + if (!ch1.flag(Char::LIVE) || !ch2.flag(Char::LIVE)) { + ch1.flags |= Char::LIVE; + ch2.flags |= Char::LIVE; + changed = true; + } + } if (changed) - goto redo_live_reachable; + goto redo_live_reachable; /* Characters reachable from live settings are base-live. */ for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) - if (ch->flag(Char::LIVE)) - if (VirtualChar *vc = ch->virtual_char) { - int font_number = 0; - for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) - if (s->op == Setting::SHOW && font_number == 0 - && _encoding[s->x].base_code >= 0) - _encoding[s->x].flags |= Char::BASE_LIVE; - else if (s->op == Setting::FONT) - font_number = s->x; - } + if (ch->flag(Char::LIVE)) + if (VirtualChar *vc = ch->virtual_char) { + int font_number = 0; + for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + if (s->op == Setting::SHOW && font_number == 0 + && _encoding[s->x].base_code >= 0) + _encoding[s->x].flags |= Char::BASE_LIVE; + else if (s->op == Setting::FONT) + font_number = s->x; + } } void Metrics::reencode(const Vector &reencoding) { for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) { - for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) { - l->in2 = reencoding[l->in2]; - l->out = reencoding[l->out]; - } - for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) - k->in2 = reencoding[k->in2]; - if (VirtualChar *vc = ch->virtual_char) { - int font_number = 0; - for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) - if (s->op == Setting::SHOW && font_number == 0) - s->x = reencoding[s->x]; - else if (s->op == Setting::FONT) - font_number = s->x; - } - if (ch->built_in1 >= 0) { - ch->built_in1 = reencoding[ch->built_in1]; - ch->built_in2 = reencoding[ch->built_in2]; - } - if (ch->base_code >= 0) - ch->base_code = reencoding[ch->base_code]; + for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) { + l->in2 = reencoding[l->in2]; + l->out = reencoding[l->out]; + } + for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) + k->in2 = reencoding[k->in2]; + if (VirtualChar *vc = ch->virtual_char) { + int font_number = 0; + for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + if (s->op == Setting::SHOW && font_number == 0) + s->x = reencoding[s->x]; + else if (s->op == Setting::FONT) + font_number = s->x; + } + if (ch->built_in1 >= 0) { + ch->built_in1 = reencoding[ch->built_in1]; + ch->built_in2 = reencoding[ch->built_in2]; + } + if (ch->base_code >= 0) + ch->base_code = reencoding[ch->base_code]; } _emap.clear(); } /*****************************************************************************/ -/* shrinking the encoding */ +/* shrinking the encoding */ bool Metrics::Char::context_setting(Code in1, Code in2) const @@ -988,9 +992,9 @@ Metrics::Char::context_setting(Code in1, // return true iff this character could represent the context setting of // 'in1' and 'in2' if (!virtual_char || ligatures.size()) - return false; + return false; else - return (in1 == built_in1 || in2 == built_in2); + return (in1 == built_in1 || in2 == built_in2); } void @@ -1001,56 +1005,56 @@ Metrics::cut_encoding(int size) /* Change "emptyslot"s to ".notdef"s. */ for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) - if (ch->glyph == emptyslot_glyph()) { - ch->glyph = 0; - ch->base_code = -1; - // 21.Feb.2007: Character isn't live any more. - ch->flags &= ~(Char::BASE_LIVE | Char::LIVE); - } + if (ch->glyph == emptyslot_glyph()) { + ch->glyph = 0; + ch->base_code = -1; + // 21.Feb.2007: Character isn't live any more. + ch->flags &= ~(Char::BASE_LIVE | Char::LIVE); + } /* Maybe we don't need to do anything else. */ if (_encoding.size() <= size) { - _encoding.resize(size, Char()); - return; + _encoding.resize(size, Char()); + return; } /* Need liveness markings. */ if (!_liveness_marked) - mark_liveness(size); + mark_liveness(size); /* Characters below 'size' are 'good'. Characters above 'size' are not 'good'. */ Vector good(_encoding.size(), 1); for (Code c = size; c < _encoding.size(); c++) - good[c] = 0; + good[c] = 0; /* Characters encoded via base_code are 'good', though. */ for (Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) - if (ch->base_code >= size) - good[ch->base_code] = 1; + if (ch->base_code >= size) + good[ch->base_code] = 1; /* Some fake characters might point beyond 'size'; remove them too. No need for a multipass algorithm since virtual chars never point to virtual chars. */ for (Code c = 0; c < _encoding.size(); c++) { - if (VirtualChar *vc = _encoding[c].virtual_char) { - int font_number = 0; - for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) - if (s->op == Setting::SHOW && font_number == 0 && !good[s->x]) { - _encoding[c].clear(); - goto bad_virtual_char; - } else if (s->op == Setting::FONT) - font_number = s->x; - } - if (c < size) - good[c] = 1; + if (VirtualChar *vc = _encoding[c].virtual_char) { + int font_number = 0; + for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + if (s->op == Setting::SHOW && font_number == 0 && !good[s->x]) { + _encoding[c].clear(); + goto bad_virtual_char; + } else if (s->op == Setting::FONT) + font_number = s->x; + } + if (c < size) + good[c] = 1; bad_virtual_char: ; } /* Certainly none of the later ligatures or kerns will be meaningful. */ for (Code c = size; c < _encoding.size(); c++) { - _encoding[c].ligatures.clear(); - _encoding[c].kerns.clear(); + _encoding[c].ligatures.clear(); + _encoding[c].kerns.clear(); } /* Remove ligatures and kerns that point beyond 'size', except for valid @@ -1059,20 +1063,20 @@ Metrics::cut_encoding(int size) /* 30.May.2005 -- Kerns might point involve a too-high character; kill them. */ for (Code c = 0; c < size; c++) { - Char &ch = _encoding[c]; - for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) - if (!good[l->in2] || l->in2 >= size - || (!good[l->out] && !_encoding[l->out].context_setting(c, l->in2))) { - *l = ch.ligatures.back(); - ch.ligatures.pop_back(); - l--; - } - for (Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) - if (!good[k->in2] || k->in2 >= size) { - *k = ch.kerns.back(); - ch.kerns.pop_back(); - k--; - } + Char &ch = _encoding[c]; + for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) + if (!good[l->in2] || l->in2 >= size + || (!good[l->out] && !_encoding[l->out].context_setting(c, l->in2))) { + *l = ch.ligatures.back(); + ch.ligatures.pop_back(); + l--; + } + for (Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) + if (!good[k->in2] || k->in2 >= size) { + *k = ch.kerns.back(); + ch.kerns.pop_back(); + k--; + } } /* We are done! */ @@ -1097,19 +1101,19 @@ static int unicode_score(uint32_t u) { if (u == 0) - return NOCHAR_SCORE; + return NOCHAR_SCORE; else if (u >= 'a' && u <= 'z') - return BASIC_LATIN_LOWER_SCORE; + return BASIC_LATIN_LOWER_SCORE; else if (u >= 'A' && u <= 'Z') - return BASIC_LATIN_UPPER_SCORE; + return BASIC_LATIN_UPPER_SCORE; else if (u < 0x0080) - return BASIC_LATIN_OTHER_SCORE; + return BASIC_LATIN_OTHER_SCORE; else if (u < 0x0100) - return LATIN1_SUPPLEMENT_SCORE; + return LATIN1_SUPPLEMENT_SCORE; else if (u < 0x8000) - return LOW_16_SCORE; + return LOW_16_SCORE; else - return OTHER_SCORE; + return OTHER_SCORE; } struct Slot { @@ -1145,8 +1149,8 @@ Metrics::shrink_encoding(int size, const /* Maybe we don't need to do anything. */ if (_encoding.size() <= size) { - cut_encoding(size); - return; + cut_encoding(size); + return; } /* Need a list of all ligatures.. */ @@ -1155,7 +1159,7 @@ Metrics::shrink_encoding(int size, const /* Need liveness markings. */ if (!_liveness_marked) - mark_liveness(size, &all_ligs); + mark_liveness(size, &all_ligs); /* Score characters by importance. Importance relates first to Unicode values, and then recursively to the importances of characters that form @@ -1164,8 +1168,8 @@ Metrics::shrink_encoding(int size, const /* Create an initial set of scores, based on Unicode values. */ Vector scores(_encoding.size(), NOCHAR_SCORE); for (int i = 0; i < _encoding.size(); i++) - if (_encoding[i].unicode) - scores[i] = unicode_score(_encoding[i].unicode); + if (_encoding[i].unicode) + scores[i] = unicode_score(_encoding[i].unicode); /* Prefer conventional f-ligatures. */ bool has_ff = false; @@ -1194,121 +1198,121 @@ Metrics::shrink_encoding(int size, const only by fakes. */ bool changed = true; while (changed) { - changed = false; - for (Ligature3 *l = all_ligs.begin(); l != all_ligs.end(); l++) { - int score = scores[l->in1] + scores[l->in2]; - if (scores[l->out] > score) + changed = false; + for (Ligature3 *l = all_ligs.begin(); l != all_ligs.end(); l++) { + int score = scores[l->in1] + scores[l->in2]; + if (scores[l->out] > score) scores[l->out] = score, changed = true; - } + } - for (Code c = 0; c < _encoding.size(); c++) - if (VirtualChar *vc = _encoding[c].virtual_char) { - /* Make sure that if this virtual character appears, its parts - will also appear, by scoring the parts less */ - int score = scores[c] - 1, font_number = 0; - for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) - if (s->op == Setting::SHOW && font_number == 0 - && score < scores[s->x]) - scores[s->x] = score, changed = true; - else if (s->op == Setting::FONT) - font_number = s->x; - } + for (Code c = 0; c < _encoding.size(); c++) + if (VirtualChar *vc = _encoding[c].virtual_char) { + /* Make sure that if this virtual character appears, its parts + will also appear, by scoring the parts less */ + int score = scores[c] - 1, font_number = 0; + for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + if (s->op == Setting::SHOW && font_number == 0 + && score < scores[s->x]) + scores[s->x] = score, changed = true; + else if (s->op == Setting::FONT) + font_number = s->x; + } } /* Rescore intermediates to not be better off than their endpoints. */ /* XXX multiple layers of intermediate? */ for (Code c = 0; c < _encoding.size(); c++) { - Char &ch = _encoding[c]; - if (ch.flag(Char::INTERMEDIATE)) - for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) - if (scores[c] < scores[l->out] && !_encoding[l->out].context_setting(c, l->in2)) - scores[c] = scores[l->out]; + Char &ch = _encoding[c]; + if (ch.flag(Char::INTERMEDIATE)) + for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) + if (scores[c] < scores[l->out] && !_encoding[l->out].context_setting(c, l->in2)) + scores[c] = scores[l->out]; } /* Collect characters that want to be reassigned. */ Vector slots; for (Code c = size; c < _encoding.size(); c++) - if (scores[c] < NOCHAR_SCORE - && !(_encoding[c].flags & Char::CONTEXT_ONLY) - && (_encoding[c].flags & (Char::LIVE | Char::BASE_LIVE))) { - Slot slot = { c, -1, _encoding[c].glyph, scores[c], _encoding[c].lookup_source }; - slots.push_back(slot); - } + if (scores[c] < NOCHAR_SCORE + && !(_encoding[c].flags & Char::CONTEXT_ONLY) + && (_encoding[c].flags & (Char::LIVE | Char::BASE_LIVE))) { + Slot slot = { c, -1, _encoding[c].glyph, scores[c], _encoding[c].lookup_source }; + slots.push_back(slot); + } // Sort them by score, then by glyph. std::sort(slots.begin(), slots.end()); /* Prefer their old slots, if available. */ for (Slot *slot = slots.begin(); slot < slots.end(); slot++) - if (PermString g = code_name(slot->old_code)) { - int c = dvipsenc.encoding_of(g); - if (c >= 0 && _encoding[c].glyph == 0) { - _encoding[c].swap(_encoding[slot->old_code]); - slot->new_code = c; - } - } + if (PermString g = code_name(slot->old_code)) { + int c = dvipsenc.encoding_of(g); + if (c >= 0 && _encoding[c].glyph == 0) { + _encoding[c].swap(_encoding[slot->old_code]); + slot->new_code = c; + } + } /* List empty slots in two phases: Those not encoded by the input encoding, then those encoded by the input encoding (but that character wasn't available). */ Vector empty_codes; for (int want_encoded = 0; want_encoded < 2; want_encoded++) - for (Code c = 0; c < size; c++) - if (_encoding[c].base_code < 0 - && dvipsenc.encoded(c) == (bool) want_encoded) - empty_codes.push_back(c); + for (Code c = 0; c < size; c++) + if (_encoding[c].base_code < 0 + && dvipsenc.encoded(c) == (bool) want_encoded) + empty_codes.push_back(c); /* Then, assign codes to the unencoded characters. */ int nunencoded = 0; for (Slot *slot = slots.begin(); slot != slots.end(); slot++) { - if (slot->new_code >= 0) - continue; + if (slot->new_code >= 0) + continue; - int needs = (_encoding[slot->old_code].visible_base() ? 1 : 0) - + (_encoding[slot->old_code].flag(Char::LIVE) ? 2 : 0); - assert(needs > 0); - - Code dest = -1; - for (Code *h = empty_codes.begin(); h < empty_codes.end() && dest < 0; h++) { - int haves = (_encoding[*h].base_code < 0 ? 1 : 0) - + (!_encoding[*h].visible() ? 2 : 0); - if ((needs & haves) == needs) - dest = *h; - } - - if (dest >= 0) { - if (needs & 2) { - assert(!_encoding[dest].visible()); - _encoding[dest].swap(_encoding[slot->old_code]); - slot->new_code = dest; - } else { - _encoding[slot->old_code].base_code = dest; - slot->new_code = slot->old_code; - } - if (needs & 1) { - assert(_encoding[dest].base_code < 0 || _encoding[dest].base_code == slot->old_code); - _encoding[dest].base_code = slot->old_code; - } - } else - nunencoded++; + int needs = (_encoding[slot->old_code].visible_base() ? 1 : 0) + + (_encoding[slot->old_code].flag(Char::LIVE) ? 2 : 0); + assert(needs > 0); + + Code dest = -1; + for (Code *h = empty_codes.begin(); h < empty_codes.end() && dest < 0; h++) { + int haves = (_encoding[*h].base_code < 0 ? 1 : 0) + + (!_encoding[*h].visible() ? 2 : 0); + if ((needs & haves) == needs) + dest = *h; + } + + if (dest >= 0) { + if (needs & 2) { + assert(!_encoding[dest].visible()); + _encoding[dest].swap(_encoding[slot->old_code]); + slot->new_code = dest; + } else { + _encoding[slot->old_code].base_code = dest; + slot->new_code = slot->old_code; + } + if (needs & 1) { + assert(_encoding[dest].base_code < 0 || _encoding[dest].base_code == slot->old_code); + _encoding[dest].base_code = slot->old_code; + } + } else + nunencoded++; } /* Complain if some characters can't fit. */ if (nunencoded) { - // collect names of unencoded glyphs - Vector unencoded; - for (Slot *slot = slots.begin(); slot != slots.end(); slot++) - if (slot->new_code < 0) - unencoded.push_back(code_name(slot->old_code)); - std::sort(unencoded.begin(), unencoded.end()); - StringAccum sa; - for (const String* a = unencoded.begin(); a < unencoded.end(); a++) - sa << *a << ' '; - sa.pop_back(); - sa.append_break_lines(sa.take_string(), 68, " "); - sa.pop_back(); - errh->lwarning(" ", (unencoded.size() == 1 ? "not enough room in encoding, ignoring %d glyph" : "not enough room in encoding, ignoring %d glyphs"), unencoded.size()); - errh->lmessage(" ", "(\ + // collect names of unencoded glyphs + Vector unencoded; + for (Slot *slot = slots.begin(); slot != slots.end(); slot++) + if (slot->new_code < 0) + unencoded.push_back(code_name(slot->old_code)); + std::sort(unencoded.begin(), unencoded.end()); + StringAccum sa; + for (const String* a = unencoded.begin(); a < unencoded.end(); a++) + sa << *a << ' '; + sa.pop_back(); + sa.append_break_lines(sa.take_string(), 68, " "); + sa.pop_back(); + errh->lwarning(" ", (unencoded.size() == 1 ? "not enough room in encoding, ignoring %d glyph" : "not enough room in encoding, ignoring %d glyphs"), unencoded.size()); + errh->lmessage(" ", "(\ The font uses more glyphs than the encoding has available slots,\n\ so these glyphs have been left out:\n%s\n\ To select specific glyphs, add them to the input encoding.)", sa.c_str()); @@ -1317,10 +1321,10 @@ To select specific glyphs, add them to t /* Reencode changed slots. */ Vector reencoding; for (Code c = 0; c < _encoding.size(); c++) - reencoding.push_back(c); + reencoding.push_back(c); for (Slot *s = slots.begin(); s != slots.end(); s++) - if (s->new_code >= 0) - reencoding[s->old_code] = s->new_code; + if (s->new_code >= 0) + reencoding[s->old_code] = s->new_code; reencode(reencoding); check(); @@ -1331,38 +1335,38 @@ Metrics::make_base(int size) { Vector reencoding; for (Code c = 0; c < size && c < _encoding.size(); c++) { - Char &ch = _encoding[c]; - if (ch.base_code >= 0 && ch.base_code != c) { - if (!reencoding.size()) - for (Code cc = 0; cc < _encoding.size(); cc++) - reencoding.push_back(cc); - reencoding[ch.base_code] = c; - reencoding[c] = ch.base_code; - _encoding[c].swap(_encoding[ch.base_code]); - } - if (ch.virtual_char) // remove it - ch.clear(); + Char &ch = _encoding[c]; + if (ch.base_code >= 0 && ch.base_code != c) { + if (!reencoding.size()) + for (Code cc = 0; cc < _encoding.size(); cc++) + reencoding.push_back(cc); + reencoding[ch.base_code] = c; + reencoding[c] = ch.base_code; + _encoding[c].swap(_encoding[ch.base_code]); + } + if (ch.virtual_char) // remove it + ch.clear(); } if (reencoding.size()) { - reencode(reencoding); - cut_encoding(size); + reencode(reencoding); + cut_encoding(size); } check(); } /*****************************************************************************/ -/* output */ +/* output */ bool Metrics::need_virtual(int size) const { if (size > _encoding.size()) - size = _encoding.size(); + size = _encoding.size(); for (const Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) - if (ch->glyph /* actually encoded */ - && (ch->pdx || ch->pdy || ch->adx || ch->virtual_char)) - return true; + if (ch->glyph /* actually encoded */ + && (ch->pdx || ch->pdy || ch->adx || ch->virtual_char)) + return true; return false; } @@ -1370,10 +1374,10 @@ bool Metrics::need_base() { if (!_liveness_marked) - mark_liveness(_encoding.size()); + mark_liveness(_encoding.size()); for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) - if ((ch->flags & Char::BASE_LIVE) && ch->glyph != _boundary_glyph) - return true; + if ((ch->flags & Char::BASE_LIVE) && ch->glyph != _boundary_glyph) + return true; return false; } @@ -1383,72 +1387,72 @@ Metrics::setting(Code code, Vectorsetting.begin(); s != vc->setting.end(); s++) - switch (s->op) { - case Setting::MOVE: - case Setting::RULE: - case Setting::PUSH: - case Setting::POP: - case Setting::SPECIAL: - v.push_back(*s); - break; - case Setting::FONT: - v.push_back(*s); - font_number = s->x; - break; - case Setting::SHOW: - if (font_number == 0) - good &= setting(s->x, v, (SettingMode)(sm | SET_KEEP)); - else - v.push_back(*s); - break; - case Setting::KERN: - case Setting::KERNX: - if (sm & SET_INTERMEDIATE) - v.push_back(*s); - else if (font_number == 0 && s > vc->setting.begin() - && s + 1 < vc->setting.end() - && s[-1].op == Setting::SHOW - && s[1].op == Setting::SHOW) { - int k = kern(s[-1].x, s[1].x); - if (s->op == Setting::KERNX) - k -= letterspace; - if (k) - v.push_back(Setting(Setting::MOVE, k, 0)); - } - break; - } - - if (ch.pdy != 0 || ch.adx - ch.pdx != 0) - v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); - return good; + for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + switch (s->op) { + case Setting::MOVE: + case Setting::RULE: + case Setting::PUSH: + case Setting::POP: + case Setting::SPECIAL: + v.push_back(*s); + break; + case Setting::FONT: + v.push_back(*s); + font_number = s->x; + break; + case Setting::SHOW: + if (font_number == 0) + good &= setting(s->x, v, (SettingMode)(sm | SET_KEEP)); + else + v.push_back(*s); + break; + case Setting::KERN: + case Setting::KERNX: + if (sm & SET_INTERMEDIATE) + v.push_back(*s); + else if (font_number == 0 && s > vc->setting.begin() + && s + 1 < vc->setting.end() + && s[-1].op == Setting::SHOW + && s[1].op == Setting::SHOW) { + int k = kern(s[-1].x, s[1].x); + if (s->op == Setting::KERNX) + k -= letterspace; + if (k) + v.push_back(Setting(Setting::MOVE, k, 0)); + } + break; + } + + if (ch.pdy != 0 || ch.adx - ch.pdx != 0) + v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); + return good; } else if (ch.base_code >= 0) { - if (ch.pdx != 0 || ch.pdy != 0) - v.push_back(Setting(Setting::MOVE, ch.pdx, ch.pdy)); + if (ch.pdx != 0 || ch.pdy != 0) + v.push_back(Setting(Setting::MOVE, ch.pdx, ch.pdy)); - v.push_back(Setting(Setting::SHOW, ch.base_code, ch.glyph)); + v.push_back(Setting(Setting::SHOW, ch.base_code, ch.glyph)); - if (ch.pdy != 0 || ch.adx - ch.pdx != 0) - v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); - return true; + if (ch.pdy != 0 || ch.adx - ch.pdx != 0) + v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); + return true; } else - return false; + return false; } int @@ -1460,22 +1464,22 @@ Metrics::ligatures(Code in1, Vectorin2); - const Char &outch = _encoding[l->out]; - if (outch.context_setting(in1, l->in2)) { - if (in1 == outch.built_in1 && l->in2 == outch.built_in2) - in2.pop_back(); - else if (in1 == outch.built_in1) { - out.push_back(outch.built_in2); - context.push_back(-1); - } else { - out.push_back(outch.built_in1); - context.push_back(1); - } - } else { - out.push_back(l->out); - context.push_back(0); - } + in2.push_back(l->in2); + const Char &outch = _encoding[l->out]; + if (outch.context_setting(in1, l->in2)) { + if (in1 == outch.built_in1 && l->in2 == outch.built_in2) + in2.pop_back(); + else if (in1 == outch.built_in1) { + out.push_back(outch.built_in2); + context.push_back(-1); + } else { + out.push_back(outch.built_in1); + context.push_back(1); + } + } else { + out.push_back(l->out); + context.push_back(0); + } } return in2.size(); @@ -1489,74 +1493,74 @@ Metrics::kerns(Code in1, Vector &i const Char &in1ch = _encoding[in1]; for (const Kern *k = in1ch.kerns.begin(); k != in1ch.kerns.end(); k++) - if (k->kern != 0) { - in2.push_back(k->in2); - kern.push_back(k->kern); - } + if (k->kern != 0) { + in2.push_back(k->in2); + kern.push_back(k->kern); + } return in2.size(); } /*****************************************************************************/ -/* debugging */ +/* debugging */ void Metrics::unparse(const Char *ch) const { Code c; if (ch >= _encoding.begin() && ch < _encoding.end()) - c = ch - _encoding.begin(); + c = ch - _encoding.begin(); else - c = -1; + c = -1; fprintf(stderr, "%4d/%s%s%s%s%s%s\n", c, code_str(c), - (ch->flag(Char::LIVE) ? " [L]" : ""), - (ch->flag(Char::BASE_LIVE) ? " [B]" : ""), - (ch->flag(Char::CONTEXT_ONLY) ? " [C]" : ""), - (ch->flag(Char::BUILT) ? " [!]" : ""), - (ch->base_code >= 0 ? " " : "")); + (ch->flag(Char::LIVE) ? " [L]" : ""), + (ch->flag(Char::BASE_LIVE) ? " [B]" : ""), + (ch->flag(Char::CONTEXT_ONLY) ? " [C]" : ""), + (ch->flag(Char::BUILT) ? " [!]" : ""), + (ch->base_code >= 0 ? " " : "")); if (ch->base_code >= 0 && ch->base_code != c) - fprintf(stderr, "\tBASE %d/%s\n", ch->base_code, code_str(ch->base_code)); + fprintf(stderr, "\tBASE %d/%s\n", ch->base_code, code_str(ch->base_code)); if (const VirtualChar *vc = ch->virtual_char) { - fprintf(stderr, "\t*"); - int curfont = 0; - for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) - switch (s->op) { - case Setting::FONT: - fprintf(stderr, " {F%d}", s->x); - curfont = s->x; - break; - case Setting::SHOW: - fprintf(stderr, " %d", s->x); - if (curfont == 0) - fprintf(stderr, "/%s", code_str(s->x)); - break; - case Setting::KERN: - fprintf(stderr, " <>"); - break; - case Setting::MOVE: - fprintf(stderr, " <%+d,%+d>", s->x, s->y); - break; - case Setting::RULE: - fprintf(stderr, " [%d,%d]", s->x, s->y); - break; - case Setting::PUSH: - fprintf(stderr, " ("); - break; - case Setting::POP: - fprintf(stderr, " )"); - break; - case Setting::SPECIAL: - fprintf(stderr, " S{%s}", s->s.c_str()); - break; - } - fprintf(stderr, " ((%d/%s, %d/%s))\n", ch->built_in1, code_str(ch->built_in1), ch->built_in2, code_str(ch->built_in2)); + fprintf(stderr, "\t*"); + int curfont = 0; + for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) + switch (s->op) { + case Setting::FONT: + fprintf(stderr, " {F%d}", s->x); + curfont = s->x; + break; + case Setting::SHOW: + fprintf(stderr, " %d", s->x); + if (curfont == 0) + fprintf(stderr, "/%s", code_str(s->x)); + break; + case Setting::KERN: + fprintf(stderr, " <>"); + break; + case Setting::MOVE: + fprintf(stderr, " <%+d,%+d>", s->x, s->y); + break; + case Setting::RULE: + fprintf(stderr, " [%d,%d]", s->x, s->y); + break; + case Setting::PUSH: + fprintf(stderr, " ("); + break; + case Setting::POP: + fprintf(stderr, " )"); + break; + case Setting::SPECIAL: + fprintf(stderr, " S{%s}", s->s.c_str()); + break; + } + fprintf(stderr, " ((%d/%s, %d/%s))\n", ch->built_in1, code_str(ch->built_in1), ch->built_in2, code_str(ch->built_in2)); } for (const Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) - fprintf(stderr, "\t[%d/%s => %d/%s]%s\n", l->in2, code_str(l->in2), l->out, code_str(l->out), (_encoding[l->out].context_setting(c, l->in2) ? " [C]" : "")); + fprintf(stderr, "\t[%d/%s => %d/%s]%s\n", l->in2, code_str(l->in2), l->out, code_str(l->out), (_encoding[l->out].context_setting(c, l->in2) ? " [C]" : "")); #if 0 for (const Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) - fprintf(stderr, "\t{%d/%s %+d}\n", k->in2, code_str(k->in2), k->kern); + fprintf(stderr, "\t{%d/%s %+d}\n", k->in2, code_str(k->in2), k->kern); #endif } @@ -1564,6 +1568,6 @@ void Metrics::unparse() const { for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) - if (ch->glyph) - unparse(ch); + if (ch->glyph) + unparse(ch); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/metrics.hh 2018-02-23 12:47:54.092971728 -0500 @@ -2,23 +2,11 @@ #define OTFTOTFM_METRICS_HH #include #include +#include "setting.hh" namespace Efont { class CharstringProgram; } class DvipsEncoding; class GlyphFilter; -struct Setting { - enum { NONE, FONT, SHOW, KERN, KERNX, MOVE, RULE, PUSH, POP, - SPECIAL, DEAD }; - int op; - int x; - int y; - String s; - Setting(int op_in, int x_in = 0, int y_in = 0) - : op(op_in), x(x_in), y(y_in) { } - Setting(int op_in, const String &s_in) : op(op_in), s(s_in) { } - bool valid_op() const { return op >= FONT && op <= SPECIAL; } -}; - class Metrics { public: typedef int Code; @@ -33,22 +21,22 @@ class Metrics { public: void check() const; - Glyph boundary_glyph() const { return _boundary_glyph; } - Glyph emptyslot_glyph() const { return _emptyslot_glyph; } + Glyph boundary_glyph() const { return _boundary_glyph; } + Glyph emptyslot_glyph() const { return _emptyslot_glyph; } - String coding_scheme() const { return _coding_scheme; } - void set_coding_scheme(const String &s) { _coding_scheme = s; } + String coding_scheme() const { return _coding_scheme; } + void set_coding_scheme(const String &s) { _coding_scheme = s; } - int design_units() const { return _design_units; } - int units_per_em() const { return _units_per_em; } - void set_design_units(int du) { _design_units = du; } + int design_units() const { return _design_units; } + int units_per_em() const { return _units_per_em; } + void set_design_units(int du) { _design_units = du; } - int n_mapped_fonts() const { return _mapped_fonts.size();} + int n_mapped_fonts() const { return _mapped_fonts.size();} const Efont::CharstringProgram *mapped_font(int i) const { return _mapped_fonts[i]; } const String &mapped_font_name(int i) const { return _mapped_font_names[i]; } int add_mapped_font(const Efont::CharstringProgram *, const String &); - inline int encoding_size() const { return _encoding.size(); } + inline int encoding_size() const { return _encoding.size(); } inline bool valid_code(Code) const; inline bool nonvirtual_code(Code) const; PermString code_name(Code) const; @@ -63,7 +51,7 @@ class Metrics { public: void encode_virtual(Code, PermString, uint32_t uni, const Vector &, bool base_char); void add_altselector_code(Code, int altselector_type); - bool altselectors() const { return _altselectors.size() > 0; } + bool altselectors() const { return _altselectors.size() > 0; } inline bool was_base_glyph(Code) const; inline Code base_code(Code) const; @@ -101,57 +89,57 @@ class Metrics { public: void unparse() const; struct Ligature { - Code in2; - Code out; - Ligature(Code in2_, Code out_) : in2(in2_), out(out_) { } + Code in2; + Code out; + Ligature(Code in2_, Code out_) : in2(in2_), out(out_) { } }; struct Kern { - Code in2; - int kern; - Kern(Code in2_, int kern_) : in2(in2_), kern(kern_) { } + Code in2; + int kern; + Kern(Code in2_, int kern_) : in2(in2_), kern(kern_) { } }; struct VirtualChar { - PermString name; - Vector setting; + PermString name; + Vector setting; }; struct Ligature3 { - Code in1; - Code in2; - Code out; - Ligature3(Code in1_, Code in2_, Code out_) : in1(in1_), in2(in2_), out(out_) { } + Code in1; + Code in2; + Code out; + Ligature3(Code in1_, Code in2_, Code out_) : in1(in1_), in2(in2_), out(out_) { } String unparse(const Metrics& m) const; }; private: struct Char { - Glyph glyph; - Code base_code; - uint32_t unicode; - Vector ligatures; - Vector kerns; - VirtualChar *virtual_char; - int pdx; - int pdy; - int adx; - Code built_in1; - Code built_in2; - int lookup_source; - enum { BUILT = 1, INTERMEDIATE = 2, CONTEXT_ONLY = 4, LIVE = 8, - BASE_LIVE = 16, BASE_REP = 32, IS_FF = 64 }; - int flags; - - Char() : virtual_char(0) { clear(); } - void clear(); - void swap(Char &); - bool visible() const { return glyph != 0; } - bool visible_base() const { return glyph != 0 && glyph != VIRTUAL_GLYPH; } - bool flag(int f) const { return (flags & f) != 0; } - inline bool base_glyph() const; - bool context_setting(Code in1, Code in2) const; + Glyph glyph; + Code base_code; + uint32_t unicode; + Vector ligatures; + Vector kerns; + VirtualChar *virtual_char; + int pdx; + int pdy; + int adx; + Code built_in1; + Code built_in2; + int lookup_source; + enum { BUILT = 1, INTERMEDIATE = 2, CONTEXT_ONLY = 4, LIVE = 8, + BASE_LIVE = 16, BASE_REP = 32, IS_FF = 64 }; + int flags; + + Char() : virtual_char(0) { clear(); } + void clear(); + void swap(Char &); + bool visible() const { return glyph != 0; } + bool visible_base() const { return glyph != 0 && glyph != VIRTUAL_GLYPH; } + bool flag(int f) const { return (flags & f) != 0; } + inline bool base_glyph() const; + bool context_setting(Code in1, Code in2) const; }; Vector _encoding; @@ -171,7 +159,7 @@ class Metrics { public: Vector _mapped_fonts; Vector _mapped_font_names; - Metrics(const Metrics &); // does not exist + Metrics(const Metrics &); // does not exist Metrics &operator=(const Metrics &); // does not exist inline void assign_emap(Glyph, Code); @@ -191,17 +179,19 @@ class Metrics { public: class ChangedContext; void apply_ligature(const Vector &, const Substitution *, int lookup); void apply_single(Code cin, const Substitution *s, int lookup, - ChangedContext &ctx, const GlyphFilter &glyph_filter, - const Vector &glyph_names); + ChangedContext &ctx, const GlyphFilter &glyph_filter, + const Vector &glyph_names); void apply_simple_context_ligature(const Vector &codes, - const Substitution *s, int lookup, ChangedContext &ctx); + const Substitution *s, int lookup, ChangedContext &ctx, + const GlyphFilter &glyph_filter, + const Vector &glyph_names); void apply_alternates_single(Code cin, const Substitution *s, int lookup, - const GlyphFilter &glyph_filter, - const Vector &glyph_names); + const GlyphFilter &glyph_filter, + const Vector &glyph_names); void apply_alternates_ligature(const Vector &codes, - const Substitution *s, int lookup, - const GlyphFilter &glyph_filter, - const Vector &glyph_names); + const Substitution *s, int lookup, + const GlyphFilter &glyph_filter, + const Vector &glyph_names); void unparse(const Char *) const; @@ -224,36 +214,36 @@ inline Metrics::Glyph Metrics::glyph(Code code) const { if (code < 0 || code >= _encoding.size()) - return 0; + return 0; else - return _encoding[code].glyph; + return _encoding[code].glyph; } inline uint32_t Metrics::unicode(Code code) const { if (code < 0 || code >= _encoding.size()) - return 0; + return 0; else - return _encoding[code].unicode; + return _encoding[code].unicode; } inline Metrics::Glyph Metrics::base_glyph(Code code) const { if (code < 0 || code >= _encoding.size() || _encoding[code].base_code < 0) - return 0; + return 0; else - return _encoding[code].glyph; + return _encoding[code].glyph; } inline Metrics::Code Metrics::base_code(Code code) const { if (code < 0 || code >= _encoding.size()) - return 0; + return 0; else - return _encoding[code].base_code; + return _encoding[code].base_code; } inline Metrics::Code @@ -261,16 +251,16 @@ Metrics::encoding(Glyph g, Code after) c { Code c; if (g >= 0 && g < _emap.size() && (c = _emap.at_u(g)) >= -1) - return c < 0 || c >= after ? c : -1; + return c < 0 || c >= after ? c : -1; else - return hard_encoding(g, after); + return hard_encoding(g, after); } inline void Metrics::assign_emap(Glyph g, Code code) { if (g >= _emap.size()) - _emap.resize(g + 1, -1); + _emap.resize(g + 1, -1); _emap[g] = (_emap[g] == -1 || _emap[g] == code ? code : -2); } @@ -290,9 +280,9 @@ inline bool Metrics::was_base_glyph(Code code) const { if (code < 0 || code >= _encoding.size()) - return 0; + return 0; else - return _encoding[code].base_glyph(); + return _encoding[code].base_glyph(); } #endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.1 2018-02-23 12:47:54.092971728 -0500 @@ -1,5 +1,5 @@ '\"t -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. @@ -868,15 +868,19 @@ Do not generate a font map line for the .BI \-\-truetype\-directory= dir .TP 5 .BI \-\-type42\-directory= dir +.TP 5 +.BI \-\-directory= dir Set the directory used for various output types. Each directory may be set by an environment variable, and defaults to a TDS directory in automatic mode, or to "." otherwise. Environment variable names and default TDS -locations are described in the Automatic Mode section above. +locations are described in the Automatic Mode section above. The +.B \-\-directory +option sets the default directory for all output types. ' .Sp .TP 5 .BI \-\-map\-file= filename -Set file in which +Set file in which .B otftotfm will write a font map line for the font. The default is the standard output in manual mode, and @@ -956,7 +960,7 @@ have the following format: This tells .B otftotfm that the glyph named -.I glyph +.I glyph translates into the first Unicode value in the .I choice list that has a character in the font. \fIGlyph\fR and the @@ -1042,7 +1046,7 @@ and .IR glyph2 . "{LK}" and "{KL}" inhibit both ligatures and kerns. .PP -You can set the +You can set the .B \-\-boundary\-char and .B \-\-altselector\-char @@ -1060,7 +1064,7 @@ has a default set of eight ligatures, na space l =: lslash ; space L =: Lslash ; question quoteleft =: questiondown ; exclam quoteleft =: exclamdown ; hyphen hyphen =: endash ; endash hyphen =: emdash ; - quoteleft quoteleft =: quotedblleft ; + quoteleft quoteleft =: quotedblleft ; quoteright quoteright =: quotedblright .fi LIGKERN commands in the encoding file and diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.cc 2018-02-23 12:47:54.094971678 -0500 @@ -1,6 +1,6 @@ /* otftotfm.cc -- driver for translating OpenType fonts to TeX metrics * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -63,91 +63,89 @@ #ifdef HAVE_FCNTL_H # include #endif -#ifdef _MSC_VER -# include -#endif using namespace Efont; -#define VERSION_OPT 301 -#define HELP_OPT 302 -#define QUERY_SCRIPTS_OPT 303 -#define QUERY_FEATURES_OPT 304 -#define KPATHSEA_DEBUG_OPT 305 - -#define SCRIPT_OPT 311 -#define FEATURE_OPT 312 -#define ENCODING_OPT 313 -#define LITERAL_ENCODING_OPT 314 -#define EXTEND_OPT 315 -#define SLANT_OPT 316 -#define LETTERSPACE_OPT 317 -#define LIGKERN_OPT 318 -#define CODINGSCHEME_OPT 319 -#define UNICODING_OPT 320 -#define BOUNDARY_CHAR_OPT 321 -#define DESIGN_SIZE_OPT 322 -#define MINIMUM_KERN_OPT 323 -#define ALTSELECTOR_CHAR_OPT 324 -#define INCLUDE_ALTERNATES_OPT 325 -#define EXCLUDE_ALTERNATES_OPT 326 -#define CLEAR_ALTERNATES_OPT 327 -#define ALTSELECTOR_FEATURE_OPT 328 -#define DEFAULT_LIGKERN_OPT 329 -#define NO_ECOMMAND_OPT 330 -#define LETTER_FEATURE_OPT 331 -#define INCLUDE_SUBS_OPT 332 -#define EXCLUDE_SUBS_OPT 333 -#define CLEAR_SUBS_OPT 334 -#define SUBS_FILTER_OPT 335 -#define ALTERNATES_FILTER_OPT 336 -#define SPACE_FACTOR_OPT 337 -#define MATH_SPACING_OPT 338 -#define POSITION_OPT 339 -#define WARN_MISSING_OPT 340 -#define BASE_ENCODINGS_OPT 341 -#define FIXED_PITCH_OPT 342 -#define ITALIC_ANGLE_OPT 343 -#define PROPORTIONAL_WIDTH_OPT 344 -#define X_HEIGHT_OPT 345 - -#define AUTOMATIC_OPT 350 -#define FONT_NAME_OPT 351 -#define QUIET_OPT 352 -#define GLYPHLIST_OPT 353 -#define VENDOR_OPT 354 -#define TYPEFACE_OPT 355 -#define NOCREATE_OPT 356 -#define VERBOSE_OPT 357 -#define FORCE_OPT 358 - -#define VIRTUAL_OPT 360 -#define PL_OPT 361 -#define TFM_OPT 362 -#define MAP_FILE_OPT 363 -#define OUTPUT_ENCODING_OPT 364 - -#define DIR_OPTS 380 -#define ENCODING_DIR_OPT (DIR_OPTS + O_ENCODING) -#define TFM_DIR_OPT (DIR_OPTS + O_TFM) -#define PL_DIR_OPT (DIR_OPTS + O_PL) -#define VF_DIR_OPT (DIR_OPTS + O_VF) -#define VPL_DIR_OPT (DIR_OPTS + O_VPL) -#define TYPE1_DIR_OPT (DIR_OPTS + O_TYPE1) -#define TYPE42_DIR_OPT (DIR_OPTS + O_TYPE42) -#define TRUETYPE_DIR_OPT (DIR_OPTS + O_TRUETYPE) - -#define NO_OUTPUT_OPTS 400 -#define NO_ENCODING_OPT (NO_OUTPUT_OPTS + G_ENCODING) -#define NO_TYPE1_OPT (NO_OUTPUT_OPTS + G_TYPE1) -#define NO_DOTLESSJ_OPT (NO_OUTPUT_OPTS + G_DOTLESSJ) -#define NO_UPDMAP_OPT (NO_OUTPUT_OPTS + G_UPDMAP) - -#define YES_OUTPUT_OPTS 2000 -#define TRUETYPE_OPT (YES_OUTPUT_OPTS + G_TRUETYPE) -#define TYPE42_OPT (YES_OUTPUT_OPTS + G_TYPE42) +#define VERSION_OPT 301 +#define HELP_OPT 302 +#define QUERY_SCRIPTS_OPT 303 +#define QUERY_FEATURES_OPT 304 +#define KPATHSEA_DEBUG_OPT 305 + +#define SCRIPT_OPT 311 +#define FEATURE_OPT 312 +#define ENCODING_OPT 313 +#define LITERAL_ENCODING_OPT 314 +#define EXTEND_OPT 315 +#define SLANT_OPT 316 +#define LETTERSPACE_OPT 317 +#define LIGKERN_OPT 318 +#define CODINGSCHEME_OPT 319 +#define UNICODING_OPT 320 +#define BOUNDARY_CHAR_OPT 321 +#define DESIGN_SIZE_OPT 322 +#define MINIMUM_KERN_OPT 323 +#define ALTSELECTOR_CHAR_OPT 324 +#define INCLUDE_ALTERNATES_OPT 325 +#define EXCLUDE_ALTERNATES_OPT 326 +#define CLEAR_ALTERNATES_OPT 327 +#define ALTSELECTOR_FEATURE_OPT 328 +#define DEFAULT_LIGKERN_OPT 329 +#define NO_ECOMMAND_OPT 330 +#define LETTER_FEATURE_OPT 331 +#define INCLUDE_SUBS_OPT 332 +#define EXCLUDE_SUBS_OPT 333 +#define CLEAR_SUBS_OPT 334 +#define SUBS_FILTER_OPT 335 +#define ALTERNATES_FILTER_OPT 336 +#define SPACE_FACTOR_OPT 337 +#define MATH_SPACING_OPT 338 +#define POSITION_OPT 339 +#define WARN_MISSING_OPT 340 +#define BASE_ENCODINGS_OPT 341 +#define FIXED_PITCH_OPT 342 +#define ITALIC_ANGLE_OPT 343 +#define PROPORTIONAL_WIDTH_OPT 344 +#define X_HEIGHT_OPT 345 + +#define AUTOMATIC_OPT 350 +#define FONT_NAME_OPT 351 +#define QUIET_OPT 352 +#define GLYPHLIST_OPT 353 +#define VENDOR_OPT 354 +#define TYPEFACE_OPT 355 +#define NOCREATE_OPT 356 +#define VERBOSE_OPT 357 +#define FORCE_OPT 358 + +#define VIRTUAL_OPT 360 +#define PL_OPT 361 +#define TFM_OPT 362 +#define MAP_FILE_OPT 363 +#define OUTPUT_ENCODING_OPT 364 + +#define DIR_OPTS 380 +#define ENCODING_DIR_OPT (DIR_OPTS + O_ENCODING) +#define TFM_DIR_OPT (DIR_OPTS + O_TFM) +#define PL_DIR_OPT (DIR_OPTS + O_PL) +#define VF_DIR_OPT (DIR_OPTS + O_VF) +#define VPL_DIR_OPT (DIR_OPTS + O_VPL) +#define TYPE1_DIR_OPT (DIR_OPTS + O_TYPE1) +#define TYPE42_DIR_OPT (DIR_OPTS + O_TYPE42) +#define TRUETYPE_DIR_OPT (DIR_OPTS + O_TRUETYPE) +#define DIR_OPT (DIR_OPTS + NUMODIR) + +#define NO_OUTPUT_OPTS 400 +#define NO_ENCODING_OPT (NO_OUTPUT_OPTS + G_ENCODING) +#define NO_TYPE1_OPT (NO_OUTPUT_OPTS + G_TYPE1) +#define NO_DOTLESSJ_OPT (NO_OUTPUT_OPTS + G_DOTLESSJ) +#define NO_UPDMAP_OPT (NO_OUTPUT_OPTS + G_UPDMAP) + +#define YES_OUTPUT_OPTS 2000 +#define TRUETYPE_OPT (YES_OUTPUT_OPTS + G_TRUETYPE) +#define TYPE42_OPT (YES_OUTPUT_OPTS + G_TYPE42) -#define CHAR_OPTTYPE (Clp_ValFirstUser) +#define CHAR_OPTTYPE (Clp_ValFirstUser) static Clp_Option options[] = { @@ -194,7 +192,8 @@ static Clp_Option options[] = { { "italic-angle", 0, ITALIC_ANGLE_OPT, Clp_ValDouble, 0 }, { "x-height", 0, X_HEIGHT_OPT, Clp_ValString, 0 }, - { "pl", 'p', PL_OPT, 0, 0 }, + { "pl", 'p', PL_OPT, 0, Clp_Negate }, + { "tfm", 't', TFM_OPT, 0, Clp_Negate }, // not in documentation { "virtual", 0, VIRTUAL_OPT, 0, Clp_Negate }, { "no-encoding", 0, NO_ENCODING_OPT, 0, 0 }, { "no-type1", 0, NO_TYPE1_OPT, 0, 0 }, @@ -210,6 +209,7 @@ static Clp_Option options[] = { { "vendor", 'v', VENDOR_OPT, Clp_ValString, 0 }, { "typeface", 0, TYPEFACE_OPT, Clp_ValString, 0 }, + { "directory", 0, DIR_OPT, Clp_ValString, 0 }, { "encoding-directory", 0, ENCODING_DIR_OPT, Clp_ValString, 0 }, { "pl-directory", 0, PL_DIR_OPT, Clp_ValString, 0 }, { "tfm-directory", 0, TFM_DIR_OPT, Clp_ValString, 0 }, @@ -229,7 +229,6 @@ static Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, - { "tfm", 't', TFM_OPT, 0, 0 }, // deprecated { "query-features", 0, QUERY_FEATURES_OPT, 0, 0 }, { "qf", 0, QUERY_FEATURES_OPT, 0, 0 }, { "query-scripts", 0, QUERY_SCRIPTS_OPT, 0, 0 }, @@ -286,7 +285,7 @@ static double x_height; static String out_encoding_file; static String out_encoding_name; -int output_flags = G_ENCODING | G_METRICS | G_VMETRICS | G_PSFONTSMAP | G_TYPE1 | G_DOTLESSJ | G_UPDMAP | G_BINARY | G_TRUETYPE; +unsigned output_flags = G_ENCODING | G_METRICS | G_VMETRICS | G_PSFONTSMAP | G_TYPE1 | G_DOTLESSJ | G_UPDMAP | G_TRUETYPE; bool automatic = false; bool verbose = false; @@ -303,9 +302,9 @@ usage_error(ErrorHandler *errh, const ch va_list val; va_start(val, error_message); if (!error_message) - errh->message("Usage: %s [OPTION]... FONT", program_name); + errh->message("Usage: %s [OPTION]... FONT", program_name); else - errh->xmessage(ErrorHandler::e_error, error_message, val); + errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } @@ -323,7 +322,7 @@ encoding. Output files are written to th %<--automatic%> and the % options).\n\ \n\ Usage: %s [-a] [OPTIONS] OTFFILE FONTNAME\n\n", - program_name); + program_name); uerrh.message("\ Font feature and transformation options:\n\ -s, --script=SCRIPT[.LANG] Use features for script SCRIPT[.LANG] [latn].\n\ @@ -391,6 +390,7 @@ File location options:\n\ --encoding-directory=DIR Put encoding files in DIR [.|automatic].\n\ --type1-directory=DIR Put Type 1 fonts in DIR [automatic].\n\ --truetype-directory=DIR Put TrueType fonts in DIR [automatic].\n\ + --directory=DIR Put output in DIR [.|automatic].\n\ --map-file=FILE Update FILE with psfonts.map information [-].\n\ \n\ Other options:\n\ @@ -449,14 +449,14 @@ suffix_font_name(const String &font_name { const char *begin = font_name.begin(), *end = font_name.end(); while (end > begin && isdigit((unsigned char) end[-1])) - --end; + --end; if (end < font_name.end() && end > begin && end[-1] != '-' && end[-1] != '+') - end = font_name.end(); + end = font_name.end(); else - while (end > begin && (end[-1] == '-' || end[-1] == '+')) - --end; + while (end > begin && (end[-1] == '-' || end[-1] == '+')) + --end; if (end == begin) - end = font_name.end(); + end = font_name.end(); return font_name.substring(begin, end) + suffix + font_name.substring(end, font_name.end()); } @@ -470,40 +470,40 @@ static double get_design_size(const FontInfo &finfo) { try { - String gpos_table = finfo.otf->table("GPOS"); - if (!gpos_table) - throw OpenType::Error(); - - ErrorHandler *errh = ErrorHandler::silent_handler(); - OpenType::Gpos gpos(gpos_table, errh); - - // extract 'size' feature(s) - int required_fid; - Vector fids; - for (const OpenType::Tag *t = interesting_scripts.begin(); t < interesting_scripts.end(); t += 2) - gpos.script_list().features(t[0], t[1], required_fid, fids, 0, false); - - int size_fid = gpos.feature_list().find(OpenType::Tag("size"), fids); - if (size_fid < 0) - throw OpenType::Error(); - - // old Adobe fonts implement an old, incorrect idea - // of what the FeatureParams offset means. - OpenType::Name name(finfo.otf->table("name"), errh); - OpenType::Data size_data = gpos.feature_list().size_params(size_fid, name, errh); - if (!size_data.length()) - throw OpenType::Error(); - - double result = size_data.u16(0) / 10.; - // check for insane design sizes - if (result < 1 || result > 1000) - throw OpenType::Error(); + String gpos_table = finfo.otf->table("GPOS"); + if (!gpos_table) + throw OpenType::Error(); + + ErrorHandler *errh = ErrorHandler::silent_handler(); + OpenType::Gpos gpos(gpos_table, errh); + + // extract 'size' feature(s) + int required_fid; + Vector fids; + for (const OpenType::Tag *t = interesting_scripts.begin(); t < interesting_scripts.end(); t += 2) + gpos.script_list().features(t[0], t[1], required_fid, fids, 0, false); + + int size_fid = gpos.feature_list().find(OpenType::Tag("size"), fids); + if (size_fid < 0) + throw OpenType::Error(); + + // old Adobe fonts implement an old, incorrect idea + // of what the FeatureParams offset means. + OpenType::Name name(finfo.otf->table("name"), errh); + OpenType::Data size_data = gpos.feature_list().size_params(size_fid, name, errh); + if (!size_data.length()) + throw OpenType::Error(); + + double result = size_data.u16(0) / 10.; + // check for insane design sizes + if (result < 1 || result > 1000) + throw OpenType::Error(); - // return a number in 'pt', not 'bp' - return result * 72.27 / 72.; + // return a number in 'pt', not 'bp' + return result * 72.27 / 72.; } catch (OpenType::Error) { - return 10.0; + return 10.0; } } @@ -556,9 +556,9 @@ void Printer::print(const char* prefix, String Printer::render(double value) const { value = transform(value); if (round_ || value == 0 || (value > 0.01 && value - floor(value) < 0.01)) - return String(value); + return String(value); else { - char buf[128]; + char buf[128]; sprintf(buf, "%.4f", value); return String(buf); } @@ -574,21 +574,21 @@ font_slant(const FontInfo &finfo) static void output_pl(Metrics &metrics, const String &ps_name, int boundary_char, - const FontInfo &finfo, bool vpl, - const String &filename, ErrorHandler *errh) + const FontInfo &finfo, bool vpl, + const String &filename, ErrorHandler *errh) { // create file if (no_create) { - errh->message("would create %s", filename.c_str()); - return; + errh->message("would create %s", filename.c_str()); + return; } if (verbose) - errh->message("creating %s", filename.c_str()); - FILE *f = fopen(filename.c_str(), "wb"); + errh->message("creating %s", filename.c_str()); + FILE *f = fopen(filename.c_str(), "w"); if (!f) { - errh->error("%s: %s", filename.c_str(), strerror(errno)); - return; + errh->error("%s: %s", filename.c_str(), strerror(errno)); + return; } // XXX check DESIGNSIZE and DESIGNUNITS for correctness @@ -598,139 +598,139 @@ output_pl(Metrics &metrics, const String // calculate a TeX FAMILY name using afm2tfm's algorithm String family_name = String("TeX-") + ps_name; if (family_name.length() > 19) - family_name = family_name.substring(0, 9) + family_name.substring(-10); + family_name = family_name.substring(0, 9) + family_name.substring(-10); fprintf(f, "(FAMILY %s)\n", family_name.c_str()); if (metrics.coding_scheme()) - fprintf(f, "(CODINGSCHEME %.39s)\n", String(metrics.coding_scheme()).c_str()); + fprintf(f, "(CODINGSCHEME %.39s)\n", String(metrics.coding_scheme()).c_str()); int design_units = metrics.design_units(); if (design_size <= 0) - design_size = get_design_size(finfo); + design_size = get_design_size(finfo); max_printed_real = 0; fprintf(f, "(DESIGNSIZE R %.1f)\n" - "(DESIGNUNITS R %d.0)\n" - "(COMMENT DESIGNSIZE (1 em) IS IN POINTS)\n" - "(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/%d)\n" - "(FONTDIMEN\n", design_size, design_units, design_units); + "(DESIGNUNITS R %d.0)\n" + "(COMMENT DESIGNSIZE (1 em) IS IN POINTS)\n" + "(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/%d)\n" + "(FONTDIMEN\n", design_size, design_units, design_units); // figure out font dimensions Transform font_xform; if (extend) - font_xform.scale(extend, 1); + font_xform.scale(extend, 1); if (slant) - font_xform.shear(slant); + font_xform.shear(slant); double bounds[4], width; Printer pr(f, design_units, metrics.units_per_em()); double actual_slant = font_slant(finfo); if (actual_slant) - fprintf(f, " (SLANT R %g)\n", actual_slant); + fprintf(f, " (SLANT R %g)\n", actual_slant); if (char_bounds(bounds, width, finfo, font_xform, ' ')) { - // advance space width by letterspacing, scale by space_factor - double space_width = (width + (vpl ? letterspace : 0)) * space_factor; - pr.print(" (SPACE", space_width); - if (finfo.is_fixed_pitch()) { - // fixed-pitch: no space stretch or shrink - pr.print(" (STRETCH", 0); - pr.print(" (SHRINK", 0); - pr.print(" (EXTRASPACE", space_width); - } else { - pr.print(" (STRETCH", space_width / 2.); - pr.print(" (SHRINK", space_width / 3.); - pr.print(" (EXTRASPACE", space_width / 6.); - } + // advance space width by letterspacing, scale by space_factor + double space_width = (width + (vpl ? letterspace : 0)) * space_factor; + pr.print(" (SPACE", space_width); + if (finfo.is_fixed_pitch()) { + // fixed-pitch: no space stretch or shrink + pr.print(" (STRETCH", 0); + pr.print(" (SHRINK", 0); + pr.print(" (EXTRASPACE", space_width); + } else { + pr.print(" (STRETCH", space_width / 2.); + pr.print(" (SHRINK", space_width / 3.); + pr.print(" (EXTRASPACE", space_width / 6.); + } } double x_height = finfo.x_height(font_xform); if (x_height < finfo.units_per_em()) - pr.print(" (XHEIGHT", x_height); + pr.print(" (XHEIGHT", x_height); pr.print(" (QUAD", finfo.units_per_em()); fprintf(f, " )\n"); if (boundary_char >= 0) - fprintf(f, "(BOUNDARYCHAR D %d)\n", boundary_char); + fprintf(f, "(BOUNDARYCHAR D %d)\n", boundary_char); // figure out font mapping int mapped_font0 = 0; Vector font_mapping; if (vpl) { - int vpl_first_font = (metrics.need_base() ? 0 : 1); - font_mapping.assign(metrics.n_mapped_fonts(), 0); - if (vpl_first_font == 1 && font_mapping.size() == 1) - font_mapping.push_back(0); - // how many times is each font used? - Vector settings; - for (int i = 0; i < 256; i++) - if (metrics.setting(i, settings)) { - int font_number = 0; - for (const Setting *s = settings.begin(); s < settings.end(); s++) - if (s->op == Setting::SHOW) - font_mapping[font_number]++; - else if (s->op == Setting::FONT) - font_number = (int) s->x; - } - // make sure the most-used font is number 0 - mapped_font0 = std::max_element(font_mapping.begin(), font_mapping.end()) - font_mapping.begin(); - // prepare the mapping - for (int i = vpl_first_font; i < font_mapping.size(); i++) - font_mapping[i] = i - vpl_first_font; - font_mapping[mapped_font0] = 0; - font_mapping[vpl_first_font] = mapped_font0 - vpl_first_font; - if (vpl_first_font != 0) - font_mapping[0] = font_mapping.size() - 1; - // write MAPFONT - for (int i = 0; i < metrics.n_mapped_fonts() - vpl_first_font; i++) { - int j = std::find(font_mapping.begin(), font_mapping.end(), i) - font_mapping.begin(); - String name = metrics.mapped_font_name(j); - if (!name) - name = make_base_font_name(font_name); - fprintf(f, "(MAPFONT D %d\n (FONTNAME %s)\n (FONTDSIZE R %.1f)\n )\n", i, name.c_str(), design_size); - } + int vpl_first_font = (metrics.need_base() ? 0 : 1); + font_mapping.assign(metrics.n_mapped_fonts(), 0); + if (vpl_first_font == 1 && font_mapping.size() == 1) + font_mapping.push_back(0); + // how many times is each font used? + Vector settings; + for (int i = 0; i < 256; i++) + if (metrics.setting(i, settings)) { + int font_number = 0; + for (const Setting *s = settings.begin(); s < settings.end(); s++) + if (s->op == Setting::SHOW) + font_mapping[font_number]++; + else if (s->op == Setting::FONT) + font_number = (int) s->x; + } + // make sure the most-used font is number 0 + mapped_font0 = std::max_element(font_mapping.begin(), font_mapping.end()) - font_mapping.begin(); + // prepare the mapping + for (int i = vpl_first_font; i < font_mapping.size(); i++) + font_mapping[i] = i - vpl_first_font; + font_mapping[mapped_font0] = 0; + font_mapping[vpl_first_font] = mapped_font0 - vpl_first_font; + if (vpl_first_font != 0) + font_mapping[0] = font_mapping.size() - 1; + // write MAPFONT + for (int i = 0; i < metrics.n_mapped_fonts() - vpl_first_font; i++) { + int j = std::find(font_mapping.begin(), font_mapping.end(), i) - font_mapping.begin(); + String name = metrics.mapped_font_name(j); + if (!name) + name = make_base_font_name(font_name); + fprintf(f, "(MAPFONT D %d\n (FONTNAME %s)\n (FONTDSIZE R %.1f)\n )\n", i, name.c_str(), design_size); + } } else - for (int i = 0; i < metrics.n_mapped_fonts(); i++) - font_mapping.push_back(i); + for (int i = 0; i < metrics.n_mapped_fonts(); i++) + font_mapping.push_back(i); // figure out the proper names and numbers for glyphs Vector glyph_ids; Vector glyph_comments(257, String()); Vector glyph_base_comments(257, String()); for (int i = 0; i < metrics.encoding_size(); i++) { - if (metrics.glyph(i)) { - PermString name = metrics.code_name(i), expected_name; - if (i >= '0' && i <= '9') - expected_name = digit_names[i - '0']; - else if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z')) - expected_name = PermString((char)i); - String glyph_comment; - if (name != expected_name) - glyph_comment = " (COMMENT " + String(name) + ")"; - - int base = metrics.base_code(i); - if (base >= 0 && base < 256) - glyph_base_comments[base] = glyph_comment; + if (metrics.glyph(i)) { + PermString name = metrics.code_name(i), expected_name; + if (i >= '0' && i <= '9') + expected_name = digit_names[i - '0']; + else if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z')) + expected_name = PermString((char)i); + String glyph_comment; + if (name != expected_name) + glyph_comment = " (COMMENT " + String(name) + ")"; + + int base = metrics.base_code(i); + if (base >= 0 && base < 256) + glyph_base_comments[base] = glyph_comment; - if (i >= 256) - continue; + if (i >= 256) + continue; char* expected_name_end; - if (expected_name + if (expected_name && (name == expected_name || (name.length() == 7 && memcmp(name.data(), "uni00", 5) == 0 && strtol(name.c_str() + 3, &expected_name_end, 16) == i && *expected_name_end == 0))) - glyph_ids.push_back("C " + String((char)i)); - else - glyph_ids.push_back("D " + String(i)); + glyph_ids.push_back("C " + String((char)i)); + else + glyph_ids.push_back("D " + String(i)); - glyph_comments[i] = glyph_base_comments[i] = glyph_comment; + glyph_comments[i] = glyph_base_comments[i] = glyph_comment; - } else if (i < 256) - glyph_ids.push_back("D " + String(i)); + } else if (i < 256) + glyph_ids.push_back("D " + String(i)); } // finally, BOUNDARYCHAR glyph_ids.push_back("BOUNDARYCHAR"); @@ -741,38 +741,50 @@ output_pl(Metrics &metrics, const String // don't print KRN x after printing LIG x uint32_t used[8]; bool any_ligs = false; + StringAccum omitted_clig_sa; for (int i = 0; i <= 256; i++) - if (metrics.glyph(i) && minimum_kern < 10000) { - int any_lig = metrics.ligatures(i, lig_code2, lig_outcode, lig_context); - int any_kern = metrics.kerns(i, kern_code2, kern_amt); - if (any_lig || any_kern) { - StringAccum kern_sa; - memset(&used[0], 0, 32); - for (int j = 0; j < lig_code2.size(); j++) { - kern_sa << " (" << lig_context_str(lig_context[j]) - << ' ' << glyph_ids[lig_code2[j]] - << ' ' << glyph_ids[lig_outcode[j]] - << ')' << glyph_comments[lig_code2[j]] - << glyph_comments[lig_outcode[j]] << '\n'; - used[lig_code2[j] >> 5] |= (1 << (lig_code2[j] & 0x1F)); - } - for (Vector::const_iterator k2 = kern_code2.begin(); k2 < kern_code2.end(); k2++) - if (!(used[*k2 >> 5] & (1 << (*k2 & 0x1F)))) { - double this_kern = kern_amt[k2 - kern_code2.begin()]; - if (fabs(this_kern) >= minimum_kern) - kern_sa << " (KRN " << glyph_ids[*k2] - << " R " << pr.render(this_kern) - << ')' << glyph_comments[*k2] << '\n'; - } - if (kern_sa) { - if (any_ligs) - fprintf(f, "\n"); - fprintf(f, " (LABEL %s)%s\n%s (STOP)\n", glyph_ids[i].c_str(), glyph_comments[i].c_str(), kern_sa.c_str()); - any_ligs = true; - } - } - } + if (metrics.glyph(i) && minimum_kern < 10000) { + int any_lig = metrics.ligatures(i, lig_code2, lig_outcode, lig_context); + int any_kern = metrics.kerns(i, kern_code2, kern_amt); + if (any_lig || any_kern) { + StringAccum kern_sa; + memset(used, 0, sizeof(used)); + for (int j = 0; j < lig_code2.size(); j++) { + if (lig_outcode[j] < 257) { + kern_sa << " (" << lig_context_str(lig_context[j]) + << ' ' << glyph_ids[lig_code2[j]] + << ' ' << glyph_ids[lig_outcode[j]] + << ')' << glyph_comments[lig_code2[j]] + << glyph_comments[lig_outcode[j]] << '\n'; + used[lig_code2[j] >> 5] |= (1 << (lig_code2[j] & 0x1F)); + } else { + omitted_clig_sa << "(COMMENT omitted " + << lig_context_str(lig_context[j]) + << ' ' << metrics.code_name(i) + << ' ' << metrics.code_name(lig_code2[j]) + << ' ' << metrics.code_name(lig_outcode[j]) + << ")\n"; + } + } + for (Vector::const_iterator k2 = kern_code2.begin(); k2 < kern_code2.end(); k2++) + if (!(used[*k2 >> 5] & (1 << (*k2 & 0x1F)))) { + double this_kern = kern_amt[k2 - kern_code2.begin()]; + if (fabs(this_kern) >= minimum_kern) + kern_sa << " (KRN " << glyph_ids[*k2] + << " R " << pr.render(this_kern) + << ')' << glyph_comments[*k2] << '\n'; + } + if (kern_sa) { + if (any_ligs) + fprintf(f, "\n"); + fprintf(f, " (LABEL %s)%s\n%s (STOP)\n", glyph_ids[i].c_str(), glyph_comments[i].c_str(), kern_sa.c_str()); + any_ligs = true; + } + } + } fprintf(f, " )\n"); + if (omitted_clig_sa) + fprintf(f, "%s\n", omitted_clig_sa.c_str()); // CHARACTERs Vector settings; @@ -780,121 +792,121 @@ output_pl(Metrics &metrics, const String Vector push_stack; for (int i = 0; i < 256; i++) - if (metrics.setting(i, settings)) { - fprintf(f, "(CHARACTER %s%s\n", glyph_ids[i].c_str(), glyph_comments[i].c_str()); + if (metrics.setting(i, settings)) { + fprintf(f, "(CHARACTER %s%s\n", glyph_ids[i].c_str(), glyph_comments[i].c_str()); - // unparse settings into DVI commands - sa.clear(); - push_stack.clear(); - CharstringBounds boundser(font_xform); - int program_number = mapped_font0; - const CharstringProgram *program = finfo.program(); - for (const Setting *s = settings.begin(); s < settings.end(); s++) - switch (s->op) { - - case Setting::SHOW: - if (vpl || program == finfo.program()) - boundser.char_bounds(program->glyph_context(s->y)); - // 3.Aug.2004 -- reported by Marco Kuhlmann: Don't use - // glyph_ids[] array when looking at a different font. - if (program_number == 0) - sa << " (SETCHAR " << glyph_ids[s->x] << ')' << glyph_base_comments[s->x] << "\n"; - else - sa << " (SETCHAR D " << s->x << ")\n"; - break; - - case Setting::MOVE: { - int x = 0, y = 0; - while (s+1 < settings.end() && s[1].op == Setting::MOVE) - x += s->x, y += s->y, s++; - if (vpl) - boundser.translate(s->x + x, s->y + y); - if (s->x + x) - sa << " (MOVERIGHT R " << pr.render(s->x + x) << ")\n"; - if (s->y + y) - sa << " (MOVEUP R " << pr.render(s->y + y) << ")\n"; - break; - } - - case Setting::RULE: - if (vpl) { - boundser.mark(Point(0, 0)); - boundser.mark(Point(s->x, s->y)); - boundser.translate(s->x, 0); - } - sa << " (SETRULE R " << pr.render(s->y) << " R " << pr.render(s->x) << ")\n"; - break; - - case Setting::FONT: - if ((int) s->x != program_number) { - program = metrics.mapped_font((int) s->x); - program_number = (int) s->x; - sa << " (SELECTFONT D " << font_mapping[program_number] << ")\n"; - } - break; - - case Setting::PUSH: - push_stack.push_back(boundser.transform(Point(0, 0))); - sa << " (PUSH)\n"; - break; - - case Setting::POP: { - assert(push_stack.size()); - Point p = push_stack.back() - boundser.transform(Point(0, 0)); - if (vpl) - boundser.translate(p.x, p.y); - push_stack.pop_back(); - sa << " (POP)\n"; - break; - } - - case Setting::SPECIAL: { - bool needhex = false; - for (const char *str = s->s.begin(); str < s->s.end() && !needhex; str++) - if (*str < ' ' || *str > '~' || *str == '(' || *str == ')') - needhex = true; - if (needhex) { - sa << " (SPECIALHEX "; - for (const char *str = s->s.begin(); str < s->s.end(); str++) { - static const char hexdig[] = "0123456789ABCDEF"; - int val = (unsigned char) *str; - sa << hexdig[val >> 4] << hexdig[val & 0xF]; - } - sa << ")\n"; - } else - sa << " (SPECIAL " << s->s << ")\n"; - break; - } - - } - - assert(push_stack.size() == 0); - - // output information - boundser.output(bounds, width); - pr.print(" (CHARWD", width); - if (bounds[3] > 0) - pr.print(" (CHARHT", bounds[3]); - if (bounds[1] < 0) - pr.print(" (CHARDP", -bounds[1]); - if (bounds[2] > width) - pr.print_transformed(" (CHARIC", pr.transform(bounds[2]) - pr.transform(width)); - if (vpl && (settings.size() > 1 || settings[0].op != Setting::SHOW)) - fprintf(f, " (MAP\n%s )\n", sa.c_str()); - fprintf(f, " )\n"); - } + // unparse settings into DVI commands + sa.clear(); + push_stack.clear(); + CharstringBounds boundser(font_xform); + int program_number = mapped_font0; + const CharstringProgram *program = finfo.program(); + for (const Setting *s = settings.begin(); s < settings.end(); s++) + switch (s->op) { + + case Setting::SHOW: + if (vpl || program == finfo.program()) + boundser.char_bounds(program->glyph_context(s->y)); + // 3.Aug.2004 -- reported by Marco Kuhlmann: Don't use + // glyph_ids[] array when looking at a different font. + if (program_number == 0) + sa << " (SETCHAR " << glyph_ids[s->x] << ')' << glyph_base_comments[s->x] << "\n"; + else + sa << " (SETCHAR D " << s->x << ")\n"; + break; + + case Setting::MOVE: { + int x = 0, y = 0; + while (s+1 < settings.end() && s[1].op == Setting::MOVE) + x += s->x, y += s->y, s++; + if (vpl) + boundser.translate(s->x + x, s->y + y); + if (s->x + x) + sa << " (MOVERIGHT R " << pr.render(s->x + x) << ")\n"; + if (s->y + y) + sa << " (MOVEUP R " << pr.render(s->y + y) << ")\n"; + break; + } + + case Setting::RULE: + if (vpl) { + boundser.mark(Point(0, 0)); + boundser.mark(Point(s->x, s->y)); + boundser.translate(s->x, 0); + } + sa << " (SETRULE R " << pr.render(s->y) << " R " << pr.render(s->x) << ")\n"; + break; + + case Setting::FONT: + if ((int) s->x != program_number) { + program = metrics.mapped_font((int) s->x); + program_number = (int) s->x; + sa << " (SELECTFONT D " << font_mapping[program_number] << ")\n"; + } + break; + + case Setting::PUSH: + push_stack.push_back(boundser.transform(Point(0, 0))); + sa << " (PUSH)\n"; + break; + + case Setting::POP: { + assert(push_stack.size()); + Point p = push_stack.back() - boundser.transform(Point(0, 0)); + if (vpl) + boundser.translate(p.x, p.y); + push_stack.pop_back(); + sa << " (POP)\n"; + break; + } + + case Setting::SPECIAL: { + bool needhex = false; + for (const char *str = s->s.begin(); str < s->s.end() && !needhex; str++) + if (*str < ' ' || *str > '~' || *str == '(' || *str == ')') + needhex = true; + if (needhex) { + sa << " (SPECIALHEX "; + for (const char *str = s->s.begin(); str < s->s.end(); str++) { + static const char hexdig[] = "0123456789ABCDEF"; + int val = (unsigned char) *str; + sa << hexdig[val >> 4] << hexdig[val & 0xF]; + } + sa << ")\n"; + } else + sa << " (SPECIAL " << s->s << ")\n"; + break; + } + + } + + assert(push_stack.size() == 0); + + // output information + boundser.output(bounds, width); + pr.print(" (CHARWD", width); + if (bounds[3] > 0) + pr.print(" (CHARHT", bounds[3]); + if (bounds[1] < 0) + pr.print(" (CHARDP", -bounds[1]); + if (bounds[2] > width) + pr.print_transformed(" (CHARIC", pr.transform(bounds[2]) - pr.transform(width)); + if (vpl && (settings.size() > 1 || settings[0].op != Setting::SHOW)) + fprintf(f, " (MAP\n%s )\n", sa.c_str()); + fprintf(f, " )\n"); + } // at last, close the file fclose(f); // Did we print a number too big for TeX to handle? If so, try again. if (max_printed_real >= 2047) { - if (metrics.design_units() <= 1) - errh->fatal("This font appears to be broken. It has characters so big that the PL format\ncannot represent them."); - metrics.set_design_units(metrics.design_units() > 200 ? metrics.design_units() - 250 : 1); - if (verbose) - errh->message("the font%,s metrics overflow the limits of PL files\n(reducing DESIGNUNITS to %d and trying again)", metrics.design_units()); - output_pl(metrics, ps_name, boundary_char, finfo, vpl, filename, errh); + if (metrics.design_units() <= 1) + errh->fatal("This font appears to be broken. It has characters so big that the PL format\ncannot represent them."); + metrics.set_design_units(metrics.design_units() > 200 ? metrics.design_units() - 250 : 1); + if (verbose) + errh->message("the font%,s metrics overflow the limits of PL files\n(reducing DESIGNUNITS to %d and trying again)", metrics.design_units()); + output_pl(metrics, ps_name, boundary_char, finfo, vpl, filename, errh); } } @@ -903,7 +915,7 @@ struct Lookup { bool required; Vector features; GlyphFilter* filter; - Lookup() : used(false), required(false), filter(0) { } + Lookup() : used(false), required(false), filter(0) { } }; static void @@ -914,81 +926,81 @@ find_lookups(const OpenType::ScriptList& // go over all scripts for (int i = 0; i < interesting_scripts.size(); i += 2) { - OpenType::Tag script = interesting_scripts[i]; - OpenType::Tag langsys = interesting_scripts[i+1]; + OpenType::Tag script = interesting_scripts[i]; + OpenType::Tag langsys = interesting_scripts[i+1]; - // collect features applying to this script - scripts.features(script, langsys, required, fids, errh); + // collect features applying to this script + scripts.features(script, langsys, required, fids, errh); - // only use the selected features - features.filter(fids, interesting_features); + // only use the selected features + features.filter(fids, interesting_features); - // mark features as having been used - for (int j = (required < 0 ? 0 : -1); j < fids.size(); j++) { - int fid = (j < 0 ? required : fids[j]); - OpenType::Tag ftag = features.tag(fid); - if (features.lookups(fid, lookupids, errh) < 0) - lookupids.clear(); - for (int k = 0; k < lookupids.size(); k++) { - int l = lookupids[k]; - if (l < 0 || l >= lookups.size()) - errh->error("lookup for %<%s%> feature out of range", OpenType::Tag::langsys_text(script, langsys).c_str()); - else { - lookups[l].used = true; - lookups[l].features.push_back(ftag); - if (j < 0) - lookups[l].required = true; - } - } - } + // mark features as having been used + for (int j = (required < 0 ? 0 : -1); j < fids.size(); j++) { + int fid = (j < 0 ? required : fids[j]); + OpenType::Tag ftag = features.tag(fid); + if (features.lookups(fid, lookupids, errh) < 0) + lookupids.clear(); + for (int k = 0; k < lookupids.size(); k++) { + int l = lookupids[k]; + if (l < 0 || l >= lookups.size()) + errh->error("lookup for %<%s%> feature out of range", OpenType::Tag::langsys_text(script, langsys).c_str()); + else { + lookups[l].used = true; + lookups[l].features.push_back(ftag); + if (j < 0) + lookups[l].required = true; + } + } + } } // now check for compatible glyph filters for (Lookup* l = lookups.begin(); l < lookups.end(); l++) - if (l->used && !l->required) { - l->filter = feature_filters[l->features[0]]; - for (OpenType::Tag* ft = l->features.begin() + 1; ft < l->features.end(); ft++) - if (!l->filter->check_eq(*feature_filters[*ft])) { - errh->error("%<%s%> and %<%s%> features share a lookup, but have different filters", l->features[0].text().c_str(), ft->text().c_str()); - break; - } - } + if (l->used && !l->required) { + l->filter = feature_filters[l->features[0]]; + for (OpenType::Tag* ft = l->features.begin() + 1; ft < l->features.end(); ft++) + if (!l->filter->check_eq(*feature_filters[*ft])) { + errh->error("%<%s%> and %<%s%> features share a lookup, but have different filters", l->features[0].text().c_str(), ft->text().c_str()); + break; + } + } } static int write_encoding_file(String &filename, const String &encoding_name, - StringAccum &contents, ErrorHandler *errh) + StringAccum &contents, ErrorHandler *errh) { FILE *f; int ok_retval = (access(filename.c_str(), R_OK) >= 0 ? 0 : 1); if (no_create) { - errh->message((ok_retval ? "would create encoding file %s" : "would update encoding file %s"), filename.c_str()); - return ok_retval; + errh->message((ok_retval ? "would create encoding file %s" : "would update encoding file %s"), filename.c_str()); + return ok_retval; } else if (verbose) - errh->message((ok_retval ? "creating encoding file %s" : "updating encoding file %s"), filename.c_str()); + errh->message((ok_retval ? "creating encoding file %s" : "updating encoding file %s"), filename.c_str()); int fd = open(filename.c_str(), O_RDWR | O_CREAT, 0666); if (fd < 0) - return errh->error("%s: %s", filename.c_str(), strerror(errno)); + return errh->error("%s: %s", filename.c_str(), strerror(errno)); f = fdopen(fd, "r+"); // NB: also change update_autofont_map if you change this code #if defined(F_SETLKW) && defined(HAVE_FTRUNCATE) { - struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - int result; - while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) - /* try again */; - if (result < 0) { - result = errno; - fclose(f); - return errh->error("locking %s: %s", filename.c_str(), strerror(result)); - } + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + int result; + while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) + /* try again */; + if (result < 0) { + result = errno; + fclose(f); + return errh->error("locking %s: %s", filename.c_str(), strerror(result)); + } } #endif @@ -996,32 +1008,32 @@ write_encoding_file(String &filename, co StringAccum sa; int amt; do { - if (char *x = sa.reserve(8192)) { - amt = fread(x, 1, 8192, f); - sa.adjust_length(amt); - } else - amt = 0; + if (char *x = sa.reserve(8192)) { + amt = fread(x, 1, 8192, f); + sa.adjust_length(amt); + } else + amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) - return errh->error("%s: %s", filename.c_str(), strerror(errno)); + return errh->error("%s: %s", filename.c_str(), strerror(errno)); String old_encodings = sa.take_string(); bool created = (!old_encodings); // append old encodings int pos1 = old_encodings.find_left("\n%%"); while (pos1 >= 0 && pos1 < old_encodings.length()) { - int pos2 = old_encodings.find_left("\n%%", pos1 + 1); - if (pos2 < 0) - pos2 = old_encodings.length(); - if (old_encodings.substring(pos1 + 3, encoding_name.length()) == encoding_name) { - // encoding already exists, don't change it - fclose(f); - if (verbose) - errh->message("%s unchanged", filename.c_str()); - return 0; - } else - contents << old_encodings.substring(pos1, pos2 - pos1); - pos1 = pos2; + int pos2 = old_encodings.find_left("\n%%", pos1 + 1); + if (pos2 < 0) + pos2 = old_encodings.length(); + if (old_encodings.substring(pos1 + 3, encoding_name.length()) == encoding_name) { + // encoding already exists, don't change it + fclose(f); + if (verbose) + errh->message("%s unchanged", filename.c_str()); + return 0; + } else + contents << old_encodings.substring(pos1, pos2 - pos1); + pos1 = pos2; } // rewind file @@ -1030,9 +1042,9 @@ write_encoding_file(String &filename, co if (ftruncate(fd, 0) < 0) #endif { - fclose(f); - f = fopen(filename.c_str(), "wb"); - fd = fileno(f); + fclose(f); + f = fopen(filename.c_str(), "w"); + fd = fileno(f); } ignore_result(fwrite(contents.data(), 1, contents.length(), f)); @@ -1041,33 +1053,33 @@ write_encoding_file(String &filename, co // inform about the new file if necessary if (created) - update_odir(O_ENCODING, filename, errh); + update_odir(O_ENCODING, filename, errh); return 0; } static bool output_encoding(const Metrics &metrics, - const Vector &glyph_names, - ErrorHandler *errh) + const Vector &glyph_names, + ErrorHandler *errh) { static const char * const hex_digits = "0123456789ABCDEF"; // collect encoding data Vector glyphs; if (!metrics.base_glyphs(glyphs, 256)) - return false; + return false; StringAccum sa; for (int i = 0; i < 256; i++) { - if ((i & 0xF) == 0) - sa << (i ? "\n%" : "%") << hex_digits[(i >> 4) & 0xF] << '0' << '\n' << ' '; - else if ((i & 0x7) == 0) - sa << '\n' << ' '; - int g = glyphs[i]; - if (g > 0 && g < glyph_names.size()) - sa << ' ' << '/' << glyph_names[g]; - else - sa << " /.notdef"; + if ((i & 0xF) == 0) + sa << (i ? "\n%" : "%") << hex_digits[(i >> 4) & 0xF] << '0' << '\n' << ' '; + else if ((i & 0x7) == 0) + sa << '\n' << ' '; + int g = glyphs[i]; + if (g > 0 && g < glyph_names.size()) + sa << ' ' << '/' << glyph_names[g]; + else + sa << " /.notdef"; } sa << '\n'; @@ -1084,18 +1096,18 @@ output_encoding(const Metrics &metrics, // create encoding filename bool output_encoding_only = (bool) out_encoding_file; if (!out_encoding_file) - out_encoding_file = getodir(O_ENCODING, errh) + String("/a_") + String(text_digest).substring(0, 6) + ".enc"; + out_encoding_file = getodir(O_ENCODING, errh) + String("/a_") + String(text_digest).substring(0, 6) + ".enc"; // exit if we're not responsible for generating an encoding if (!(output_flags & G_ENCODING)) - return true; + return true; // put encoding block in a StringAccum // 3.Jun.2003: stick command line definition at the end of the encoding, // where it won't confuse idiotic ps2pk StringAccum contents; if (!output_encoding_only) - contents << "% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT\n\n\ + contents << "% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT\n\n\ %%" << out_encoding_name << "\n"; contents << "% Encoding created by otftotfm" << current_time << "\n\ % Command line follows encoding\n"; @@ -1108,156 +1120,199 @@ output_encoding(const Metrics &metrics, char *buf = banner.mutable_data(); // get rid of crap characters for (int i = 0; i < banner.length(); i++) - if (buf[i] < ' ' || buf[i] > 0176) { - if (buf[i] == '\n' || buf[i] == '\r') - buf[i] = ' '; - else - buf[i] = '.'; - } + if (buf[i] < ' ' || buf[i] > 0176) { + if (buf[i] == '\n' || buf[i] == '\r') + buf[i] = ' '; + else + buf[i] = '.'; + } // break lines at 80 characters -- it would be nice if this were in a // library while (banner.length() > 0) { - int pos = banner.find_left(' '), last_pos = pos; - while (pos < 75 && pos >= 0) { - last_pos = pos; - pos = banner.find_left(' ', pos + 1); - } - if (last_pos < 0 || (pos < 0 && banner.length() < 75)) - last_pos = banner.length(); - contents << "% " << banner.substring(0, last_pos) << '\n'; - banner = banner.substring(last_pos + 1); + int pos = banner.find_left(' '), last_pos = pos; + while (pos < 75 && pos >= 0) { + last_pos = pos; + pos = banner.find_left(' ', pos + 1); + } + if (last_pos < 0 || (pos < 0 && banner.length() < 75)) + last_pos = banner.length(); + contents << "% " << banner.substring(0, last_pos) << '\n'; + banner = banner.substring(last_pos + 1); } // open encoding file if (out_encoding_file == "-") - ignore_result(fwrite(contents.data(), 1, contents.length(), stdout)); + ignore_result(fwrite(contents.data(), 1, contents.length(), stdout)); else if (write_encoding_file(out_encoding_file, out_encoding_name, contents, errh) == 1) - update_odir(O_ENCODING, out_encoding_file, errh); + update_odir(O_ENCODING, out_encoding_file, errh); return true; } static void output_tfm(Metrics &metrics, const String &ps_name, int boundary_char, - const FontInfo &finfo, String tfm_filename, String vf_filename, - ErrorHandler *errh) + const FontInfo &finfo, String tfm_filename, String vf_filename, + String pl_filename, ErrorHandler *errh) { - String pl_filename; + bool had_pl_filename = !pl_filename.empty(); bool vpl = vf_filename; - if (no_create) { - errh->message("would write %s to temporary file", (vpl ? "VPL" : "PL")); - pl_filename = ""; - } else { - int pl_fd = temporary_file(pl_filename, errh); - if (pl_fd < 0) - return; - output_pl(metrics, ps_name, boundary_char, finfo, vpl, pl_filename, errh); - close(pl_fd); + if (!pl_filename) { + if (no_create) { + errh->message("would write %s to temporary file", (vpl ? "VPL" : "PL")); + pl_filename = ""; + } else { + int pl_fd = temporary_file(pl_filename, errh); + if (pl_fd < 0) + return; + output_pl(metrics, ps_name, boundary_char, finfo, vpl, pl_filename, errh); + close(pl_fd); + } } StringAccum command; if (vpl) - command << "vptovf " << shell_quote(pl_filename) << ' ' << shell_quote(vf_filename) << ' ' << shell_quote(tfm_filename) << " >&2"; + command << "vptovf " << shell_quote(pl_filename) << ' ' << shell_quote(vf_filename) << ' ' << shell_quote(tfm_filename) << " 2>&1"; else - command << "pltotf " << shell_quote(pl_filename) << ' ' << shell_quote(tfm_filename) << " >&2"; + command << "pltotf " << shell_quote(pl_filename) << ' ' << shell_quote(tfm_filename) << " 2>&1"; - int status = mysystem(command.c_str(), errh); + FILE* cmdfile = mypopen(command.c_str(), "r", errh); + int status; + if (cmdfile) { + StringAccum results; + while (!feof(cmdfile)) { + char* buf = results.reserve(BUFSIZ); + results.adjust_length(fread(buf, 1, BUFSIZ, cmdfile)); + } + // compensate for shitty vptovf/pltotf messages + char* by_units, *last_line; + while (!results.empty() + && (by_units = strstr((char*) results.c_str(), " units")) + && (last_line = strrchr((char*) results.c_str(), '\n')) + && results.end() - last_line > 1 + && isdigit((unsigned char) last_line[1])) { + char* start_number = last_line + 1; + char* end_number = last_line + 2; + while (end_number < results.end() + && isdigit((unsigned char) *end_number)) + ++end_number; + if (end_number < results.end() && *end_number == '.') { + char* dot = end_number; + ++end_number; + while (end_number < results.end() + && end_number < dot + 8 + && isdigit((unsigned char) *end_number)) + ++end_number; + } + String number(start_number, end_number); + char* by_units_dest = by_units + 1 + (end_number - start_number); + memmove(by_units_dest, by_units + 1, start_number - (by_units + 1)); + memmove(by_units + 1, number.begin(), number.length()); + } + if (!results.empty()) + fwrite(results.begin(), 1, results.length(), stderr); + status = pclose(cmdfile); + } else + status = -1; - if (!no_create) - unlink(pl_filename.c_str()); + if (!no_create && !had_pl_filename) + unlink(pl_filename.c_str()); if (status != 0) - errh->fatal("%s execution failed", (vpl ? "vptovf" : "pltotf")); + errh->fatal("%s execution failed", (vpl ? "vptovf" : "pltotf")); else { - update_odir(O_TFM, tfm_filename, errh); - if (vpl) - update_odir(O_VF, vf_filename, errh); + update_odir(O_TFM, tfm_filename, errh); + if (vpl) + update_odir(O_VF, vf_filename, errh); } } void output_metrics(Metrics &metrics, const String &ps_name, int boundary_char, - const FontInfo &finfo, - const String &encoding_name, const String &encoding_file, - const String &font_name, - String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), - ErrorHandler *errh) + const FontInfo &finfo, + const String &encoding_name, const String &encoding_file, + const String &font_name, + String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), + ErrorHandler *errh) { String base_font_name = font_name; bool need_virtual = metrics.need_virtual(257); if (need_virtual) { - if (output_flags & G_VMETRICS) - base_font_name = make_base_font_name(font_name); - else if (output_flags & G_METRICS) - errh->warning("features require virtual fonts"); + if (output_flags & G_VMETRICS) + base_font_name = make_base_font_name(font_name); + else if (output_flags & G_METRICS) + errh->warning("features require virtual fonts"); } // output virtual metrics if (!(output_flags & G_VMETRICS)) - /* do nothing */; + /* do nothing */; else if (!need_virtual) { - if (automatic) { - // erase old virtual font - String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; - if (no_create) - errh->message("would remove potential VF file %<%s%>", vf.c_str()); - else { - if (verbose) - errh->message("removing potential VF file %<%s%>", vf.c_str()); - if (unlink(vf.c_str()) < 0 && errno != ENOENT) - errh->error("removing %s: %s", vf.c_str(), strerror(errno)); - } - } + if (automatic) { + // erase old virtual font + String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; + if (no_create) + errh->message("would remove potential VF file %<%s%>", vf.c_str()); + else { + if (verbose) + errh->message("removing potential VF file %<%s%>", vf.c_str()); + if (unlink(vf.c_str()) < 0 && errno != ENOENT) + errh->error("removing %s: %s", vf.c_str(), strerror(errno)); + } + } } else { - if (output_flags & G_BINARY) { - String tfm = getodir(O_TFM, errh) + "/" + font_name + ".tfm"; - String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; - output_tfm(metrics, ps_name, boundary_char, finfo, tfm, vf, errh); - } else { - String outfile = getodir(O_VPL, errh) + "/" + font_name + ".vpl"; - output_pl(metrics, ps_name, boundary_char, finfo, true, outfile, errh); - update_odir(O_VPL, outfile, errh); - } + String vplfile; + if (output_flags & G_ASCII) { + vplfile = getodir(O_VPL, errh) + "/" + font_name + ".vpl"; + output_pl(metrics, ps_name, boundary_char, finfo, true, vplfile, errh); + update_odir(O_VPL, vplfile, errh); + } + if (output_flags & G_BINARY) { + String tfm = getodir(O_TFM, errh) + "/" + font_name + ".tfm"; + String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; + output_tfm(metrics, ps_name, boundary_char, finfo, tfm, vf, vplfile, errh); + } } // quit if no base needed metrics.make_base(257); if (!metrics.need_base()) - return; + return; // output metrics double save_minimum_kern = minimum_kern; if (need_virtual) - minimum_kern = 100000; - if (!(output_flags & G_METRICS)) - /* do nothing */; - else if (output_flags & G_BINARY) { - String tfm = getodir(O_TFM, errh) + "/" + base_font_name + ".tfm"; - output_tfm(metrics, ps_name, boundary_char, finfo, tfm, String(), errh); - } else { - String outfile = getodir(O_PL, errh) + "/" + base_font_name + ".pl"; - output_pl(metrics, ps_name, boundary_char, finfo, false, outfile, errh); - update_odir(O_PL, outfile, errh); + minimum_kern = 100000; + if (output_flags & G_METRICS) { + String plfile; + if (output_flags & G_ASCII) { + plfile = getodir(O_PL, errh) + "/" + base_font_name + ".pl"; + output_pl(metrics, ps_name, boundary_char, finfo, false, plfile, errh); + update_odir(O_PL, plfile, errh); + } + if (output_flags & G_BINARY) { + String tfm = getodir(O_TFM, errh) + "/" + base_font_name + ".tfm"; + output_tfm(metrics, ps_name, boundary_char, finfo, tfm, String(), plfile, errh); + } } minimum_kern = save_minimum_kern; // print DVIPS map line if (errh->nerrors() == 0 && (output_flags & G_PSFONTSMAP)) { - StringAccum sa; - sa << base_font_name << ' ' << ps_name << " \""; - if (extend) - sa << extend << " ExtendFont "; - if (slant) - sa << slant << " SlantFont "; - if (encoding_name) - sa << encoding_name << " ReEncodeFont\" <[" << pathname_filename(encoding_file); - else - sa << "\""; - sa << ' ' << dvips_include(ps_name, finfo, errh) << '\n'; - update_autofont_map(base_font_name, sa.take_string(), errh); - // if virtual font, remove any map line for base font name - if (base_font_name != font_name) - update_autofont_map(font_name, "", errh); + StringAccum sa; + sa << base_font_name << ' ' << ps_name << " \""; + if (extend) + sa << extend << " ExtendFont "; + if (slant) + sa << slant << " SlantFont "; + if (encoding_name) + sa << encoding_name << " ReEncodeFont\" <[" << pathname_filename(encoding_file); + else + sa << "\""; + sa << ' ' << dvips_include(ps_name, finfo, errh) << '\n'; + update_autofont_map(base_font_name, sa.take_string(), errh); + // if virtual font, remove any map line for base font name + if (base_font_name != font_name) + update_autofont_map(font_name, "", errh); } } @@ -1281,48 +1336,48 @@ report_underused_features(const HashMap< { Vector x[X_COUNT]; for (int i = 0; i < interesting_features.size(); i++) { - OpenType::Tag f = interesting_features[i]; - int fu = feature_usage[f.value()]; - String ftext = errh->format("%<%s%>", f.text().c_str()); - if (fu == 0) - x[X_UNUSED].push_back(ftext); - else if ((fu & (F_GSUB_TRY | F_GPOS_TRY)) == fu) - x[X_BOTH_NONE].push_back(ftext); - else { - if (fu & F_GSUB_TRY) { - if ((fu & (F_GSUB_PART | F_GSUB_ALL)) == 0) - x[X_GSUB_NONE].push_back(ftext); - else if (fu & F_GSUB_PART) - x[X_GSUB_PART].push_back(ftext); - } - if (fu & F_GPOS_TRY) { - if ((fu & (F_GPOS_PART | F_GPOS_ALL)) == 0) - x[X_GPOS_NONE].push_back(ftext); - else if (fu & F_GPOS_PART) - x[X_GPOS_PART].push_back(ftext); - } - } + OpenType::Tag f = interesting_features[i]; + int fu = feature_usage[f.value()]; + String ftext = errh->format("%<%s%>", f.text().c_str()); + if (fu == 0) + x[X_UNUSED].push_back(ftext); + else if ((fu & (F_GSUB_TRY | F_GPOS_TRY)) == fu) + x[X_BOTH_NONE].push_back(ftext); + else { + if (fu & F_GSUB_TRY) { + if ((fu & (F_GSUB_PART | F_GSUB_ALL)) == 0) + x[X_GSUB_NONE].push_back(ftext); + else if (fu & F_GSUB_PART) + x[X_GSUB_PART].push_back(ftext); + } + if (fu & F_GPOS_TRY) { + if ((fu & (F_GPOS_PART | F_GPOS_ALL)) == 0) + x[X_GPOS_NONE].push_back(ftext); + else if (fu & F_GPOS_PART) + x[X_GPOS_PART].push_back(ftext); + } + } } for (int i = 0; i < X_COUNT; i++) - if (x[i].size()) - goto found; + if (x[i].size()) + goto found; return; found: for (int i = 0; i < X_COUNT; i++) - if (x[i].size()) { - StringAccum sa; - const char* msg_pct = strchr(x_messages[i], '%'); - sa.append(x_messages[i], msg_pct - x_messages[i]); - const char* sep = (x[i].size() > 2 ? ", " : " "); - for (const String* a = x[i].begin(); a < x[i].end() - 1; a++) - sa << *a << sep; - sa << (x[i].size() > 1 ? "and " : "") << x[i].back() - << (x[i].size() > 1 ? " features" : " feature") << (msg_pct+1); - sa.append_break_lines(sa.take_string(), 58); - errh->warning("%s", sa.c_str()); - } + if (x[i].size()) { + StringAccum sa; + const char* msg_pct = strchr(x_messages[i], '%'); + sa.append(x_messages[i], msg_pct - x_messages[i]); + const char* sep = (x[i].size() > 2 ? ", " : " "); + for (const String* a = x[i].begin(); a < x[i].end() - 1; a++) + sa << *a << sep; + sa << (x[i].size() > 1 ? "and " : "") << x[i].back() + << (x[i].size() > 1 ? " features" : " feature") << (msg_pct+1); + sa.append_break_lines(sa.take_string(), 58); + errh->warning("%s", sa.c_str()); + } } static String otf_filename; @@ -1331,24 +1386,24 @@ static String main_dvips_map(const String &ps_name, const FontInfo &finfo, ErrorHandler *errh) { if (String fn = installed_type1(otf_filename, ps_name, (output_flags & G_TYPE1) != 0, errh)) - return "<" + pathname_filename(fn); + return "<" + pathname_filename(fn); if (!finfo.cff) { - String ttf_fn, t42_fn; - ttf_fn = installed_truetype(otf_filename, (output_flags & G_TRUETYPE) != 0, errh); - t42_fn = installed_type42(otf_filename, ps_name, (output_flags & G_TYPE42) != 0, errh); - if (t42_fn && (!ttf_fn || (output_flags & G_TYPE42) != 0)) - return "<" + pathname_filename(t42_fn); - else if (ttf_fn) - return "<" + pathname_filename(ttf_fn); + String ttf_fn, t42_fn; + ttf_fn = installed_truetype(otf_filename, (output_flags & G_TRUETYPE) != 0, errh); + t42_fn = installed_type42(otf_filename, ps_name, (output_flags & G_TYPE42) != 0, errh); + if (t42_fn && (!ttf_fn || (output_flags & G_TYPE42) != 0)) + return "<" + pathname_filename(t42_fn); + else if (ttf_fn) + return "<" + pathname_filename(ttf_fn); } return "<" + pathname_filename(otf_filename); } static void do_gsub(Metrics& metrics, const OpenType::Font& otf, - DvipsEncoding& dvipsenc, bool dvipsenc_literal, - HashMap& feature_usage, - const Vector& glyph_names, ErrorHandler* errh) + DvipsEncoding& dvipsenc, bool dvipsenc_literal, + HashMap& feature_usage, + const Vector& glyph_names, ErrorHandler* errh) { // find activated GSUB features OpenType::Gsub gsub(otf.table("GSUB"), &otf, errh); @@ -1358,70 +1413,70 @@ do_gsub(Metrics& metrics, const OpenType // find all characters that might result Vector used(glyph_names.size(), false); for (Metrics::Code c = 0; c < metrics.encoding_size(); ++c) { - Metrics::Glyph g = metrics.glyph(c); - if (g >= 0 && g < used.size()) - used[g] = true; + Metrics::Glyph g = metrics.glyph(c); + if (g >= 0 && g < used.size()) + used[g] = true; } for (int i = 0; i < lookups.size(); ++i) - if (lookups[i].used) { - OpenType::GsubLookup l = gsub.lookup(i); - l.mark_out_glyphs(gsub, used); - } + if (lookups[i].used) { + OpenType::GsubLookup l = gsub.lookup(i); + l.mark_out_glyphs(gsub, used); + } OpenType::Coverage used_coverage(used); // apply activated GSUB features Vector subs; for (int i = 0; i < lookups.size(); i++) - if (lookups[i].used) { - OpenType::GsubLookup l = gsub.lookup(i); - subs.clear(); - bool understood = l.unparse_automatics(gsub, subs, used_coverage); - - // check for -ffina, which should apply only at the ends of words, - // and -finit, which should apply only at the beginnings. - OpenType::Tag feature = (lookups[i].features.size() == 1 ? lookups[i].features[0] : OpenType::Tag()); - if (feature == OpenType::Tag("fina") || feature == OpenType::Tag("fin2") || feature == OpenType::Tag("fin3")) { - if (dvipsenc.boundary_char() < 0) - errh->warning("%<-ffina%> requires a boundary character\n(The input encoding didn%,t specify a boundary character, but\nI need one to implement %<-ffina%> features correctly. Try\nthe %<--boundary-char%> option.)"); - else { - int bg = metrics.boundary_glyph(); - for (int j = 0; j < subs.size(); j++) - subs[j].add_outer_right(bg); - } - } else if (feature == OpenType::Tag("init")) { - int bg = metrics.boundary_glyph(); - for (int j = 0; j < subs.size(); j++) - subs[j].add_outer_left(bg); - } - - //for (int subno = 0; subno < subs.size(); subno++) fprintf(stderr, "%5d\t%s\n", i, subs[subno].unparse().c_str()); - - // figure out which glyph filter to use - int nunderstood = metrics.apply(subs, !dvipsenc_literal, i, *lookups[i].filter, glyph_names); - - // mark as used - int d = (understood && nunderstood == subs.size() ? F_GSUB_ALL : (nunderstood ? F_GSUB_PART : 0)) + F_GSUB_TRY; - for (int j = 0; j < lookups[i].features.size(); j++) - feature_usage.find_force(lookups[i].features[j].value()) |= d; - } + if (lookups[i].used) { + OpenType::GsubLookup l = gsub.lookup(i); + subs.clear(); + bool understood = l.unparse_automatics(gsub, subs, used_coverage); + + // check for -ffina, which should apply only at the ends of words, + // and -finit, which should apply only at the beginnings. + OpenType::Tag feature = (lookups[i].features.size() == 1 ? lookups[i].features[0] : OpenType::Tag()); + if (feature == OpenType::Tag("fina") || feature == OpenType::Tag("fin2") || feature == OpenType::Tag("fin3")) { + if (dvipsenc.boundary_char() < 0) + errh->warning("%<-ffina%> requires a boundary character\n(The input encoding didn%,t specify a boundary character, but\nI need one to implement %<-ffina%> features correctly. Try\nthe %<--boundary-char%> option.)"); + else { + int bg = metrics.boundary_glyph(); + for (int j = 0; j < subs.size(); j++) + subs[j].add_outer_right(bg); + } + } else if (feature == OpenType::Tag("init")) { + int bg = metrics.boundary_glyph(); + for (int j = 0; j < subs.size(); j++) + subs[j].add_outer_left(bg); + } + + //for (int subno = 0; subno < subs.size(); subno++) fprintf(stderr, "%5d\t%s\n", i, subs[subno].unparse().c_str()); + + // figure out which glyph filter to use + int nunderstood = metrics.apply(subs, !dvipsenc_literal, i, *lookups[i].filter, glyph_names); + + // mark as used + int d = (understood && nunderstood == subs.size() ? F_GSUB_ALL : (nunderstood ? F_GSUB_PART : 0)) + F_GSUB_TRY; + for (int j = 0; j < lookups[i].features.size(); j++) + feature_usage.find_force(lookups[i].features[j].value()) |= d; + } // apply alternate selectors if (metrics.altselectors() && !dvipsenc_literal) { - // do lookups - altselector_features.swap(interesting_features); - altselector_feature_filters.swap(feature_filters); - Vector alt_lookups(gsub.nlookups(), Lookup()); - find_lookups(gsub.script_list(), gsub.feature_list(), alt_lookups, ErrorHandler::silent_handler()); - Vector alt_subs; - for (int i = 0; i < alt_lookups.size(); i++) - if (alt_lookups[i].used) { - OpenType::GsubLookup l = gsub.lookup(i); - alt_subs.clear(); - (void) l.unparse_automatics(gsub, alt_subs, used_coverage); - metrics.apply_alternates(alt_subs, i, *alt_lookups[i].filter, glyph_names); - } - altselector_features.swap(interesting_features); - altselector_feature_filters.swap(feature_filters); + // do lookups + altselector_features.swap(interesting_features); + altselector_feature_filters.swap(feature_filters); + Vector alt_lookups(gsub.nlookups(), Lookup()); + find_lookups(gsub.script_list(), gsub.feature_list(), alt_lookups, ErrorHandler::silent_handler()); + Vector alt_subs; + for (int i = 0; i < alt_lookups.size(); i++) + if (alt_lookups[i].used) { + OpenType::GsubLookup l = gsub.lookup(i); + alt_subs.clear(); + (void) l.unparse_automatics(gsub, alt_subs, used_coverage); + metrics.apply_alternates(alt_subs, i, *alt_lookups[i].filter, glyph_names); + } + altselector_features.swap(interesting_features); + altselector_feature_filters.swap(feature_filters); } } @@ -1429,7 +1484,7 @@ static bool kern_feature_requested() { return std::find(interesting_features.begin(), interesting_features.end(), - OpenType::Tag("kern")) != interesting_features.end(); + OpenType::Tag("kern")) != interesting_features.end(); } static void @@ -1437,20 +1492,20 @@ do_try_ttf_kern(Metrics& metrics, const { // if no GPOS "kern" lookups and "kern" requested, try "kern" table if (!kern_feature_requested()) - return; + return; try { - OpenType::KernTable kern(otf.table("kern"), errh); - Vector poss; - bool understood = kern.unparse_automatics(poss, errh); - int nunderstood = metrics.apply(poss); - - // mark as used - int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; - feature_usage.find_force(OpenType::Tag("kern").value()) |= d; + OpenType::KernTable kern(otf.table("kern"), errh); + Vector poss; + bool understood = kern.unparse_automatics(poss, errh); + int nunderstood = metrics.apply(poss); + + // mark as used + int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; + feature_usage.find_force(OpenType::Tag("kern").value()) |= d; } catch (OpenType::BlankTable) { - // nada + // nada } catch (OpenType::Error e) { - errh->warning("kern %<%s%> error, continuing", e.description.c_str()); + errh->warning("kern %<%s%> error, continuing", e.description.c_str()); } } @@ -1464,77 +1519,78 @@ do_gpos(Metrics& metrics, const OpenType // OpenType recommends that if GPOS exists, but the "kern" feature loads // no lookups, we use the TrueType "kern" table, if any. if (kern_feature_requested()) { - OpenType::Tag kern_tag("kern"); - for (Lookup *l = lookups.begin(); l != lookups.end(); ++l) - if (std::find(l->features.begin(), l->features.end(), kern_tag) != l->features.end()) - goto skip_ttf_kern; - do_try_ttf_kern(metrics, otf, feature_usage, errh); + OpenType::Tag kern_tag("kern"); + for (Lookup *l = lookups.begin(); l != lookups.end(); ++l) + if (std::find(l->features.begin(), l->features.end(), kern_tag) != l->features.end()) + goto skip_ttf_kern; + do_try_ttf_kern(metrics, otf, feature_usage, errh); skip_ttf_kern: ; } Vector poss; for (int i = 0; i < lookups.size(); i++) - if (lookups[i].used) { - OpenType::GposLookup l = gpos.lookup(i); - poss.clear(); - bool understood = l.unparse_automatics(poss, errh); - int nunderstood = metrics.apply(poss); - - // mark as used - int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; - for (int j = 0; j < lookups[i].features.size(); j++) - feature_usage.find_force(lookups[i].features[j].value()) |= d; - } + if (lookups[i].used) { + OpenType::GposLookup l = gpos.lookup(i); + poss.clear(); + bool understood = l.unparse_automatics(poss, errh); + int nunderstood = metrics.apply(poss); + + // mark as used + int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; + for (int j = 0; j < lookups[i].features.size(); j++) + feature_usage.find_force(lookups[i].features[j].value()) |= d; + } } static void do_math_spacing(Metrics &metrics, const FontInfo &finfo, - const DvipsEncoding &dvipsenc) + const DvipsEncoding &dvipsenc) { Transform font_xform; if (extend) - font_xform.scale(extend, 1); + font_xform.scale(extend, 1); if (slant) - font_xform.shear(slant); + font_xform.shear(slant); CharstringBounds boundser(font_xform); double x_height = finfo.x_height(font_xform); - double slant = font_slant(finfo); + double actual_slant = font_slant(finfo); int boundary_char = dvipsenc.boundary_char(); double bounds[4], width; for (int code = 0; code < metrics.encoding_size(); code++) - if (metrics.was_base_glyph(code) && code != boundary_char - && char_bounds(bounds, width, finfo, font_xform, code)) { - int left_sb = (bounds[0] < 0 ? (int) ceil(-bounds[0]) : 0); - metrics.add_single_positioning(code, left_sb, 0, left_sb); - - if (skew_char >= 0 && code < 256) { - double virtual_height = - (bounds[3] > x_height ? bounds[3] : x_height) - - 0.5 * x_height; - double right_sb = (bounds[2] > width ? bounds[2] - width : 0); - int skew = (int) (slant * virtual_height + left_sb - right_sb); - metrics.add_kern(code, skew_char, skew); - } - } + if (metrics.was_base_glyph(code) + && code != boundary_char + && char_bounds(bounds, width, finfo, font_xform, metrics.unicode(code))) { + int left_sb = (bounds[0] < 0 ? (int) ceil(-bounds[0]) : 0); + metrics.add_single_positioning(code, left_sb, 0, left_sb); + + if (skew_char >= 0 && code < 256) { + double sheight = std::max(bounds[3], x_height) - 0.5 * x_height; + double right_sb = std::max(bounds[2] - width, 0.0); + double desired = left_sb + 0.5 * width + actual_slant * sheight + 0.25 * right_sb; + double computed = 0.5 * (left_sb + width + right_sb); + int skew = (int) (desired - computed); + metrics.add_kern(code, skew_char, skew); + } + } } static void do_file(const String &otf_filename, const OpenType::Font &otf, - const DvipsEncoding &dvipsenc_in, bool dvipsenc_literal, - ErrorHandler *errh) + const DvipsEncoding &dvipsenc_in, bool dvipsenc_literal, + ErrorHandler *errh) { FontInfo finfo(&otf, errh); if (!finfo.ok()) - return; + return; if (!finfo.cff) - errh->warning("TrueType-flavored font support is experimental"); + errh->warning("TrueType-flavored font support is experimental"); if (override_is_fixed_pitch) - finfo.set_is_fixed_pitch(is_fixed_pitch); + finfo.set_is_fixed_pitch(is_fixed_pitch); if (override_italic_angle) - finfo.set_italic_angle(italic_angle); + finfo.set_italic_angle(italic_angle); if (override_x_height != FontInfo::x_height_auto) finfo.set_x_height(override_x_height, x_height); @@ -1545,15 +1601,15 @@ do_file(const String &otf_filename, cons // set typeface name from font family name { - String typeface = finfo.family_name(); + String typeface = finfo.family_name(); - // make it reasonable for the shell - StringAccum sa; - for (int i = 0; i < typeface.length(); i++) - if (isalnum((unsigned char) typeface[i]) || typeface[i] == '_' || typeface[i] == '-' || typeface[i] == '.' || typeface[i] == ',' || typeface[i] == '+') - sa << typeface[i]; + // make it reasonable for the shell + StringAccum sa; + for (int i = 0; i < typeface.length(); i++) + if (isalnum((unsigned char) typeface[i]) || typeface[i] == '_' || typeface[i] == '-' || typeface[i] == '.' || typeface[i] == ',' || typeface[i] == '+') + sa << typeface[i]; - set_typeface(sa.length() ? sa.take_string() : font_name, false); + set_typeface(sa.length() ? sa.take_string() : font_name, false); } // initialize encoding @@ -1562,10 +1618,10 @@ do_file(const String &otf_filename, cons // encode boundary glyph at 256; pretend its Unicode value is '\n' metrics.encode(256, '\n', metrics.boundary_glyph()); if (dvipsenc_literal) - dvipsenc.make_metrics(metrics, finfo, 0, true, errh); + dvipsenc.make_metrics(metrics, finfo, 0, true, errh); else { - T1Secondary secondary(finfo, font_name, otf_filename); - dvipsenc.make_metrics(metrics, finfo, &secondary, false, errh); + T1Secondary secondary(finfo, font_name, otf_filename); + dvipsenc.make_metrics(metrics, finfo, &secondary, false, errh); } // maintain statistics about features @@ -1573,11 +1629,11 @@ do_file(const String &otf_filename, cons // apply activated GSUB features try { - do_gsub(metrics, otf, dvipsenc, dvipsenc_literal, feature_usage, glyph_names, errh); + do_gsub(metrics, otf, dvipsenc, dvipsenc_literal, feature_usage, glyph_names, errh); } catch (OpenType::BlankTable) { - // nada + // nada } catch (OpenType::Error e) { - errh->warning("GSUB %<%s%> error, continuing", e.description.c_str()); + errh->warning("GSUB %<%s%> error, continuing", e.description.c_str()); } // apply LIGKERN ligature commands to the result @@ -1588,15 +1644,15 @@ do_file(const String &otf_filename, cons // reencode characters to fit within 8 bytes (+ 1 for the boundary) if (!dvipsenc_literal) - metrics.shrink_encoding(257, dvipsenc_in, errh); + metrics.shrink_encoding(257, dvipsenc_in, errh); // apply activated GPOS features try { - do_gpos(metrics, otf, feature_usage, errh); + do_gpos(metrics, otf, feature_usage, errh); } catch (OpenType::BlankTable) { - do_try_ttf_kern(metrics, otf, feature_usage, errh); + do_try_ttf_kern(metrics, otf, feature_usage, errh); } catch (OpenType::Error e) { - errh->warning("GPOS %<%s%> error, continuing", e.description.c_str()); + errh->warning("GPOS %<%s%> error, continuing", e.description.c_str()); } // apply LIGKERN kerning and POS positioning commands to the result @@ -1605,11 +1661,11 @@ do_file(const String &otf_filename, cons // use prespecified raw fonts for (BaseEncoding **be = base_encodings.begin(); be != base_encodings.end(); be++) - if (!(*be)->secondary) { - Vector mapp; - (*be)->encoding.make_base_mappings(mapp, finfo); - metrics.apply_base_encoding((*be)->font_name, (*be)->encoding, mapp); - } + if (!(*be)->secondary) { + Vector mapp; + (*be)->encoding.make_base_mappings(mapp, finfo); + metrics.apply_base_encoding((*be)->font_name, (*be)->encoding, mapp); + } // remove extra characters metrics.cut_encoding(257); @@ -1618,24 +1674,24 @@ do_file(const String &otf_filename, cons // apply letterspacing, if any if (letterspace) - for (int code = 0; code < metrics.encoding_size(); code++) - if (metrics.was_base_glyph(code) && code != boundary_char) { - metrics.add_single_positioning(code, letterspace / 2, 0, letterspace); - if (code < 256) { - metrics.add_kern(code, 256, -letterspace / 2); - metrics.add_kern(256, code, -letterspace / 2); - } - } + for (int code = 0; code < metrics.encoding_size(); code++) + if (metrics.was_base_glyph(code) && code != boundary_char) { + metrics.add_single_positioning(code, letterspace / 2, 0, letterspace); + if (code < 256) { + metrics.add_kern(code, 256, -letterspace / 2); + metrics.add_kern(256, code, -letterspace / 2); + } + } // apply math letterspacing, if any if (math_spacing) - do_math_spacing(metrics, finfo, dvipsenc); + do_math_spacing(metrics, finfo, dvipsenc); // reencode right components of boundary_glyph as boundary_char if (metrics.reencode_right_ligkern(256, boundary_char) > 0 - && boundary_char < 0) { - errh->warning("no boundary character, ignoring some ligatures and/or kerns\n"); - errh->message("(You may want to try the --boundary-char option.)"); + && boundary_char < 0) { + errh->warning("no boundary character, ignoring some ligatures and/or kerns\n"); + errh->message("(You may want to try the --boundary-char option.)"); } // report unused and underused features if any @@ -1643,51 +1699,51 @@ do_file(const String &otf_filename, cons // figure out our FONTNAME if (!font_name) { - // derive font name from OpenType font name - font_name = finfo.postscript_name(); - if (encoding_file) { - int slash = encoding_file.find_right('/') + 1; - int dot = encoding_file.find_right('.'); - if (dot < slash) // includes dot < 0 case - dot = encoding_file.length(); - font_name += String("--") + encoding_file.substring(slash, dot - slash); - } - if (interesting_scripts.size() != 2 || interesting_scripts[0] != OpenType::Tag("latn") || interesting_scripts[1].valid()) - for (int i = 0; i < interesting_scripts.size(); i += 2) { - font_name += String("--S") + interesting_scripts[i].text(); - if (interesting_scripts[i+1].valid()) - font_name += String(".") + interesting_scripts[i+1].text(); - } - for (int i = 0; i < interesting_features.size(); i++) - if (feature_usage[interesting_features[i].value()]) - font_name += String("--F") + interesting_features[i].text(); + // derive font name from OpenType font name + font_name = finfo.postscript_name(); + if (encoding_file) { + int slash = encoding_file.find_right('/') + 1; + int dot = encoding_file.find_right('.'); + if (dot < slash) // includes dot < 0 case + dot = encoding_file.length(); + font_name += String("--") + encoding_file.substring(slash, dot - slash); + } + if (interesting_scripts.size() != 2 || interesting_scripts[0] != OpenType::Tag("latn") || interesting_scripts[1].valid()) + for (int i = 0; i < interesting_scripts.size(); i += 2) { + font_name += String("--S") + interesting_scripts[i].text(); + if (interesting_scripts[i+1].valid()) + font_name += String(".") + interesting_scripts[i+1].text(); + } + for (int i = 0; i < interesting_features.size(); i++) + if (feature_usage[interesting_features[i].value()]) + font_name += String("--F") + interesting_features[i].text(); } // output encoding if (dvipsenc_literal) { - out_encoding_name = dvipsenc_in.name(); - out_encoding_file = dvipsenc_in.filename(); + out_encoding_name = dvipsenc_in.name(); + out_encoding_file = dvipsenc_in.filename(); } else - output_encoding(metrics, glyph_names, errh); + output_encoding(metrics, glyph_names, errh); // set up coding scheme if (metrics.coding_scheme()) - metrics.set_design_units(1); + metrics.set_design_units(1); else - metrics.set_coding_scheme(out_encoding_name); + metrics.set_coding_scheme(out_encoding_name); // force no type 1 if (!finfo.cff && (output_flags & G_TYPE1)) { - errh->warning("assuming --no-type1 since this font is TrueType-flavored"); - output_flags &= ~G_TYPE1; + errh->warning("assuming --no-type1 since this font is TrueType-flavored"); + output_flags &= ~G_TYPE1; } // output ::otf_filename = otf_filename; output_metrics(metrics, finfo.postscript_name(), dvipsenc.boundary_char(), - finfo, - out_encoding_name, out_encoding_file, - font_name, main_dvips_map, errh); + finfo, + out_encoding_name, out_encoding_file, + font_name, main_dvips_map, errh); } @@ -1695,8 +1751,8 @@ String installed_metrics_font_name(const String &base_font_name, const String &secondary) { for (BaseEncoding **be = base_encodings.begin(); be != base_encodings.end(); be++) - if ((*be)->secondary == secondary && ::font_name == base_font_name) - return (*be)->font_name; + if ((*be)->secondary == secondary && ::font_name == base_font_name) + return (*be)->font_name; return String(); } @@ -1706,16 +1762,16 @@ static int clp_parse_char(Clp_Parser *clp, const char *arg, int complain, void *) { if (arg[0] && !arg[1] && !isdigit((unsigned char) arg[0])) { - clp->val.i = (unsigned char)arg[0]; - return 1; + clp->val.i = (unsigned char)arg[0]; + return 1; } else if (arg[0] == '-' || isdigit((unsigned char) arg[0])) { - char *end; - clp->val.i = strtol(arg, &end, 10); - if (clp->val.i <= 255 && !*end) - return 1; + char *end; + clp->val.i = strtol(arg, &end, 10); + if (clp->val.i <= 255 && !*end) + return 1; } if (complain) - Clp_OptionError(clp, "'%O' expects a character, not '%s'", arg); + Clp_OptionError(clp, "'%O' expects a character, not '%s'", arg); return 0; } } @@ -1729,51 +1785,51 @@ parse_base_encodings(const String &filen str.c_str(); const char *s_end = str.end(); for (const char *s = str.begin(); s != s_end; ) { - while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') - s++; - // skip comments and blank lines - if (s != s_end && *s != '%' && *s != '#' && *s != '\n' && *s != '\r') { - const char *w1 = s; - while (s != s_end && !isspace((unsigned char) *s)) - s++; - BaseEncoding *be = new BaseEncoding; - be->font_name = str.substring(w1, s); - while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') - s++; - const char *w2 = s; - while (s != s_end && !isspace((unsigned char) *s)) - s++; - String efile = str.substring(w2, s); - while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') - s++; - if (s != s_end && !isspace((unsigned char) *s) && *s != '%' && *s != '#') { - const char *w3 = s; - while (s != s_end && !isspace((unsigned char) *s)) - s++; - be->secondary = str.substring(w3, s); - } - LandmarkErrorHandler lerrh(errh, print_filename + String(lineno)); - int before = lerrh.nerrors(); - if (be->secondary) - /* encoding ignored */; - else if (!efile) - lerrh.error("missing encoding name"); - else if (String path = locate_encoding(efile, errh)) - be->encoding.parse(path, true, true, &lerrh); - else - lerrh.error("encoding %<%s%> not found", efile.c_str()); - if (lerrh.nerrors() == before) - base_encodings.push_back(be); - else - delete be; - } - while (s != s_end && *s != '\n' && *s != '\r') - s++; - if (s != s_end && *s == '\r') - s++; - if (s != s_end && *s == '\n') - s++; - lineno++; + while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') + s++; + // skip comments and blank lines + if (s != s_end && *s != '%' && *s != '#' && *s != '\n' && *s != '\r') { + const char *w1 = s; + while (s != s_end && !isspace((unsigned char) *s)) + s++; + BaseEncoding *be = new BaseEncoding; + be->font_name = str.substring(w1, s); + while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') + s++; + const char *w2 = s; + while (s != s_end && !isspace((unsigned char) *s)) + s++; + String efile = str.substring(w2, s); + while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') + s++; + if (s != s_end && !isspace((unsigned char) *s) && *s != '%' && *s != '#') { + const char *w3 = s; + while (s != s_end && !isspace((unsigned char) *s)) + s++; + be->secondary = str.substring(w3, s); + } + LandmarkErrorHandler lerrh(errh, print_filename + String(lineno)); + int before = lerrh.nerrors(); + if (be->secondary) + /* encoding ignored */; + else if (!efile) + lerrh.error("missing encoding name"); + else if (String path = locate_encoding(efile, errh)) + be->encoding.parse(path, true, true, &lerrh); + else + lerrh.error("encoding %<%s%> not found", efile.c_str()); + if (lerrh.nerrors() == before) + base_encodings.push_back(be); + else + delete be; + } + while (s != s_end && *s != '\n' && *s != '\r') + s++; + if (s != s_end && *s == '\r') + s++; + if (s != s_end && *s == '\n') + s++; + lineno++; } } @@ -1784,7 +1840,7 @@ main(int argc, char *argv[]) handle_sigchld(); #endif Clp_Parser *clp = - Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); + Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); Clp_AddType(clp, CHAR_OPTTYPE, 0, clp_parse_char, 0); program_name = Clp_ProgramName(clp); #if HAVE_KPATHSEA @@ -1792,13 +1848,13 @@ main(int argc, char *argv[]) #endif #ifdef HAVE_CTIME { - time_t t = time(0); - char *c = ctime(&t); - current_time = " on " + String(c).substring(0, -1); // get rid of \n + time_t t = time(0); + char *c = ctime(&t); + current_time = " on " + String(c).substring(0, -1); // get rid of \n } #endif for (int i = 0; i < argc; i++) - invocation << (i ? " " : "") << argv[i]; + invocation << (i ? " " : "") << argv[i]; ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); const char *input_file = 0; @@ -1811,350 +1867,376 @@ main(int argc, char *argv[]) Vector base_encoding_files; bool no_ecommand = false, default_ligkern = true; int warn_missing = -1; + unsigned specified_output_flags = 0; String codingscheme; + const char* odirs[NUMODIR + 1]; + for (int i = 0; i <= NUMODIR; ++i) { + odirs[i] = 0; + } GlyphFilter current_substitution_filter; GlyphFilter current_alternate_filter; GlyphFilter* current_filter_ptr = &null_filter; + Vector allocated_filters; while (1) { - int opt = Clp_Next(clp); - switch (opt) { + int opt = Clp_Next(clp); + switch (opt) { - case SCRIPT_OPT: { - String arg = clp->vstr; - int period = arg.find_left('.'); - OpenType::Tag scr(period <= 0 ? arg : arg.substring(0, period)); - if (scr.valid() && period > 0) { - OpenType::Tag lang(arg.substring(period + 1)); - if (lang.valid()) { - interesting_scripts.push_back(scr); - interesting_scripts.push_back(lang); - } else - usage_error(errh, "bad language tag"); - } else if (scr.valid()) { - interesting_scripts.push_back(scr); - interesting_scripts.push_back(OpenType::Tag()); - } else - usage_error(errh, "bad script tag"); - break; - } - - case FEATURE_OPT: { - OpenType::Tag t(clp->vstr); - if (!t.valid()) - usage_error(errh, "bad feature tag"); - else if (feature_filters[t]) - usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); - else { - if (!current_filter_ptr) - current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); - interesting_features.push_back(t); - feature_filters.insert(t, current_filter_ptr); - } - break; - } - - case LETTER_FEATURE_OPT: { - OpenType::Tag t(clp->vstr); - if (!t.valid()) - usage_error(errh, "bad feature tag"); - else if (feature_filters[t]) - usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); - else { - interesting_features.push_back(t); - GlyphFilter* gf = new GlyphFilter; - gf->add_substitution_filter("", false, errh); - *gf += current_alternate_filter; - feature_filters.insert(t, gf); - } - break; - } - - case SUBS_FILTER_OPT: - current_substitution_filter = null_filter; - /* fallthru */ - case EXCLUDE_SUBS_OPT: - case INCLUDE_SUBS_OPT: - current_substitution_filter.add_substitution_filter(clp->vstr, opt == EXCLUDE_SUBS_OPT, errh); - current_filter_ptr = 0; - break; - - case CLEAR_SUBS_OPT: - current_substitution_filter = null_filter; - current_filter_ptr = 0; - break; - - case ENCODING_OPT: - if (encoding_file) - usage_error(errh, "encoding specified twice"); - encoding_file = clp->vstr; + case SCRIPT_OPT: { + String arg = clp->vstr; + int period = arg.find_left('.'); + OpenType::Tag scr(period <= 0 ? arg : arg.substring(0, period)); + if (scr.valid() && period > 0) { + OpenType::Tag lang(arg.substring(period + 1)); + if (lang.valid()) { + interesting_scripts.push_back(scr); + interesting_scripts.push_back(lang); + } else + usage_error(errh, "bad language tag"); + } else if (scr.valid()) { + interesting_scripts.push_back(scr); + interesting_scripts.push_back(OpenType::Tag()); + } else + usage_error(errh, "bad script tag"); + break; + } + + case FEATURE_OPT: { + OpenType::Tag t(clp->vstr); + if (!t.valid()) + usage_error(errh, "bad feature tag"); + else if (feature_filters[t]) + usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); + else { + if (!current_filter_ptr) { + current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); + allocated_filters.push_back(current_filter_ptr); + } + interesting_features.push_back(t); + feature_filters.insert(t, current_filter_ptr); + } + break; + } + + case LETTER_FEATURE_OPT: { + OpenType::Tag t(clp->vstr); + if (!t.valid()) + usage_error(errh, "bad feature tag"); + else if (feature_filters[t]) + usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); + else { + interesting_features.push_back(t); + GlyphFilter* gf = new GlyphFilter; + gf->add_substitution_filter("", false, errh); + *gf += current_alternate_filter; + feature_filters.insert(t, gf); + } + break; + } + + case SUBS_FILTER_OPT: + current_substitution_filter = null_filter; + /* fallthru */ + case EXCLUDE_SUBS_OPT: + case INCLUDE_SUBS_OPT: + current_substitution_filter.add_substitution_filter(clp->vstr, opt == EXCLUDE_SUBS_OPT, errh); + current_filter_ptr = 0; + break; + + case CLEAR_SUBS_OPT: + current_substitution_filter = null_filter; + current_filter_ptr = 0; + break; + + case ENCODING_OPT: + if (encoding_file) + usage_error(errh, "encoding specified twice"); + encoding_file = clp->vstr; have_encoding_file = true; - break; + break; - case LITERAL_ENCODING_OPT: - if (encoding_file) - usage_error(errh, "encoding specified twice"); - encoding_file = clp->vstr; + case LITERAL_ENCODING_OPT: + if (encoding_file) + usage_error(errh, "encoding specified twice"); + encoding_file = clp->vstr; have_encoding_file = true; - literal_encoding = true; - break; + literal_encoding = true; + break; + + case BASE_ENCODINGS_OPT: + base_encoding_files.push_back(clp->vstr); + break; + + case EXTEND_OPT: + if (extend) + usage_error(errh, "extend value specified twice"); + extend = clp->val.d; + break; + + case SLANT_OPT: + if (slant) + usage_error(errh, "slant value specified twice"); + slant = clp->val.d; + break; + + case LETTERSPACE_OPT: + if (letterspace) + usage_error(errh, "letterspacing value specified twice"); + letterspace = clp->val.i; + break; + + case SPACE_FACTOR_OPT: + if (space_factor != 1) + usage_error(errh, "space factor specified twice"); + space_factor = clp->val.d; + break; + + case MATH_SPACING_OPT: + math_spacing = !clp->negated; + if (math_spacing && clp->have_val) { + if (clp->val.i < 0 || clp->val.i > 255) + usage_error(errh, "--math-spacing skew character must be between 0 and 255"); + skew_char = clp->val.i; + } + break; + + case DESIGN_SIZE_OPT: + if (design_size > 0) + usage_error(errh, "design size value specified twice"); + else if (clp->val.d <= 0) + usage_error(errh, "design size must be > 0"); + design_size = clp->val.d; + break; + + case LIGKERN_OPT: + ligkern.push_back(clp->vstr); + break; + + case POSITION_OPT: + pos.push_back(clp->vstr); + break; + + case WARN_MISSING_OPT: + warn_missing = !clp->negated; + break; + + case NO_ECOMMAND_OPT: + no_ecommand = true; + break; + + case DEFAULT_LIGKERN_OPT: + default_ligkern = !clp->negated; + break; + + case BOUNDARY_CHAR_OPT: + ligkern.push_back(String("|| = ") + String(clp->val.i)); + break; + + case ALTSELECTOR_CHAR_OPT: + ligkern.push_back(String("^^ = ") + String(clp->val.i)); + break; + + case ALTSELECTOR_FEATURE_OPT: { + OpenType::Tag t(clp->vstr); + if (!t.valid()) + usage_error(errh, "bad feature tag"); + else if (altselector_feature_filters[t]) + usage_error(errh, "altselector feature %<%s%> included twice", t.text().c_str()); + else { + if (!current_filter_ptr) { + current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); + allocated_filters.push_back(current_filter_ptr); + } + altselector_features.push_back(t); + altselector_feature_filters.insert(t, current_filter_ptr); + } + break; + } + + case ALTERNATES_FILTER_OPT: + current_alternate_filter = null_filter; + /* fallthru */ + case EXCLUDE_ALTERNATES_OPT: + case INCLUDE_ALTERNATES_OPT: + current_alternate_filter.add_alternate_filter(clp->vstr, opt == EXCLUDE_ALTERNATES_OPT, errh); + current_filter_ptr = 0; + break; + + case CLEAR_ALTERNATES_OPT: + current_alternate_filter = null_filter; + current_filter_ptr = 0; + break; + + case UNICODING_OPT: + unicoding.push_back(clp->vstr); + break; + + case CODINGSCHEME_OPT: + if (codingscheme) + usage_error(errh, "coding scheme specified twice"); + codingscheme = clp->vstr; + if (codingscheme.length() > 39) + errh->warning("only first 39 characters of coding scheme are significant"); + if (codingscheme.find_left('(') >= 0 || codingscheme.find_left(')') >= 0) + usage_error(errh, "coding scheme cannot contain parentheses"); + break; + + case AUTOMATIC_OPT: + automatic = !clp->negated; + break; + + case VENDOR_OPT: + if (!set_vendor(clp->vstr)) + usage_error(errh, "vendor name specified twice"); + break; + + case TYPEFACE_OPT: + if (!set_typeface(clp->vstr, true)) + usage_error(errh, "typeface name specified twice"); + break; + + case VIRTUAL_OPT: + if (clp->negated) + output_flags &= ~G_VMETRICS; + else + output_flags |= G_VMETRICS; + specified_output_flags |= G_VMETRICS; + break; + + case NO_ENCODING_OPT: + case NO_TYPE1_OPT: + case NO_DOTLESSJ_OPT: + case NO_UPDMAP_OPT: + output_flags &= ~(opt - NO_OUTPUT_OPTS); + specified_output_flags |= opt - NO_OUTPUT_OPTS; + break; + + case TRUETYPE_OPT: + case TYPE42_OPT: + if (!clp->negated) + output_flags |= (opt - YES_OUTPUT_OPTS); + else + output_flags &= ~(opt - YES_OUTPUT_OPTS); + specified_output_flags |= opt - YES_OUTPUT_OPTS; + break; - case BASE_ENCODINGS_OPT: - base_encoding_files.push_back(clp->vstr); - break; - - case EXTEND_OPT: - if (extend) - usage_error(errh, "extend value specified twice"); - extend = clp->val.d; - break; - - case SLANT_OPT: - if (slant) - usage_error(errh, "slant value specified twice"); - slant = clp->val.d; - break; - - case LETTERSPACE_OPT: - if (letterspace) - usage_error(errh, "letterspacing value specified twice"); - letterspace = clp->val.i; - break; - - case SPACE_FACTOR_OPT: - if (space_factor != 1) - usage_error(errh, "space factor specified twice"); - space_factor = clp->val.d; - break; - - case MATH_SPACING_OPT: - math_spacing = !clp->negated; - if (math_spacing && clp->have_val) { - if (clp->val.i < 0 || clp->val.i > 255) - usage_error(errh, "--math-spacing skew character must be between 0 and 255"); - skew_char = clp->val.i; - } - break; - - case DESIGN_SIZE_OPT: - if (design_size > 0) - usage_error(errh, "design size value specified twice"); - else if (clp->val.d <= 0) - usage_error(errh, "design size must be > 0"); - design_size = clp->val.d; - break; - - case LIGKERN_OPT: - ligkern.push_back(clp->vstr); - break; - - case POSITION_OPT: - pos.push_back(clp->vstr); - break; - - case WARN_MISSING_OPT: - warn_missing = !clp->negated; - break; - - case NO_ECOMMAND_OPT: - no_ecommand = true; - break; - - case DEFAULT_LIGKERN_OPT: - default_ligkern = !clp->negated; - break; - - case BOUNDARY_CHAR_OPT: - ligkern.push_back(String("|| = ") + String(clp->val.i)); - break; - - case ALTSELECTOR_CHAR_OPT: - ligkern.push_back(String("^^ = ") + String(clp->val.i)); - break; - - case ALTSELECTOR_FEATURE_OPT: { - OpenType::Tag t(clp->vstr); - if (!t.valid()) - usage_error(errh, "bad feature tag"); - else if (altselector_feature_filters[t]) - usage_error(errh, "altselector feature %<%s%> included twice", t.text().c_str()); - else { - if (!current_filter_ptr) - current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); - altselector_features.push_back(t); - altselector_feature_filters.insert(t, current_filter_ptr); - } - break; - } - - case ALTERNATES_FILTER_OPT: - current_alternate_filter = null_filter; - /* fallthru */ - case EXCLUDE_ALTERNATES_OPT: - case INCLUDE_ALTERNATES_OPT: - current_alternate_filter.add_alternate_filter(clp->vstr, opt == EXCLUDE_ALTERNATES_OPT, errh); - current_filter_ptr = 0; - break; - - case CLEAR_ALTERNATES_OPT: - current_alternate_filter = null_filter; - current_filter_ptr = 0; - break; - - case UNICODING_OPT: - unicoding.push_back(clp->vstr); - break; - - case CODINGSCHEME_OPT: - if (codingscheme) - usage_error(errh, "coding scheme specified twice"); - codingscheme = clp->vstr; - if (codingscheme.length() > 39) - errh->warning("only first 39 characters of coding scheme are significant"); - if (codingscheme.find_left('(') >= 0 || codingscheme.find_left(')') >= 0) - usage_error(errh, "coding scheme cannot contain parentheses"); - break; - - case AUTOMATIC_OPT: - automatic = !clp->negated; - break; - - case VENDOR_OPT: - if (!set_vendor(clp->vstr)) - usage_error(errh, "vendor name specified twice"); - break; - - case TYPEFACE_OPT: - if (!set_typeface(clp->vstr, true)) - usage_error(errh, "typeface name specified twice"); - break; - - case VIRTUAL_OPT: - if (clp->negated) - output_flags &= ~G_VMETRICS; - else - output_flags |= G_VMETRICS; - break; - - case NO_ENCODING_OPT: - case NO_TYPE1_OPT: - case NO_DOTLESSJ_OPT: - case NO_UPDMAP_OPT: - output_flags &= ~(opt - NO_OUTPUT_OPTS); - break; - - case TRUETYPE_OPT: - case TYPE42_OPT: - if (!clp->negated) - output_flags |= (opt - YES_OUTPUT_OPTS); - else - output_flags &= ~(opt - YES_OUTPUT_OPTS); - break; - - case OUTPUT_ENCODING_OPT: - if (out_encoding_file) - usage_error(errh, "encoding output file specified twice"); - out_encoding_file = (clp->have_val ? clp->vstr : "-"); - output_flags = G_ENCODING; - break; - - case MINIMUM_KERN_OPT: - minimum_kern = clp->val.d; - break; - - case MAP_FILE_OPT: - if (clp->negated) - output_flags &= ~G_PSFONTSMAP; - else { - output_flags |= G_PSFONTSMAP; - if (!set_map_file(clp->vstr)) - usage_error(errh, "map file specified twice"); - } - break; - - case PL_OPT: - output_flags = (output_flags & ~G_BINARY) | G_ASCII; - break; - - case TFM_OPT: - output_flags = (output_flags & ~G_ASCII) | G_BINARY; - break; - - case ENCODING_DIR_OPT: - case TFM_DIR_OPT: - case PL_DIR_OPT: - case VF_DIR_OPT: - case VPL_DIR_OPT: - case TYPE1_DIR_OPT: - case TRUETYPE_DIR_OPT: - case TYPE42_DIR_OPT: - if (!setodir(opt - DIR_OPTS, clp->vstr)) - usage_error(errh, "%s directory specified twice", odirname(opt - DIR_OPTS)); - break; - - case FONT_NAME_OPT: - font_name: - if (font_name) - usage_error(errh, "font name specified twice"); - font_name = clp->vstr; - break; - - case FIXED_PITCH_OPT: - override_is_fixed_pitch = true; - is_fixed_pitch = !clp->negated; - break; - - case PROPORTIONAL_WIDTH_OPT: - override_is_fixed_pitch = true; - is_fixed_pitch = !!clp->negated; - break; - - case ITALIC_ANGLE_OPT: - override_italic_angle = true; - italic_angle = clp->val.d; - break; - - case GLYPHLIST_OPT: - glyphlist_files.push_back(clp->vstr); - break; - - case QUERY_FEATURES_OPT: - usage_error(errh, "run % instead"); - break; - - case QUERY_SCRIPTS_OPT: - usage_error(errh, "run % instead"); - break; - - case QUIET_OPT: - if (clp->negated) - errh = ErrorHandler::default_handler(); - else - // 9.Nov.05 -- need a new SilentErrorHandler, because we use - // the base SilentErrorHandler elsewhere to ignore errors - errh = new SilentErrorHandler; - break; - - case VERBOSE_OPT: - verbose = !clp->negated; - break; - - case NOCREATE_OPT: - no_create = clp->negated; - break; - - case FORCE_OPT: - force = !clp->negated; - break; + case OUTPUT_ENCODING_OPT: + if (out_encoding_file) + usage_error(errh, "encoding output file specified twice"); + out_encoding_file = (clp->have_val ? clp->vstr : "-"); + output_flags = G_ENCODING; + specified_output_flags = -1; + break; + + case MINIMUM_KERN_OPT: + minimum_kern = clp->val.d; + break; + + case MAP_FILE_OPT: + if (clp->negated) + output_flags &= ~G_PSFONTSMAP; + else { + output_flags |= G_PSFONTSMAP; + if (!set_map_file(clp->vstr)) + usage_error(errh, "map file specified twice"); + } + specified_output_flags |= G_PSFONTSMAP; + break; + + case PL_OPT: + if (clp->negated) + output_flags &= ~G_ASCII; + else + output_flags |= G_ASCII; + specified_output_flags |= G_ASCII; + break; + + case TFM_OPT: + if (clp->negated) + output_flags &= ~G_BINARY; + else + output_flags |= G_BINARY; + specified_output_flags |= G_BINARY; + break; + + case ENCODING_DIR_OPT: + case TFM_DIR_OPT: + case PL_DIR_OPT: + case VF_DIR_OPT: + case VPL_DIR_OPT: + case TYPE1_DIR_OPT: + case TRUETYPE_DIR_OPT: + case TYPE42_DIR_OPT: + case DIR_OPT: + if (!odirs[opt - DIR_OPTS]) + odirs[opt - DIR_OPTS] = clp->vstr; + else + usage_error(errh, "%s directory specified twice", odirname(opt - DIR_OPTS)); + break; - case KPATHSEA_DEBUG_OPT: + case FONT_NAME_OPT: + font_name: + if (font_name) + usage_error(errh, "font name specified twice"); + font_name = clp->vstr; + break; + + case FIXED_PITCH_OPT: + override_is_fixed_pitch = true; + is_fixed_pitch = !clp->negated; + break; + + case PROPORTIONAL_WIDTH_OPT: + override_is_fixed_pitch = true; + is_fixed_pitch = !!clp->negated; + break; + + case ITALIC_ANGLE_OPT: + override_italic_angle = true; + italic_angle = clp->val.d; + break; + + case GLYPHLIST_OPT: + glyphlist_files.push_back(clp->vstr); + break; + + case QUERY_FEATURES_OPT: + usage_error(errh, "run % instead"); + break; + + case QUERY_SCRIPTS_OPT: + usage_error(errh, "run % instead"); + break; + + case QUIET_OPT: + if (clp->negated) + errh = ErrorHandler::default_handler(); + else + // 9.Nov.05 -- need a new SilentErrorHandler, because we use + // the base SilentErrorHandler elsewhere to ignore errors + errh = new SilentErrorHandler; + break; + + case VERBOSE_OPT: + verbose = !clp->negated; + break; + + case NOCREATE_OPT: + no_create = clp->negated; + break; + + case FORCE_OPT: + force = !clp->negated; + break; + + case KPATHSEA_DEBUG_OPT: #if HAVE_KPATHSEA - kpsei_set_debug_flags(clp->val.u); + kpsei_set_debug_flags(clp->val.u); #else - errh->warning("Not compiled with kpathsea!"); + errh->warning("Not compiled with kpathsea!"); #endif - break; + break; case X_HEIGHT_OPT: { char* ends; @@ -2169,127 +2251,141 @@ main(int argc, char *argv[]) && *ends == 0 && *clp->vstr != 0) override_x_height = FontInfo::x_height_explicit; else - usage_error(errh, "bad --x-height option"); + usage_error(errh, "bad --x-height option"); break; } - case VERSION_OPT: - printf("otftotfm (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2002-2016 Eddie Kohler\n\ + case VERSION_OPT: + printf("otftotfm (LCDF typetools) %s\n", VERSION); + printf("Copyright (C) 2002-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); - exit(0); - break; + exit(0); + break; + + case HELP_OPT: + usage(); + exit(0); + break; + + case Clp_NotOption: + if (input_file && font_name) + usage_error(errh, "too many arguments"); + else if (input_file) + goto font_name; + else + input_file = clp->vstr; + break; + + case Clp_Done: + goto done; - case HELP_OPT: - usage(); - exit(0); - break; - - case Clp_NotOption: - if (input_file && font_name) - usage_error(errh, "too many arguments"); - else if (input_file) - goto font_name; - else - input_file = clp->vstr; - break; - - case Clp_Done: - goto done; - - case Clp_BadOption: - usage_error(errh, 0); - break; + case Clp_BadOption: + usage_error(errh, 0); + break; - default: - break; + default: + break; - } + } } done: // check for odd option combinations if (warn_missing > 0 && !(output_flags & G_VMETRICS)) - errh->warning("%<--warn-missing%> has no effect with %<--no-virtual%>"); + errh->warning("%<--warn-missing%> has no effect with %<--no-virtual%>"); + if (!(specified_output_flags & (G_BINARY | G_ASCII))) + output_flags |= G_BINARY; // set up file names if (!input_file) - usage_error(errh, "no font filename provided"); + usage_error(errh, "no font filename provided"); if (encoding_file == "-") - encoding_file = ""; + encoding_file = ""; + + // set up output directories + if (odirs[NUMODIR]) { + for (int i = 0; i < NUMODIR; ++i) + if (!odirs[i]) + odirs[i] = odirs[NUMODIR]; + } + for (int i = 0; i < NUMODIR; ++i) + if (odirs[i]) + setodir(i, odirs[i]); // set up feature filters if (!altselector_features.size()) { - if (!current_filter_ptr) - current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); - altselector_features.push_back(OpenType::Tag("dlig")); - altselector_feature_filters.insert(OpenType::Tag("dlig"), current_filter_ptr); - altselector_features.push_back(OpenType::Tag("salt")); - altselector_feature_filters.insert(OpenType::Tag("salt"), current_filter_ptr); + if (!current_filter_ptr) { + current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); + allocated_filters.push_back(current_filter_ptr); + } + altselector_features.push_back(OpenType::Tag("dlig")); + altselector_feature_filters.insert(OpenType::Tag("dlig"), current_filter_ptr); + altselector_features.push_back(OpenType::Tag("salt")); + altselector_feature_filters.insert(OpenType::Tag("salt"), current_filter_ptr); } else if (!current_filter_ptr) { - errh->warning("some filtering options ignored"); - errh->message("(--include-*, --exclude-*, and --*-filter options must occur\nbefore the feature options to which they should apply.)"); + errh->warning("some filtering options ignored"); + errh->message("(--include-*, --exclude-*, and --*-filter options must occur\nbefore the feature options to which they should apply.)"); } try { - // read font - otf_data = read_file(input_file, errh); - if (errh->nerrors()) - exit(1); - - LandmarkErrorHandler cerrh(errh, printable_filename(input_file)); - BailErrorHandler bail_errh(&cerrh); - - OpenType::Font otf(otf_data, &bail_errh); - assert(otf.ok()); - - // figure out scripts we care about - if (!interesting_scripts.size()) { - interesting_scripts.push_back(Efont::OpenType::Tag("latn")); - interesting_scripts.push_back(Efont::OpenType::Tag()); - } - std::sort(interesting_features.begin(), interesting_features.end()); - std::sort(altselector_features.begin(), altselector_features.end()); + // read font + otf_data = read_file(input_file, errh); + if (errh->nerrors()) + exit(1); + + LandmarkErrorHandler cerrh(errh, printable_filename(input_file)); + BailErrorHandler bail_errh(&cerrh); + + OpenType::Font otf(otf_data, &bail_errh); + assert(otf.ok()); + + // figure out scripts we care about + if (!interesting_scripts.size()) { + interesting_scripts.push_back(Efont::OpenType::Tag("latn")); + interesting_scripts.push_back(Efont::OpenType::Tag()); + } + std::sort(interesting_features.begin(), interesting_features.end()); + std::sort(altselector_features.begin(), altselector_features.end()); - // find glyphlist - if (!glyphlist_files.size()) { + // find glyphlist + if (!glyphlist_files.size()) { #if HAVE_KPATHSEA - if (String g = kpsei_find_file("glyphlist.txt", KPSEI_FMT_MAP)) { - glyphlist_files.push_back(g); - if (verbose) - errh->message("glyphlist.txt found with kpathsea at %s", g.c_str()); - } else + if (String g = kpsei_find_file("glyphlist.txt", KPSEI_FMT_MAP)) { + glyphlist_files.push_back(g); + if (verbose) + errh->message("glyphlist.txt found with kpathsea at %s", g.c_str()); + } else #endif - glyphlist_files.push_back(GLYPHLISTDIR "/glyphlist.txt"); + glyphlist_files.push_back(GLYPHLISTDIR "/glyphlist.txt"); #if HAVE_KPATHSEA - if (String g = kpsei_find_file("texglyphlist.txt", KPSEI_FMT_MAP)) { - glyphlist_files.push_back(g); - if (verbose) - errh->message("texglyphlist.txt found with kpathsea at %s", g.c_str()); - } else + if (String g = kpsei_find_file("texglyphlist.txt", KPSEI_FMT_MAP)) { + glyphlist_files.push_back(g); + if (verbose) + errh->message("texglyphlist.txt found with kpathsea at %s", g.c_str()); + } else #endif - glyphlist_files.push_back(GLYPHLISTDIR "/texglyphlist.txt"); - } + glyphlist_files.push_back(GLYPHLISTDIR "/texglyphlist.txt"); + } - // read glyphlist - for (String *g = glyphlist_files.begin(); g < glyphlist_files.end(); g++) - if (String s = read_file(*g, errh, true)) - DvipsEncoding::add_glyphlist(s); - - // read base encodings - for (String *s = base_encoding_files.begin(); s < base_encoding_files.end(); s++) - parse_base_encodings(*s, errh); - - // read encoding - DvipsEncoding dvipsenc; - if (encoding_file) { - if (String path = locate_encoding(encoding_file, errh)) - dvipsenc.parse(path, no_ecommand, no_ecommand, errh); - else - errh->fatal("encoding %<%s%> not found", encoding_file.c_str()); - } else { + // read glyphlist + for (String *g = glyphlist_files.begin(); g < glyphlist_files.end(); g++) + if (String s = read_file(*g, errh, true)) + DvipsEncoding::add_glyphlist(s); + + // read base encodings + for (String *s = base_encoding_files.begin(); s < base_encoding_files.end(); s++) + parse_base_encodings(*s, errh); + + // read encoding + DvipsEncoding dvipsenc; + if (encoding_file) { + if (String path = locate_encoding(encoding_file, errh)) + dvipsenc.parse(path, no_ecommand, no_ecommand, errh); + else + errh->fatal("encoding %<%s%> not found", encoding_file.c_str()); + } else { String cff_data(otf.table("CFF")); if (!cff_data) { errh->error("explicit encoding required for TrueType fonts"); @@ -2300,42 +2396,44 @@ particular purpose.\n"); errh->message("(Use %<-e ENCODING%> to choose an encoding. %<-e texnansx%> often works,\nor say %<-e -%> to turn off this warning.)"); } - // use encoding from font - Cff cff(cff_data, otf.units_per_em(), &bail_errh); - Cff::FontParent *font = cff.font(PermString(), &bail_errh); - assert(cff.ok() && font->ok()); - if (Type1Encoding *t1e = font->type1_encoding()) { - for (int i = 0; i < 256; i++) - dvipsenc.encode(i, (*t1e)[i]); - } else - errh->fatal("font has no encoding, specify one explicitly"); - delete font; - } - - // apply default ligkern commands - if (default_ligkern) - dvipsenc.parse_ligkern(default_ligkerns, 0, ErrorHandler::silent_handler()); - - // apply command-line ligkern commands and coding scheme - cerrh.set_landmark("--ligkern command"); - for (int i = 0; i < ligkern.size(); i++) - dvipsenc.parse_ligkern(ligkern[i], 1, &cerrh); - cerrh.set_landmark("--position command"); - for (int i = 0; i < pos.size(); i++) - dvipsenc.parse_position(pos[i], 1, &cerrh); - cerrh.set_landmark("--unicoding command"); - for (int i = 0; i < unicoding.size(); i++) - dvipsenc.parse_unicoding(unicoding[i], 1, &cerrh); - if (codingscheme) - dvipsenc.set_coding_scheme(codingscheme); - if (warn_missing >= 0) - dvipsenc.set_warn_missing(warn_missing); + // use encoding from font + Cff cff(cff_data, otf.units_per_em(), &bail_errh); + Cff::FontParent *font = cff.font(PermString(), &bail_errh); + assert(cff.ok() && font->ok()); + if (Type1Encoding *t1e = font->type1_encoding()) { + for (int i = 0; i < 256; i++) + dvipsenc.encode(i, (*t1e)[i]); + } else + errh->fatal("font has no encoding, specify one explicitly"); + } + + // apply default ligkern commands + if (default_ligkern) + dvipsenc.parse_ligkern(default_ligkerns, 0, ErrorHandler::silent_handler()); + + // apply command-line ligkern commands and coding scheme + cerrh.set_landmark("--ligkern command"); + for (int i = 0; i < ligkern.size(); i++) + dvipsenc.parse_ligkern(ligkern[i], 1, &cerrh); + cerrh.set_landmark("--position command"); + for (int i = 0; i < pos.size(); i++) + dvipsenc.parse_position(pos[i], 1, &cerrh); + cerrh.set_landmark("--unicoding command"); + for (int i = 0; i < unicoding.size(); i++) + dvipsenc.parse_unicoding(unicoding[i], 1, &cerrh); + if (codingscheme) + dvipsenc.set_coding_scheme(codingscheme); + if (warn_missing >= 0) + dvipsenc.set_warn_missing(warn_missing); - do_file(input_file, otf, dvipsenc, literal_encoding, errh); + do_file(input_file, otf, dvipsenc, literal_encoding, errh); } catch (OpenType::Error e) { - errh->error("unhandled exception %<%s%>", e.description.c_str()); + errh->error("unhandled exception %<%s%>", e.description.c_str()); } + for (int i = 0; i < allocated_filters.size(); ++i) + delete allocated_filters[i]; + Clp_DeleteParser(clp); return (errh->nerrors() == 0 ? 0 : 1); } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/otftotfm.hh 2018-02-23 12:47:54.094971678 -0500 @@ -11,11 +11,11 @@ String suffix_font_name(const String &fo String installed_metrics_font_name(const String &font_name, const String &secondary); void output_metrics(Metrics &metrics, const String &ps_name, int boundary_char, - const FontInfo &finfo, - const String &encoding_name, const String &encoding_file, - const String &font_name, - String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), - ErrorHandler *errh); + const FontInfo &finfo, + const String &encoding_name, const String &encoding_file, + const String &font_name, + String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), + ErrorHandler *errh); double font_cap_height(const FontInfo &, const Transform &); double font_ascender(const FontInfo &, const Transform &); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.cc 2018-02-23 12:47:54.094971678 -0500 @@ -1,6 +1,6 @@ /* secondary.{cc,hh} -- code for generating fake glyphs * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -33,45 +33,43 @@ #include enum { - U_EXCLAMDOWN = 0x00A1, // U+00A1 INVERTED EXCLAMATION MARK - U_DEGREE = 0x00B0, // U+00B0 DEGREE SIGN - U_QUESTIONDOWN = 0x00BF, // U+00BF INVERTED QUESTION MARK - U_IJ = 0x0132, // U+0132 LATIN CAPITAL LIGATURE IJ - U_ij = 0x0133, // U+0133 LATIN SMALL LIGATURE IJ - U_DOTLESSJ = 0x0237, // U+0237 LATIN SMALL LETTER DOTLESS J - U_RINGABOVE = 0x02DA, // U+02DA RING ABOVE + U_EXCLAMDOWN = 0x00A1, // U+00A1 INVERTED EXCLAMATION MARK + U_DEGREE = 0x00B0, // U+00B0 DEGREE SIGN + U_QUESTIONDOWN = 0x00BF, // U+00BF INVERTED QUESTION MARK + U_IJ = 0x0132, // U+0132 LATIN CAPITAL LIGATURE IJ + U_ij = 0x0133, // U+0133 LATIN SMALL LIGATURE IJ + U_DOTLESSJ = 0x0237, // U+0237 LATIN SMALL LETTER DOTLESS J + U_RINGABOVE = 0x02DA, // U+02DA RING ABOVE U_COMBININGRINGABOVE = 0x030A, // U+030A COMBINING RING ABOVE - U_CWM = 0x200C, // U+200C ZERO WIDTH NON-JOINER - U_ENDASH = 0x2013, // U+2013 EN DASH - U_PERTENTHOUSAND = 0x2031, // U+2031 PER TEN THOUSAND SIGN - U_INTERROBANG = 0x203D, // U+203D INTERROBANG - U_FRACTION = 0x2044, // U+2044 FRACTION SLASH - U_CENTIGRADE = 0x2103, // U+2103 DEGREE CELSIUS - U_ASTERISKMATH = 0x2217, // U+2217 ASTERISK OPERATOR - U_BARDBL = 0x2225, // U+2225 PARALLEL TO - U_VISIBLESPACE = 0x2423, // U+2423 OPEN BOX - U_DBLBRACKETLEFT = 0x27E6, // U+27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET - U_DBLBRACKETRIGHT = 0x27E7, // U+27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET + U_CWM = 0x200C, // U+200C ZERO WIDTH NON-JOINER + U_ENDASH = 0x2013, // U+2013 EN DASH + U_PERTENTHOUSAND = 0x2031, // U+2031 PER TEN THOUSAND SIGN + U_INTERROBANG = 0x203D, // U+203D INTERROBANG + U_FRACTION = 0x2044, // U+2044 FRACTION SLASH + U_CENTIGRADE = 0x2103, // U+2103 DEGREE CELSIUS + U_ASTERISKMATH = 0x2217, // U+2217 ASTERISK OPERATOR + U_BARDBL = 0x2225, // U+2225 PARALLEL TO + U_VISIBLESPACE = 0x2423, // U+2423 OPEN BOX + U_DBLBRACKETLEFT = 0x27E6, // U+27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET + U_DBLBRACKETRIGHT = 0x27E7, // U+27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET U_INTERROBANGDOWN = 0x2E18, // U+2E18 INVERTED INTERROBANG - U_EMPTYSLOT = 0xD801, // invalid Unicode (not handled by Secondary) - U_ALTSELECTOR = 0xD802, // invalid Unicode - U_CAPITALCWM = 0xD809, // invalid Unicode - U_ASCENDERCWM = 0xD80A, // invalid Unicode - U_TWELVEUDASH = 0xD80C, // invalid Unicode - U_RINGFITTED = 0xD80D, // invalid Unicode + U_ALTSELECTOR = 0xD802, // invalid Unicode + U_CAPITALCWM = 0xD809, // invalid Unicode + U_ASCENDERCWM = 0xD80A, // invalid Unicode + U_TWELVEUDASH = 0xD80C, // invalid Unicode + U_RINGFITTED = 0xD80D, // invalid Unicode // BEGIN BACKWARDS COMPATIBILITY -- newer texglyphlist.txt does not include // these code points - U_SS = 0xD800, // invalid Unicode - U_SSSMALL = 0xD803, // invalid Unicode - U_FFSMALL = 0xD804, // invalid Unicode - U_FISMALL = 0xD805, // invalid Unicode - U_FLSMALL = 0xD806, // invalid Unicode - U_FFISMALL = 0xD807, // invalid Unicode - U_FFLSMALL = 0xD808, // invalid Unicode + U_SS = 0xD800, // invalid Unicode + U_SSSMALL = 0xD803, // invalid Unicode + U_FFSMALL = 0xD804, // invalid Unicode + U_FISMALL = 0xD805, // invalid Unicode + U_FLSMALL = 0xD806, // invalid Unicode + U_FFISMALL = 0xD807, // invalid Unicode + U_FFLSMALL = 0xD808, // invalid Unicode // END BACKWARDS COMPATIBILITY - U_USE_KERNX = 0xD80E, // invalid Unicode, not in maps U_VS1 = 0xFE00, U_VS16 = 0xFE0F, U_VS17 = 0xE0100, @@ -82,7 +80,7 @@ enum { U_ISMALL = 0xF769, U_LSMALL = 0xF76C, U_SSMALL = 0xF773, - U_MATHDOTLESSJ = 0x1D6A5 // U+1D6A5 MATHEMATICAL ITALIC SMALL DOTLESS J + U_MATHDOTLESSJ = 0x1D6A5 // U+1D6A5 MATHEMATICAL ITALIC SMALL DOTLESS J }; @@ -95,27 +93,27 @@ FontInfo::FontInfo(const Efont::OpenType assert(cmap->ok()); if (String cff_string = otf->table("CFF")) { - cff_file = new Efont::Cff(cff_string, otf->units_per_em(), errh); - if (!cff_file->ok()) - return; - Efont::Cff::FontParent *fp = cff_file->font(PermString(), errh); - if (!fp || !fp->ok()) - return; - if (!(cff = dynamic_cast(fp))) { - errh->error("CID-keyed fonts not supported"); - return; - } - _nglyphs = cff->nglyphs(); + cff_file = new Efont::Cff(cff_string, otf->units_per_em(), errh); + if (!cff_file->ok()) + return; + Efont::Cff::FontParent *fp = cff_file->font(PermString(), errh); + if (!fp || !fp->ok()) + return; + if (!(cff = dynamic_cast(fp))) { + errh->error("CID-keyed fonts not supported"); + return; + } + _nglyphs = cff->nglyphs(); } if (!cff) { - post = new Efont::OpenType::Post(otf->table("post"), errh); - // read number of glyphs from 'maxp' -- should probably be elsewhere - if (Efont::OpenType::Data maxp = otf->table("maxp")) - if (maxp.length() >= 6) - _nglyphs = maxp.u16(4); - if (_nglyphs < 0 && post->ok()) - _nglyphs = post->nglyphs(); + post = new Efont::OpenType::Post(otf->table("post"), errh); + // read number of glyphs from 'maxp' -- should probably be elsewhere + if (Efont::OpenType::Data maxp = otf->table("maxp")) + if (maxp.length() >= 6) + _nglyphs = maxp.u16(4); + if (_nglyphs < 0 && post->ok()) + _nglyphs = post->nglyphs(); } name = new Efont::OpenType::Name(otf->table("name"), errh); @@ -125,7 +123,6 @@ FontInfo::~FontInfo() { delete cmap; delete cff_file; - delete cff; delete post; delete name; delete _ttb_program; @@ -135,9 +132,9 @@ bool FontInfo::ok() const { if (cff) - return cmap->ok() && cff->ok(); + return cmap->ok() && cff->ok(); else - return post && post->ok() && name && name->ok(); + return post && post->ok() && name && name->ok(); } bool @@ -151,16 +148,16 @@ int FontInfo::glyphid(PermString name) const { if (cff) - return cff->glyphid(name); + return cff->glyphid(name); else { - if (!_got_glyph_names) { - glyph_names(_glyph_names); - _got_glyph_names = true; - } - PermString *found = std::find(_glyph_names.begin(), _glyph_names.end(), name); - if (found == _glyph_names.end()) - return 0; - return found - _glyph_names.begin(); + if (!_got_glyph_names) { + glyph_names(_glyph_names); + _got_glyph_names = true; + } + PermString *found = std::find(_glyph_names.begin(), _glyph_names.end(), name); + if (found == _glyph_names.end()) + return 0; + return found - _glyph_names.begin(); } } @@ -168,29 +165,29 @@ String FontInfo::family_name() const { if (cff) - return cff->dict_string(Efont::Cff::oFamilyName); + return cff->dict_string(Efont::Cff::oFamilyName); else - return name->english_name(Efont::OpenType::Name::N_FAMILY); + return name->english_name(Efont::OpenType::Name::N_FAMILY); } String FontInfo::postscript_name() const { if (cff) - return cff->font_name(); + return cff->font_name(); else - return name->english_name(Efont::OpenType::Name::N_POSTSCRIPT); + return name->english_name(Efont::OpenType::Name::N_POSTSCRIPT); } const Efont::CharstringProgram * FontInfo::program() const { if (cff) - return cff; + return cff; else { - if (!_ttb_program) - _ttb_program = new Efont::TrueTypeBoundsCharstringProgram(otf); - return _ttb_program; + if (!_ttb_program) + _ttb_program = new Efont::TrueTypeBoundsCharstringProgram(otf); + return _ttb_program; } } @@ -198,25 +195,25 @@ bool FontInfo::is_fixed_pitch() const { if (_override_is_fixed_pitch) - return _is_fixed_pitch; + return _is_fixed_pitch; else if (cff) { - double d; - return (cff->dict_value(Efont::Cff::oIsFixedPitch, &d) && d); + double d; + return (cff->dict_value(Efont::Cff::oIsFixedPitch, &d) && d); } else - return post->is_fixed_pitch(); + return post->is_fixed_pitch(); } double FontInfo::italic_angle() const { if (_override_italic_angle) - return _italic_angle; + return _italic_angle; else if (cff) { - double d; - (void) cff->dict_value(Efont::Cff::oItalicAngle, &d); - return d; + double d; + (void) cff->dict_value(Efont::Cff::oItalicAngle, &d); + return d; } else - return post->italic_angle(); + return post->italic_angle(); } double FontInfo::x_height(const Transform& font_xform) const { @@ -224,8 +221,8 @@ double FontInfo::x_height(const Transfor return _x_height; double x1 = -1, x2 = -1; if (_override_x_height != x_height_os2) - // XXX what if 'x', 'm', 'z' were subject to substitution? - x1 = char_one_bound(*this, font_xform, 3, false, units_per_em(), + // XXX what if 'x', 'm', 'z' were subject to substitution? + x1 = char_one_bound(*this, font_xform, 3, false, units_per_em(), (int) 'x', (int) 'm', (int) 'z', 0); if (_override_x_height != x_height_x) try { @@ -234,8 +231,10 @@ double FontInfo::x_height(const Transfor } catch (Efont::OpenType::Bounds) { } static bool warned = false; - if (_override_x_height == x_height_auto && x1 >= 0 && x2 >= 0 - && fabs(x1 - x2) > units_per_em() / 100.) { + if (_override_x_height == x_height_auto + && x1 >= 0 + && x2 >= 0 + && fabs(x1 - x2) > units_per_em() / 50.) { if (!warned) { ErrorHandler* errh = ErrorHandler::default_handler(); errh->warning("font x-height and height of % differ by %d%%", (int) (fabs(x1 - x2) * 100 / units_per_em())); @@ -256,115 +255,82 @@ Secondary::~Secondary() bool Secondary::encode_uni(int code, PermString name, - const uint32_t *uni_begin, const uint32_t *uni_end, - Metrics &metrics, ErrorHandler *errh) + const uint32_t* uni_begin, const uint32_t* uni_end, + Metrics &metrics, ErrorHandler *errh) { + uint32_t uni = 0; if (uni_begin + 1 == uni_end) - return encode_uni(code, name, *uni_begin, metrics, errh); - else { - Vector v; - int max_s = 0; - while (uni_begin != uni_end) { - Vector subv; - int s = setting(*uni_begin, subv, metrics, errh); - if (s == 0) - return false; - if (subv.size() && v.size()) - v.push_back(Setting(Setting::KERN)); - for (Vector::const_iterator it = subv.begin(); - it != subv.end(); ++it) - v.push_back(*it); - max_s = (max_s > s ? max_s : s); - ++uni_begin; - } - metrics.encode_virtual(code, name, 0, v, max_s > 1); - return true; + uni = *uni_begin; + + SettingSet set(this, metrics); + int max_s = 0; + while (uni_begin != uni_end) { + int s = setting(*uni_begin, set, errh); + if (s == 0) + return false; + max_s = (max_s > s ? max_s : s); + ++uni_begin; + set.checkpoint(); } -} -bool -Secondary::encode_uni(int code, PermString name, uint32_t uni, Metrics &metrics, ErrorHandler *errh) -{ - Vector v; - if (int s = setting(uni, v, metrics, errh)) { - metrics.encode_virtual(code, name, uni, v, s > 1); - return true; - } else if (_next) - return _next->encode_uni(code, name, uni, metrics, errh); - else - return false; + if (uni == U_ALTSELECTOR + || (uni >= U_VS1 && uni <= U_VS16) + || (uni >= U_VS17 && uni <= U_VS256)) { + int selector = 0; + if (uni >= U_VS1 && uni <= U_VS16) + selector = uni - U_VS1 + 1; + else if (uni >= U_VS17 && uni <= U_VS256) + selector = uni - U_VS17 + 17; + metrics.add_altselector_code(code, selector); + name = selector ? permprintf("", selector) : PermString(""); + } + + metrics.encode_virtual(code, name, 0, set.settings(), max_s > 1); + return true; } T1Secondary::T1Secondary(const FontInfo &finfo, const String &font_name, - const String &otf_file_name) - : _finfo(finfo), _font_name(font_name), _otf_file_name(otf_file_name), + const String &otf_file_name) + : Secondary(finfo), _font_name(font_name), _otf_file_name(otf_file_name), _units_per_em(finfo.units_per_em()), _xheight((int) ceil(finfo.x_height(Transform()))), _spacewidth(_units_per_em) { double bounds[4], width; if (char_bounds(bounds, width, finfo, Transform(), ' ')) - _spacewidth = (int) ceil(width); + _spacewidth = (int) ceil(width); } int -Secondary::setting(uint32_t uni, Vector &v, Metrics &metrics, ErrorHandler *errh) +Secondary::setting(uint32_t uni, SettingSet& set, ErrorHandler *errh) { if (_next) - return _next->setting(uni, v, metrics, errh); + return _next->setting(uni, set, errh); else - return 0; + return 0; } -bool -T1Secondary::char_setting(Vector &v, Metrics &metrics, int uni, ...) -{ - Vector codes; - - // collect codes - va_list val; - va_start(val, uni); - - int kerntype = Setting::KERN; - if (uni == U_USE_KERNX) { - kerntype = Setting::KERNX; - uni = va_arg(val, int); - } - - for (; uni; uni = va_arg(val, int)) { - int code = metrics.unicode_encoding(uni); - if (code < 0) { - Glyph glyph = _finfo.cmap->map_uni(uni); - if (glyph == 0 || (code = metrics.force_encoding(glyph)) < 0) - return false; - } - codes.push_back(code); - } - va_end(val); - - // generate setting - for (int i = 0; i < codes.size(); i++) { - if (i) - v.push_back(Setting(kerntype)); - v.push_back(Setting(Setting::SHOW, codes[i], metrics.base_glyph(codes[i]))); +SettingSet& SettingSet::show(int uni) { + if (!ok_) + return *this; + int code = metrics_.unicode_encoding(uni); + if (code < 0) { + Glyph glyph = s_->_finfo.cmap->map_uni(uni); + if (glyph != 0) + code = metrics_.force_encoding(glyph); + } + if (code < 0) { + ok_ = false; + while (v_.size() > original_size_) + v_.pop_back(); + } else { + if (!v_.empty() + && v_.back().op == Setting::SHOW + && kern_type_) + v_.push_back(Setting(kern_type_)); + v_.push_back(Setting(Setting::SHOW, code, metrics_.base_glyph(code))); } - return true; -} - -bool -T1Secondary::encode_uni(int code, PermString name, uint32_t uni, Metrics &metrics, ErrorHandler *errh) -{ - if (uni == U_ALTSELECTOR - || (uni >= U_VS1 && uni <= U_VS16) - || (uni >= U_VS17 && uni <= U_VS256)) { - Vector v; - setting(uni, v, metrics, errh); - int which = (uni == U_ALTSELECTOR ? 0 : (uni <= U_VS16 ? uni - U_VS1 + 1 : uni - U_VS17 + 17)); - metrics.encode_virtual(code, (which ? permprintf("", which) : PermString("")), uni, v, false); - metrics.add_altselector_code(code, which); - return true; - } else - return Secondary::encode_uni(code, name, uni, metrics, errh); + return *this; } @@ -380,355 +346,333 @@ int T1Secondary::dotlessj_font(Metrics &metrics, ErrorHandler *errh, Glyph &dj_glyph) { if (!_font_name || !_finfo.otf || !_finfo.cff) - return -1; + return -1; String dj_name; bool install_metrics; // XXX make sure dotlessj is for the main font? if ((dj_name = installed_metrics_font_name(_font_name, "dotlessj"))) - install_metrics = false; + install_metrics = false; else { - dj_name = suffix_font_name(_font_name, "--lcdfj"); - install_metrics = true; + dj_name = suffix_font_name(_font_name, "--lcdfj"); + install_metrics = true; } // is dotlessj already mapped? for (int i = 0; i < metrics.n_mapped_fonts(); i++) - if (metrics.mapped_font_name(i) == dj_name) - return i; + if (metrics.mapped_font_name(i) == dj_name) + return i; if (String filename = installed_type1_dotlessj(_otf_file_name, _finfo.cff->font_name(), (output_flags & G_DOTLESSJ), errh)) { - // check for special case: "\0" means the font's "j" is already - // dotless - if (filename == String("\0", 1)) - return J_NODOT; - - // open dotless-j font file - FILE *f = fopen(filename.c_str(), "rb"); - if (!f) { - errh->error("%s: %s", filename.c_str(), strerror(errno)); - return -1; - } - - // read font - Efont::Type1Reader *reader; - int c = getc(f); - ungetc(c, f); - if (c == 128) - reader = new Efont::Type1PFBReader(f); - else - reader = new Efont::Type1PFAReader(f); - Efont::Type1Font *font = new Efont::Type1Font(*reader); - delete reader; - - if (!font->ok()) { - errh->error("%s: no glyphs in dotless-J font", filename.c_str()); - delete font; - return -1; - } - - // find dotless-J character - Vector glyph_names; - font->glyph_names(glyph_names); - Vector::iterator g = std::find(glyph_names.begin(), glyph_names.end(), "uni0237"); - if (g == glyph_names.end()) { - errh->error("%s: dotless-J font has no % glyph", filename.c_str()); - delete font; - return -1; - } - dj_glyph = g - glyph_names.begin(); - - // create metrics for dotless-J - if (install_metrics) { - Metrics dj_metrics(font, 256); - dj_metrics.encode('j', U_DOTLESSJ, dj_glyph); - ::dotlessj_file_name = filename; - output_metrics(dj_metrics, font->font_name(), -1, _finfo, String(), String(), dj_name, dotlessj_dvips_include, errh); - } else if (verbose) - errh->message("using %<%s%> for dotless-J font metrics", dj_name.c_str()); + // check for special case: "\0" means the font's "j" is already + // dotless + if (filename == String("\0", 1)) + return J_NODOT; + + // open dotless-j font file + FILE *f = fopen(filename.c_str(), "rb"); + if (!f) { + errh->error("%s: %s", filename.c_str(), strerror(errno)); + return -1; + } - // add font to metrics - return metrics.add_mapped_font(font, dj_name); + // read font + Efont::Type1Reader *reader; + int c = getc(f); + ungetc(c, f); + if (c == 128) + reader = new Efont::Type1PFBReader(f); + else + reader = new Efont::Type1PFAReader(f); + Efont::Type1Font *font = new Efont::Type1Font(*reader); + delete reader; + + if (!font->ok()) { + errh->error("%s: no glyphs in dotless-J font", filename.c_str()); + delete font; + return -1; + } + + // find dotless-J character + Vector glyph_names; + font->glyph_names(glyph_names); + Vector::iterator g = std::find(glyph_names.begin(), glyph_names.end(), "uni0237"); + if (g == glyph_names.end()) { + errh->error("%s: dotless-J font has no % glyph", filename.c_str()); + delete font; + return -1; + } + dj_glyph = g - glyph_names.begin(); + + // create metrics for dotless-J + if (install_metrics) { + Metrics dj_metrics(font, 256); + dj_metrics.encode('j', U_DOTLESSJ, dj_glyph); + ::dotlessj_file_name = filename; + output_metrics(dj_metrics, font->font_name(), -1, _finfo, String(), String(), dj_name, dotlessj_dvips_include, errh); + } else if (verbose) + errh->message("using %<%s%> for dotless-J font metrics", dj_name.c_str()); + + // add font to metrics + return metrics.add_mapped_font(font, dj_name); } else - return -1; + return -1; } int -T1Secondary::setting(uint32_t uni, Vector &v, Metrics &metrics, ErrorHandler *errh) +T1Secondary::setting(uint32_t uni, SettingSet& set, ErrorHandler *errh) { Transform xform; - int vsize = v.size(); extern int letterspace; - if (char_setting(v, metrics, uni, 0)) - return 1; + if (set.show(uni).check()) + return 1; switch (uni) { case U_CWM: case U_ALTSELECTOR: - v.push_back(Setting(Setting::RULE, 0, _xheight)); - return 1; + set.push_back(Setting::RULE, 0, _xheight); + return 1; case U_CAPITALCWM: - v.push_back(Setting(Setting::RULE, 0, font_cap_height(_finfo, xform))); - return 1; + set.push_back(Setting::RULE, 0, font_cap_height(_finfo, xform)); + return 1; case U_ASCENDERCWM: - v.push_back(Setting(Setting::RULE, 0, font_ascender(_finfo, xform))); - return 1; + set.push_back(Setting::RULE, 0, font_ascender(_finfo, xform)); + return 1; case U_VISIBLESPACE: { int sb = (int) (0.050 * _units_per_em), h = (int) (0.150 * _units_per_em), lw = (int) (0.040 * _units_per_em); - v.push_back(Setting(Setting::MOVE, sb, -h)); - v.push_back(Setting(Setting::RULE, lw, h)); - v.push_back(Setting(Setting::RULE, _spacewidth, lw)); - v.push_back(Setting(Setting::RULE, lw, h)); - v.push_back(Setting(Setting::MOVE, sb, h)); - return 2; - } - - case U_SS: - if (char_setting(v, metrics, 'S', 'S', 0)) - return 1; - break; - - case U_SSSMALL: - if (char_setting(v, metrics, U_SSMALL, U_SSMALL, 0)) - return 1; - else if (char_setting(v, metrics, 's', 's', 0)) - return 1; - break; + set.move(sb, -h); + set.push_back(Setting::RULE, lw, h); + set.push_back(Setting::RULE, _spacewidth, lw); + set.push_back(Setting::RULE, lw, h); + set.move(sb, h); + return 2; + } + + case U_SS: + if (set.show('S').show('S').check()) + return 1; + break; + + case U_SSSMALL: + if (set.show(U_SSMALL).show(U_SSMALL).check() + || set.show('s').show('s').check()) + return 1; + break; case U_FFSMALL: - if (char_setting(v, metrics, U_FSMALL, U_FSMALL, 0)) - return 1; - else if (char_setting(v, metrics, 'f', 'f', 0)) - return 1; - break; + if (set.show(U_FSMALL).show(U_FSMALL).check() + || set.show('f').show('f').check()) + return 1; + break; case U_FISMALL: - if (char_setting(v, metrics, U_FSMALL, U_ISMALL, 0)) - return 1; - else if (char_setting(v, metrics, 'f', 'i', 0)) - return 1; - break; + if (set.show(U_FSMALL).show(U_ISMALL).check() + || set.show('f').show('i').check()) + return 1; + break; case U_FLSMALL: - if (char_setting(v, metrics, U_FSMALL, U_LSMALL, 0)) - return 1; - else if (char_setting(v, metrics, 'f', 'l', 0)) - return 1; - break; + if (set.show(U_FSMALL).show(U_LSMALL).check() + || set.show('f').show('l').check()) + return 1; + break; case U_FFISMALL: - if (char_setting(v, metrics, U_FSMALL, U_FSMALL, U_ISMALL, 0)) - return 1; - else if (char_setting(v, metrics, 'f', 'f', 'i', 0)) - return 1; - break; + if (set.show(U_FSMALL).show(U_FSMALL).show(U_ISMALL).check() + || set.show('f').show('f').show('i').check()) + return 1; + break; case U_FFLSMALL: - if (char_setting(v, metrics, U_FSMALL, U_FSMALL, U_LSMALL, 0)) - return 1; - else if (char_setting(v, metrics, 'f', 'f', 'l', 0)) - return 1; - break; + if (set.show(U_FSMALL).show(U_FSMALL).show(U_LSMALL).check() + || set.show('f').show('f').show('l').check()) + return 1; + break; case U_IJ: - if (char_setting(v, metrics, 'I', 'J', 0)) - return 1; - break; + if (set.show('I').show('J').check()) + return 1; + break; case U_ij: - if (char_setting(v, metrics, 'i', 'j', 0)) - return 1; - break; + if (set.show('i').show('j').check()) + return 1; + break; case U_DOTLESSJ: case U_DOTLESSJ_2: case U_MATHDOTLESSJ: { - Glyph dj_glyph; - int which = dotlessj_font(metrics, errh, dj_glyph); - if (which >= 0) { - v.push_back(Setting(Setting::FONT, which)); - v.push_back(Setting(Setting::SHOW, 'j', dj_glyph)); - return 2; - } else if (which == J_NODOT && char_setting(v, metrics, 'j', 0)) - return 1; - break; + Glyph dj_glyph; + int which = dotlessj_font(set.metrics(), errh, dj_glyph); + if (which >= 0) { + set.push_back(Setting::FONT, which); + set.push_back(Setting::SHOW, 'j', dj_glyph); + return 2; + } else if (which == J_NODOT && set.show('j').check()) + return 1; + break; } case U_DBLBRACKETLEFT: - if (char_setting(v, metrics, '[', 0)) { - if (!_finfo.is_fixed_pitch()) { - double d = char_one_bound(_finfo, xform, 4, true, 0, '[', 0); - v.push_back(Setting(Setting::MOVE, (int) (-0.666 * d - letterspace), 0)); - } - char_setting(v, metrics, '[', 0); - return 1; - } - break; + if (set.show('[').check()) { + if (!_finfo.is_fixed_pitch()) { + double d = char_one_bound(_finfo, xform, 4, true, 0, '[', 0); + set.move((int) (-0.666 * d - letterspace)); + } + set.show('['); + return 1; + } + break; case U_DBLBRACKETRIGHT: - if (char_setting(v, metrics, ']', 0)) { - if (!_finfo.is_fixed_pitch()) { - double d = char_one_bound(_finfo, xform, 4, true, 0, ']', 0); - v.push_back(Setting(Setting::MOVE, (int) (-0.666 * d - letterspace), 0)); - } - char_setting(v, metrics, ']', 0); - return 1; - } - break; + if (set.show(']').check()) { + if (!_finfo.is_fixed_pitch()) { + double d = char_one_bound(_finfo, xform, 4, true, 0, ']', 0); + set.move((int) (-0.666 * d - letterspace)); + } + set.show(']'); + return 1; + } + break; case U_BARDBL: - if (char_setting(v, metrics, '|', 0)) { - if (!_finfo.is_fixed_pitch()) { - double d = char_one_bound(_finfo, Transform(), 4, true, 0, '|', 0); - v.push_back(Setting(Setting::MOVE, (int) (-0.333 * d - letterspace), 0)); - } - char_setting(v, metrics, '|', 0); - return 1; - } - break; + if (set.show('|').check()) { + if (!_finfo.is_fixed_pitch()) { + double d = char_one_bound(_finfo, Transform(), 4, true, 0, '|', 0); + set.move((int) (-0.333 * d - letterspace)); + } + set.show('|'); + return 1; + } + break; case U_ASTERISKMATH: { - double bounds[5]; - double dropdown = 0; - if (char_bounds(bounds, bounds[4], _finfo, xform, '*')) - dropdown += std::max(bounds[3], 0.) + std::min(bounds[1], 0.); - if (char_bounds(bounds, bounds[4], _finfo, xform, '(')) - dropdown -= std::max(bounds[3], 0.) + std::min(bounds[1], 0.); - v.push_back(Setting(Setting::MOVE, 0, (int) (-dropdown / 2))); - if (char_setting(v, metrics, '*', 0)) { - v.push_back(Setting(Setting::MOVE, 0, -(int) (-dropdown / 2))); - return 1; - } - break; + double bounds[5]; + double dropdown = 0; + if (char_bounds(bounds, bounds[4], _finfo, xform, '*')) + dropdown += std::max(bounds[3], 0.) + std::min(bounds[1], 0.); + if (char_bounds(bounds, bounds[4], _finfo, xform, '(')) + dropdown -= std::max(bounds[3], 0.) + std::min(bounds[1], 0.); + int dy = (int) (-dropdown / 2); + if (set.move(0, dy).show('*').move(0, -dy).check()) + return 1; + break; } case U_TWELVEUDASH: - if (char_setting(v, metrics, U_ENDASH, 0)) { - if (!_finfo.is_fixed_pitch()) { - double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); - v.push_back(Setting(Setting::MOVE, (int) (_units_per_em * 0.667 - 2 * d - letterspace), 0)); - } - char_setting(v, metrics, U_ENDASH, 0); - return 1; - } - break; + if (set.show(U_ENDASH).check()) { + if (!_finfo.is_fixed_pitch()) { + double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); + set.move((int) (_units_per_em * 0.667 - 2 * d - letterspace)); + } + set.show(U_ENDASH); + return 1; + } + break; case U_THREEQUARTERSEMDASH: - if (char_setting(v, metrics, U_ENDASH, 0)) { - if (!_finfo.is_fixed_pitch()) { - double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); - v.push_back(Setting(Setting::MOVE, (int) (_units_per_em * 0.750 - 2 * d - letterspace), 0)); - } - char_setting(v, metrics, U_ENDASH, 0); - return 1; - } - break; + if (set.show(U_ENDASH).check()) { + if (!_finfo.is_fixed_pitch()) { + double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); + set.move((int) (_units_per_em * 0.750 - 2 * d - letterspace)); + } + set.show(U_ENDASH); + return 1; + } + break; case U_CENTIGRADE: // TODO: set italic correction to that of a 'C' - if (char_setting(v, metrics, U_USE_KERNX, U_DEGREE, 'C', 0)) - return 1; - break; + if (set.show(U_DEGREE).kernx(true).show('C').kernx(false).check()) + return 1; + break; case U_INTERROBANG: { - double exclam_offset = - (char_one_bound(_finfo, xform, 4, true, 0, '?', 0) - - char_one_bound(_finfo, xform, 4, true, 0, '!', 0)) * 0.5 + double exclam_offset = + (char_one_bound(_finfo, xform, 4, true, 0, '?', 0) + - char_one_bound(_finfo, xform, 4, true, 0, '!', 0)) * 0.5 + 0.050 * _units_per_em; - v.push_back(Setting(Setting::PUSH)); - v.push_back(Setting(Setting::MOVE, (int) exclam_offset, 0)); - if (char_setting(v, metrics, '!', 0)) { - v.push_back(Setting(Setting::POP)); - if (char_setting(v, metrics, '?', 0)) - return 1; - } - break; + if (set.push_back(Setting::PUSH).move((int) exclam_offset) + .show('!').push_back(Setting::POP).show('?').check()) + return 1; + break; } case U_INTERROBANGDOWN: { - double exclam_offset = - (char_one_bound(_finfo, xform, 4, true, 0, U_QUESTIONDOWN, 0) - - char_one_bound(_finfo, xform, 4, true, 0, U_EXCLAMDOWN, 0)) * 0.5 + double exclam_offset = + (char_one_bound(_finfo, xform, 4, true, 0, U_QUESTIONDOWN, 0) + - char_one_bound(_finfo, xform, 4, true, 0, U_EXCLAMDOWN, 0)) * 0.5 + 0.050 * _units_per_em; - v.push_back(Setting(Setting::PUSH)); - v.push_back(Setting(Setting::MOVE, (int) exclam_offset, 0)); - if (char_setting(v, metrics, U_EXCLAMDOWN, 0)) { - v.push_back(Setting(Setting::POP)); - if (char_setting(v, metrics, U_QUESTIONDOWN, 0)) - return 1; - } - break; + if (set.push_back(Setting::PUSH).move((int) exclam_offset) + .show(U_EXCLAMDOWN).push_back(Setting::POP).show(U_QUESTIONDOWN).check()) + return 1; + break; } case U_PERTENTHOUSAND: - if (char_setting(v, metrics, U_USE_KERNX, 0xF661, U_FRACTION, 0xF655, 0xF655, 0xF655, 0)) - return 1; - break; + if (set.show(0xF661).kernx(true).show(U_FRACTION) + .show(0xF655).show(0xF655).show(0xF655).kernx(false).check()) + return 1; + break; case U_RINGFITTED: { - int A_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, 'A', 0); - uint32_t ring_char = U_RINGABOVE; - int ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); - if (ring_width <= -_units_per_em) { - ring_char = U_COMBININGRINGABOVE; - ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); - } - if (A_width > -_units_per_em && ring_width > -_units_per_em) { - int offset = (A_width - ring_width) / 2; - v.push_back(Setting(Setting::MOVE, offset, 0)); - if (char_setting(v, metrics, ring_char, 0)) { - v.push_back(Setting(Setting::MOVE, A_width - ring_width - offset, 0)); - return 1; - } - } - break; + int A_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, 'A', 0); + uint32_t ring_char = U_RINGABOVE; + int ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); + if (ring_width <= -_units_per_em) { + ring_char = U_COMBININGRINGABOVE; + ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); + } + if (A_width > -_units_per_em && ring_width > -_units_per_em) { + int offset = (A_width - ring_width) / 2; + if (set.move(offset).show(ring_char).move(A_width - ring_width - offset).check()) { + return 1; + } + } + break; } } - // didn't find a good setting, restore v to pristine state - while (v.size() > vsize) - v.pop_back(); - // variant selectors get the same setting as ALTSELECTOR if ((uni >= U_VS1 && uni <= U_VS16) || (uni >= U_VS17 && uni <= U_VS256)) - return setting(U_ALTSELECTOR, v, metrics, errh); + return setting(U_ALTSELECTOR, set, errh); // otherwise, try other secondaries - return Secondary::setting(uni, v, metrics, errh); + return Secondary::setting(uni, set, errh); } bool char_bounds(double bounds[4], double& width, const FontInfo &finfo, - const Transform &transform, uint32_t uni) + const Transform &transform, uint32_t uni) { if (Efont::OpenType::Glyph g = finfo.cmap->map_uni(uni)) - return Efont::CharstringBounds::bounds(transform, finfo.program()->glyph_context(g), bounds, width); + return Efont::CharstringBounds::bounds(transform, finfo.program()->glyph_context(g), bounds, width); else - return false; + return false; } double char_one_bound(const FontInfo &finfo, const Transform &transform, - int dimen, bool max, double best, int uni, ...) + int dimen, bool max, double best, int uni, ...) { double bounds[5]; va_list val; va_start(val, uni); while (uni != 0) { - if (char_bounds(bounds, bounds[4], finfo, transform, uni)) - if (max ? bounds[dimen] > best : bounds[dimen] < best) - best = bounds[dimen]; - uni = va_arg(val, int); + if (char_bounds(bounds, bounds[4], finfo, transform, uni)) + if (max ? bounds[dimen] > best : bounds[dimen] < best) + best = bounds[dimen]; + uni = va_arg(val, int); } va_end(val); return best; @@ -738,12 +682,12 @@ double font_cap_height(const FontInfo &finfo, const Transform &font_xform) { try { - Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); - return os2.cap_height(); + Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); + return os2.cap_height(); } catch (Efont::OpenType::Bounds) { - // XXX what if 'H', 'O', 'B' were subject to substitution? - return char_one_bound(finfo, font_xform, 3, false, finfo.units_per_em(), - (int) 'H', (int) 'O', (int) 'B', 0); + // XXX what if 'H', 'O', 'B' were subject to substitution? + return char_one_bound(finfo, font_xform, 3, false, finfo.units_per_em(), + (int) 'H', (int) 'O', (int) 'B', 0); } } @@ -751,12 +695,12 @@ double font_ascender(const FontInfo &finfo, const Transform &font_xform) { try { - Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); - return os2.typo_ascender(); + Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); + return os2.typo_ascender(); } catch (Efont::OpenType::Bounds) { - // XXX what if 'd', 'l' were subject to substitution? - return char_one_bound(finfo, font_xform, 3, true, - finfo.x_height(font_xform), - (int) 'd', (int) 'l', 0); + // XXX what if 'd', 'l' were subject to substitution? + return char_one_bound(finfo, font_xform, 3, true, + finfo.x_height(font_xform), + (int) 'd', (int) 'l', 0); } } diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/secondary.hh 2018-02-23 12:47:54.094971678 -0500 @@ -2,9 +2,10 @@ #define OTFTOTFM_SECONDARY_HH #include #include +#include "setting.hh" class Metrics; +class Secondary; class Transform; -struct Setting; namespace Efont { class TrueTypeBoundsCharstringProgram; } struct FontInfo { @@ -23,12 +24,12 @@ struct FontInfo { bool ok() const; - int nglyphs() const { return _nglyphs; } + int nglyphs() const { return _nglyphs; } bool glyph_names(Vector &) const; int glyphid(PermString) const; const Efont::CharstringProgram *program() const; int units_per_em() const { - return program()->units_per_em(); + return program()->units_per_em(); } bool is_fixed_pitch() const; @@ -36,12 +37,12 @@ struct FontInfo { double x_height(const Transform& font_xform) const; void set_is_fixed_pitch(bool is_fixed_pitch) { - _override_is_fixed_pitch = true; - _is_fixed_pitch = is_fixed_pitch; + _override_is_fixed_pitch = true; + _is_fixed_pitch = is_fixed_pitch; } void set_italic_angle(double italic_angle) { - _override_italic_angle = true; - _italic_angle = italic_angle; + _override_italic_angle = true; + _italic_angle = italic_angle; } enum { x_height_auto = 0, x_height_explicit, x_height_os2, x_height_x }; @@ -69,38 +70,108 @@ struct FontInfo { }; +class SettingSet { +public: + inline SettingSet(Secondary* s, Metrics& m); + inline SettingSet& push_back(Setting s); + inline SettingSet& push_back(int op, int x = 0, int y = 0); + inline SettingSet& move(int x, int y = 0); + SettingSet& show(int uni); + inline SettingSet& kernx(bool is_kernx); + inline bool check(); + inline void checkpoint(); + inline Metrics& metrics() const; + inline const Vector& settings() const; +private: + Secondary* s_; + Vector v_; + int original_size_; + Metrics& metrics_; + int kern_type_; + bool ok_; + typedef Efont::OpenType::Glyph Glyph; +}; + class Secondary { public: - Secondary() : _next(0) { } + Secondary(const FontInfo& finfo) : _finfo(finfo), _next(0) { } virtual ~Secondary(); - void set_next(Secondary *s) { _next = s; } + void set_next(Secondary *s) { _next = s; } typedef Efont::OpenType::Glyph Glyph; - bool encode_uni(int code, PermString name, const uint32_t *uni_begin, const uint32_t *uni_end, Metrics &metrics, ErrorHandler *errh); - virtual bool encode_uni(int code, PermString name, uint32_t uni, Metrics &, ErrorHandler *); - virtual int setting(uint32_t uni, Vector &, Metrics &, ErrorHandler *); + bool encode_uni(int code, PermString name, const uint32_t* uni_first, const uint32_t* uni_last, Metrics &metrics, ErrorHandler *errh); + inline bool encode_uni(int code, PermString name, uint32_t uni, Metrics& m, ErrorHandler* errh); + virtual int setting(uint32_t uni, SettingSet&, ErrorHandler *); + protected: + const FontInfo& _finfo; + + friend class SettingSet; private: Secondary *_next; }; class T1Secondary : public Secondary { public: T1Secondary(const FontInfo &, const String &font_name, const String &otf_file_name); - bool encode_uni(int code, PermString name, uint32_t uni, Metrics &, ErrorHandler *); - int setting(uint32_t uni, Vector &, Metrics &, ErrorHandler *); + int setting(uint32_t uni, SettingSet&, ErrorHandler *); private: - const FontInfo &_finfo; String _font_name; String _otf_file_name; int _units_per_em; int _xheight; int _spacewidth; - bool char_setting(Vector &, Metrics &, int uni, ...); enum { J_NODOT = -1031892 /* unlikely value */ }; int dotlessj_font(Metrics &, ErrorHandler *, Glyph &dj_glyph); }; bool char_bounds(double bounds[4], double& width, const FontInfo &, - const Transform &, uint32_t uni); + const Transform &, uint32_t uni); double char_one_bound(const FontInfo &, const Transform &, int dimen, bool max, double best, int uni, ...); +inline SettingSet::SettingSet(Secondary* s, Metrics& m) + : s_(s), original_size_(0), metrics_(m), + kern_type_(Setting::KERN), ok_(true) { +} + +inline SettingSet& SettingSet::kernx(bool is_kernx) { + kern_type_ = is_kernx ? Setting::KERNX : Setting::KERN; + return *this; +} + +inline SettingSet& SettingSet::push_back(Setting s) { + if (ok_) + v_.push_back(s); + return *this; +} + +inline SettingSet& SettingSet::push_back(int op, int x, int y) { + return push_back(Setting(op, x, y)); +} + +inline SettingSet& SettingSet::move(int x, int y) { + return push_back(Setting(Setting::MOVE, x, y)); +} + +inline bool SettingSet::check() { + bool ok = ok_; + ok_ = true; + return ok; +} + +inline void SettingSet::checkpoint() { + assert(ok_); + original_size_ = v_.size(); +} + +inline Metrics& SettingSet::metrics() const { + return metrics_; +} + +inline const Vector& SettingSet::settings() const { + return v_; +} + +inline bool Secondary::encode_uni(int code, PermString name, uint32_t uni, Metrics& m, ErrorHandler* errh) { + return encode_uni(code, name, &uni, &uni + 1, m, errh); +} + #endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/setting.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/setting.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/setting.hh.git4166ff9 2018-02-23 12:59:25.406658041 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/setting.hh 2018-02-23 12:59:10.984019250 -0500 @@ -0,0 +1,18 @@ +#ifndef OTFTOTFM_SETTING_HH +#define OTFTOTFM_SETTING_HH +#include + +struct Setting { + enum { NONE, FONT, SHOW, KERN, KERNX, MOVE, RULE, PUSH, POP, + SPECIAL, DEAD }; + int op; + int x; + int y; + String s; + Setting(int op_in, int x_in = 0, int y_in = 0) + : op(op_in), x(x_in), y(y_in) { } + Setting(int op_in, const String &s_in) : op(op_in), s(s_in) { } + bool valid_op() const { return op >= FONT && op <= SPECIAL; } +}; + +#endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.cc 2018-02-23 12:47:54.095971653 -0500 @@ -1,6 +1,6 @@ /* uniprop.{cc,hh} -- code for Unicode character properties * - * Copyright (c) 2004-2016 Eddie Kohler + * Copyright (c) 2004-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -25,12 +25,12 @@ const unsigned char UnicodeProperty::pro 0, P_Lul, 48, P_Cn, 49, P_Lu, 87, P_Cn, 89, P_Lm, 90, P_Po, 96, P_Cn, 97, P_Ll, 136, P_Cn, 137, P_Po, 138, P_Pd, 139, P_Cn, 141, P_So, 143, P_Sc, 144, P_Cn, 145, P_Mn, 190, P_Pd, 191, P_Mn, 192, P_Po, 193, P_Mn, 195, P_Po, 196, P_Mn, 198, P_Po, 199, P_Mn, 200, P_Cn, 208, P_Lo, 235, P_Cn, 240, P_Lo, 243, P_Po, 245, P_Cn, 0, P_Cf, 6, P_Sm, 9, P_Po, 11, P_Sc, 12, P_Po, 14, P_So, 16, P_Mn, 27, P_Po, 28, P_Cf, 29, P_Cn, 30, P_Po, 32, P_Lo, 64, P_Lm, 65, P_Lo, 75, P_Mn, 96, P_Nd, 106, P_Po, 110, P_Lo, 112, P_Mn, 113, P_Lo, 212, P_Po, 213, P_Lo, 214, P_Mn, 221, P_Cf, 222, P_So, 223, P_Mn, 229, P_Lm, 231, P_Mn, 233, P_So, 234, P_Mn, 238, P_Lo, 240, P_Nd, 250, P_Lo, 253, P_So, 255, P_Lo, 0, P_Po, 14, P_Cn, 15, P_Cf, 16, P_Lo, 17, P_Mn, 18, P_Lo, 48, P_Mn, 75, P_Cn, 77, P_Lo, 166, P_Mn, 177, P_Lo, 178, P_Cn, 192, P_Nd, 202, P_Lo, 235, P_Mn, 244, P_Lm, 246, P_So, 247, P_Po, 250, P_Lm, 251, P_Cn, - 0, P_Lo, 22, P_Mn, 26, P_Lm, 27, P_Mn, 36, P_Lm, 37, P_Mn, 40, P_Lm, 41, P_Mn, 46, P_Cn, 48, P_Po, 63, P_Cn, 64, P_Lo, 89, P_Mn, 92, P_Cn, 94, P_Po, 95, P_Cn, 160, P_Lo, 181, P_Cn, 227, P_Mn, + 0, P_Lo, 22, P_Mn, 26, P_Lm, 27, P_Mn, 36, P_Lm, 37, P_Mn, 40, P_Lm, 41, P_Mn, 46, P_Cn, 48, P_Po, 63, P_Cn, 64, P_Lo, 89, P_Mn, 92, P_Cn, 94, P_Po, 95, P_Cn, 160, P_Lo, 181, P_Cn, 182, P_Lo, 190, P_Cn, 212, P_Mn, 226, P_Cf, 227, P_Mn, 0, P_Mn, 3, P_Mc, 4, P_Lo, 58, P_Mn, 59, P_Mc, 60, P_Mn, 61, P_Lo, 62, P_Mc, 65, P_Mn, 73, P_Mc, 77, P_Mn, 78, P_Mc, 80, P_Lo, 81, P_Mn, 88, P_Lo, 98, P_Mn, 100, P_Po, 102, P_Nd, 112, P_Po, 113, P_Lm, 114, P_Lo, 129, P_Mn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 141, P_Cn, 143, P_Lo, 145, P_Cn, 147, P_Lo, 169, P_Cn, 170, P_Lo, 177, P_Cn, 178, P_Lo, 179, P_Cn, 182, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 193, P_Mn, 197, P_Cn, 199, P_Mc, 201, P_Cn, 203, P_Mc, 205, P_Mn, 206, P_Lo, 207, P_Cn, 215, P_Mc, 216, P_Cn, 220, P_Lo, 222, P_Cn, 223, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Lo, 242, P_Sc, 244, P_No, 250, P_So, 251, P_Sc, 252, P_Cn, 0, P_Cn, 1, P_Mn, 3, P_Mc, 4, P_Cn, 5, P_Lo, 11, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 55, P_Cn, 56, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Cn, 62, P_Mc, 65, P_Mn, 67, P_Cn, 71, P_Mn, 73, P_Cn, 75, P_Mn, 78, P_Cn, 81, P_Mn, 82, P_Cn, 89, P_Lo, 93, P_Cn, 94, P_Lo, 95, P_Cn, 102, P_Nd, 112, P_Mn, 114, P_Lo, 117, P_Mn, 118, P_Cn, 129, P_Mn, 131, P_Mc, 132, P_Cn, 133, P_Lo, 142, P_Cn, 143, P_Lo, 146, P_Cn, 147, P_Lo, 169, P_Cn, 170, P_Lo, 177, P_Cn, 178, P_Lo, 180, P_Cn, 181, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 193, P_Mn, 198, P_Cn, 199, P_Mn, 201, P_Mc, 202, P_Cn, 203, P_Mc, 205, P_Mn, 206, P_Cn, 208, P_Lo, 209, P_Cn, 224, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Po, 241, P_Sc, 242, P_Cn, 249, P_Lo, 250, P_Cn, 0, P_Cn, 1, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Lo, 62, P_Mc, 63, P_Mn, 64, P_Mc, 65, P_Mn, 69, P_Cn, 71, P_Mc, 73, P_Cn, 75, P_Mc, 77, P_Mn, 78, P_Cn, 86, P_Mn, 87, P_Mc, 88, P_Cn, 92, P_Lo, 94, P_Cn, 95, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_So, 113, P_Lo, 114, P_No, 120, P_Cn, 130, P_Mn, 131, P_Lo, 132, P_Cn, 133, P_Lo, 139, P_Cn, 142, P_Lo, 145, P_Cn, 146, P_Lo, 150, P_Cn, 153, P_Lo, 155, P_Cn, 156, P_Lo, 157, P_Cn, 158, P_Lo, 160, P_Cn, 163, P_Lo, 165, P_Cn, 168, P_Lo, 171, P_Cn, 174, P_Lo, 186, P_Cn, 190, P_Mc, 192, P_Mn, 193, P_Mc, 195, P_Cn, 198, P_Mc, 201, P_Cn, 202, P_Mc, 205, P_Mn, 206, P_Cn, 208, P_Lo, 209, P_Cn, 215, P_Mc, 216, P_Cn, 230, P_Nd, 240, P_No, 243, P_So, 249, P_Sc, 250, P_So, 251, P_Cn, - 0, P_Mn, 1, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 41, P_Cn, 42, P_Lo, 58, P_Cn, 61, P_Lo, 62, P_Mn, 65, P_Mc, 69, P_Cn, 70, P_Mn, 73, P_Cn, 74, P_Mn, 78, P_Cn, 85, P_Mn, 87, P_Cn, 88, P_Lo, 91, P_Cn, 96, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_Cn, 120, P_No, 127, P_So, 128, P_Cn, 129, P_Mn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 141, P_Cn, 142, P_Lo, 145, P_Cn, 146, P_Lo, 169, P_Cn, 170, P_Lo, 180, P_Cn, 181, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 191, P_Mn, 192, P_Mc, 197, P_Cn, 198, P_Mn, 199, P_Mc, 201, P_Cn, 202, P_Mc, 204, P_Mn, 206, P_Cn, 213, P_Mc, 215, P_Cn, 222, P_Lo, 223, P_Cn, 224, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Cn, 241, P_Lo, 243, P_Cn, - 0, P_Cn, 1, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 59, P_Cn, 61, P_Lo, 62, P_Mc, 65, P_Mn, 69, P_Cn, 70, P_Mc, 73, P_Cn, 74, P_Mc, 77, P_Mn, 78, P_Lo, 79, P_Cn, 87, P_Mc, 88, P_Cn, 95, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_No, 118, P_Cn, 121, P_So, 122, P_Lo, 128, P_Cn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 151, P_Cn, 154, P_Lo, 178, P_Cn, 179, P_Lo, 188, P_Cn, 189, P_Lo, 190, P_Cn, 192, P_Lo, 199, P_Cn, 202, P_Mn, 203, P_Cn, 207, P_Mc, 210, P_Mn, 213, P_Cn, 214, P_Mn, 215, P_Cn, 216, P_Mc, 224, P_Cn, 230, P_Nd, 240, P_Cn, 242, P_Mc, 244, P_Po, 245, P_Cn, + 0, P_Mn, 1, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 41, P_Cn, 42, P_Lo, 58, P_Cn, 61, P_Lo, 62, P_Mn, 65, P_Mc, 69, P_Cn, 70, P_Mn, 73, P_Cn, 74, P_Mn, 78, P_Cn, 85, P_Mn, 87, P_Cn, 88, P_Lo, 91, P_Cn, 96, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_Cn, 120, P_No, 127, P_So, 128, P_Lo, 129, P_Mn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 141, P_Cn, 142, P_Lo, 145, P_Cn, 146, P_Lo, 169, P_Cn, 170, P_Lo, 180, P_Cn, 181, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 191, P_Mn, 192, P_Mc, 197, P_Cn, 198, P_Mn, 199, P_Mc, 201, P_Cn, 202, P_Mc, 204, P_Mn, 206, P_Cn, 213, P_Mc, 215, P_Cn, 222, P_Lo, 223, P_Cn, 224, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Cn, 241, P_Lo, 243, P_Cn, + 0, P_Cn, 1, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 59, P_Cn, 61, P_Lo, 62, P_Mc, 65, P_Mn, 69, P_Cn, 70, P_Mc, 73, P_Cn, 74, P_Mc, 77, P_Mn, 78, P_Lo, 79, P_So, 80, P_Cn, 84, P_Lo, 87, P_Mc, 88, P_No, 95, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_No, 121, P_So, 122, P_Lo, 128, P_Cn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 151, P_Cn, 154, P_Lo, 178, P_Cn, 179, P_Lo, 188, P_Cn, 189, P_Lo, 190, P_Cn, 192, P_Lo, 199, P_Cn, 202, P_Mn, 203, P_Cn, 207, P_Mc, 210, P_Mn, 213, P_Cn, 214, P_Mn, 215, P_Cn, 216, P_Mc, 224, P_Cn, 230, P_Nd, 240, P_Cn, 242, P_Mc, 244, P_Po, 245, P_Cn, 0, P_Cn, 1, P_Lo, 49, P_Mn, 50, P_Lo, 52, P_Mn, 59, P_Cn, 63, P_Sc, 64, P_Lo, 70, P_Lm, 71, P_Mn, 79, P_Po, 80, P_Nd, 90, P_Po, 92, P_Cn, 129, P_Lo, 131, P_Cn, 132, P_Lo, 133, P_Cn, 135, P_Lo, 137, P_Cn, 138, P_Lo, 139, P_Cn, 141, P_Lo, 142, P_Cn, 148, P_Lo, 152, P_Cn, 153, P_Lo, 160, P_Cn, 161, P_Lo, 164, P_Cn, 165, P_Lo, 166, P_Cn, 167, P_Lo, 168, P_Cn, 170, P_Lo, 172, P_Cn, 173, P_Lo, 177, P_Mn, 178, P_Lo, 180, P_Mn, 186, P_Cn, 187, P_Mn, 189, P_Lo, 190, P_Cn, 192, P_Lo, 197, P_Cn, 198, P_Lm, 199, P_Cn, 200, P_Mn, 206, P_Cn, 208, P_Nd, 218, P_Cn, 220, P_Lo, 224, P_Cn, 0, P_Lo, 1, P_So, 4, P_Po, 19, P_So, 20, P_Po, 21, P_So, 24, P_Mn, 26, P_So, 32, P_Nd, 42, P_No, 52, P_So, 53, P_Mn, 54, P_So, 55, P_Mn, 56, P_So, 57, P_Mn, 58, P_Ps, 59, P_Pe, 60, P_Ps, 61, P_Pe, 62, P_Mc, 64, P_Lo, 72, P_Cn, 73, P_Lo, 109, P_Cn, 113, P_Mn, 127, P_Mc, 128, P_Mn, 133, P_Po, 134, P_Mn, 136, P_Lo, 141, P_Mn, 152, P_Cn, 153, P_Mn, 189, P_Cn, 190, P_So, 198, P_Mn, 199, P_So, 205, P_Cn, 206, P_So, 208, P_Po, 213, P_So, 217, P_Po, 219, P_Cn, 0, P_Lo, 43, P_Mc, 45, P_Mn, 49, P_Mc, 50, P_Mn, 56, P_Mc, 57, P_Mn, 59, P_Mc, 61, P_Mn, 63, P_Lo, 64, P_Nd, 74, P_Po, 80, P_Lo, 86, P_Mc, 88, P_Mn, 90, P_Lo, 94, P_Mn, 97, P_Lo, 98, P_Mc, 101, P_Lo, 103, P_Mc, 110, P_Lo, 113, P_Mn, 117, P_Lo, 130, P_Mn, 131, P_Mc, 133, P_Mn, 135, P_Mc, 141, P_Mn, 142, P_Lo, 143, P_Mc, 144, P_Nd, 154, P_Mc, 157, P_Mn, 158, P_So, 160, P_Lu, 198, P_Cn, 199, P_Lu, 200, P_Cn, 205, P_Lu, 206, P_Cn, 208, P_Lo, 251, P_Po, 252, P_Lm, 253, P_Lo, @@ -40,18 +40,18 @@ const unsigned char UnicodeProperty::pro 0, P_Pd, 1, P_Lo, 0, P_Lo, 109, P_Po, 111, P_Lo, 128, P_Zs, 129, P_Lo, 155, P_Ps, 156, P_Pe, 157, P_Cn, 160, P_Lo, 235, P_Po, 238, P_Nl, 241, P_Lo, 249, P_Cn, 0, P_Lo, 13, P_Cn, 14, P_Lo, 18, P_Mn, 21, P_Cn, 32, P_Lo, 50, P_Mn, 53, P_Po, 55, P_Cn, 64, P_Lo, 82, P_Mn, 84, P_Cn, 96, P_Lo, 109, P_Cn, 110, P_Lo, 113, P_Cn, 114, P_Mn, 116, P_Cn, 128, P_Lo, 180, P_Mn, 182, P_Mc, 183, P_Mn, 190, P_Mc, 198, P_Mn, 199, P_Mc, 201, P_Mn, 212, P_Po, 215, P_Lm, 216, P_Po, 219, P_Sc, 220, P_Lo, 221, P_Mn, 222, P_Cn, 224, P_Nd, 234, P_Cn, 240, P_No, 250, P_Cn, - 0, P_Po, 6, P_Pd, 7, P_Po, 11, P_Mn, 14, P_Cf, 15, P_Cn, 16, P_Nd, 26, P_Cn, 32, P_Lo, 67, P_Lm, 68, P_Lo, 120, P_Cn, 128, P_Lo, 169, P_Mn, 170, P_Lo, 171, P_Cn, 176, P_Lo, 246, P_Cn, + 0, P_Po, 6, P_Pd, 7, P_Po, 11, P_Mn, 14, P_Cf, 15, P_Cn, 16, P_Nd, 26, P_Cn, 32, P_Lo, 67, P_Lm, 68, P_Lo, 120, P_Cn, 128, P_Lo, 133, P_Mn, 135, P_Lo, 169, P_Mn, 170, P_Lo, 171, P_Cn, 176, P_Lo, 246, P_Cn, 0, P_Lo, 31, P_Cn, 32, P_Mn, 35, P_Mc, 39, P_Mn, 41, P_Mc, 44, P_Cn, 48, P_Mc, 50, P_Mn, 51, P_Mc, 57, P_Mn, 60, P_Cn, 64, P_So, 65, P_Cn, 68, P_Po, 70, P_Nd, 80, P_Lo, 110, P_Cn, 112, P_Lo, 117, P_Cn, 128, P_Lo, 172, P_Cn, 176, P_Lo, 202, P_Cn, 208, P_Nd, 218, P_No, 219, P_Cn, 222, P_So, 0, P_Lo, 23, P_Mn, 25, P_Mc, 27, P_Mn, 28, P_Cn, 30, P_Po, 32, P_Lo, 85, P_Mc, 86, P_Mn, 87, P_Mc, 88, P_Mn, 95, P_Cn, 96, P_Mn, 97, P_Mc, 98, P_Mn, 99, P_Mc, 101, P_Mn, 109, P_Mc, 115, P_Mn, 125, P_Cn, 127, P_Mn, 128, P_Nd, 138, P_Cn, 144, P_Nd, 154, P_Cn, 160, P_Po, 167, P_Lm, 168, P_Po, 174, P_Cn, 176, P_Mn, 190, P_Me, 191, P_Cn, 0, P_Mn, 4, P_Mc, 5, P_Lo, 52, P_Mn, 53, P_Mc, 54, P_Mn, 59, P_Mc, 60, P_Mn, 61, P_Mc, 66, P_Mn, 67, P_Mc, 69, P_Lo, 76, P_Cn, 80, P_Nd, 90, P_Po, 97, P_So, 107, P_Mn, 116, P_So, 125, P_Cn, 128, P_Mn, 130, P_Mc, 131, P_Lo, 161, P_Mc, 162, P_Mn, 166, P_Mc, 168, P_Mn, 170, P_Mc, 171, P_Mn, 174, P_Lo, 176, P_Nd, 186, P_Lo, 230, P_Mn, 231, P_Mc, 232, P_Mn, 234, P_Mc, 237, P_Mn, 238, P_Mc, 239, P_Mn, 242, P_Mc, 244, P_Cn, 252, P_Po, - 0, P_Lo, 36, P_Mc, 44, P_Mn, 52, P_Mc, 54, P_Mn, 56, P_Cn, 59, P_Po, 64, P_Nd, 74, P_Cn, 77, P_Lo, 80, P_Nd, 90, P_Lo, 120, P_Lm, 126, P_Po, 128, P_Cn, 192, P_Po, 200, P_Cn, 208, P_Mn, 211, P_Po, 212, P_Mn, 225, P_Mc, 226, P_Mn, 233, P_Lo, 237, P_Mn, 238, P_Lo, 242, P_Mc, 244, P_Mn, 245, P_Lo, 247, P_Cn, 248, P_Mn, 250, P_Cn, - 0, P_Ll, 44, P_Lm, 107, P_Ll, 120, P_Lm, 121, P_Ll, 155, P_Lm, 192, P_Mn, 246, P_Cn, 252, P_Mn, + 0, P_Lo, 36, P_Mc, 44, P_Mn, 52, P_Mc, 54, P_Mn, 56, P_Cn, 59, P_Po, 64, P_Nd, 74, P_Cn, 77, P_Lo, 80, P_Nd, 90, P_Lo, 120, P_Lm, 126, P_Po, 128, P_Ll, 137, P_Cn, 192, P_Po, 200, P_Cn, 208, P_Mn, 211, P_Po, 212, P_Mn, 225, P_Mc, 226, P_Mn, 233, P_Lo, 237, P_Mn, 238, P_Lo, 242, P_Mc, 244, P_Mn, 245, P_Lo, 247, P_Cn, 248, P_Mn, 250, P_Cn, + 0, P_Ll, 44, P_Lm, 107, P_Ll, 120, P_Lm, 121, P_Ll, 155, P_Lm, 192, P_Mn, 246, P_Cn, 251, P_Mn, 0, P_Lul, 150, P_Ll, 158, P_Lul, 0, P_Ll, 8, P_Lu, 16, P_Ll, 22, P_Cn, 24, P_Lu, 30, P_Cn, 32, P_Ll, 40, P_Lu, 48, P_Ll, 56, P_Lu, 64, P_Ll, 70, P_Cn, 72, P_Lu, 78, P_Cn, 80, P_Ll, 88, P_Cn, 89, P_Lu, 90, P_Cn, 91, P_Lu, 92, P_Cn, 93, P_Lu, 94, P_Cn, 95, P_Lul, 97, P_Ll, 104, P_Lu, 112, P_Ll, 126, P_Cn, 128, P_Ll, 136, P_Lt, 144, P_Ll, 152, P_Lt, 160, P_Ll, 168, P_Lt, 176, P_Ll, 181, P_Cn, 182, P_Ll, 184, P_Lu, 188, P_Lt, 189, P_Sk, 190, P_Ll, 191, P_Sk, 194, P_Ll, 197, P_Cn, 198, P_Ll, 200, P_Lu, 204, P_Lt, 205, P_Sk, 208, P_Ll, 212, P_Cn, 214, P_Ll, 216, P_Lu, 220, P_Cn, 221, P_Sk, 224, P_Ll, 232, P_Lu, 237, P_Sk, 240, P_Cn, 242, P_Ll, 245, P_Cn, 246, P_Ll, 248, P_Lu, 252, P_Lt, 253, P_Sk, 255, P_Cn, 0, P_Zs, 11, P_Cf, 16, P_Pd, 22, P_Po, 24, P_Pi, 25, P_Pf, 26, P_Ps, 27, P_Pi, 29, P_Pf, 30, P_Ps, 31, P_Pi, 32, P_Po, 40, P_Zl, 41, P_Zp, 42, P_Cf, 47, P_Zs, 48, P_Po, 57, P_Pi, 58, P_Pf, 59, P_Po, 63, P_Pc, 65, P_Po, 68, P_Sm, 69, P_Ps, 70, P_Pe, 71, P_Po, 82, P_Sm, 83, P_Po, 84, P_Pc, 85, P_Po, 95, P_Zs, 96, P_Cf, 101, P_Cn, 102, P_Cf, 112, P_No, 113, P_Lm, 114, P_Cn, 116, P_No, 122, P_Sm, 125, P_Ps, 126, P_Pe, 127, P_Lm, 128, P_No, 138, P_Sm, 141, P_Ps, 142, P_Pe, 143, P_Cn, 144, P_Lm, 157, P_Cn, 160, P_Sc, 191, P_Cn, 208, P_Mn, 221, P_Me, 225, P_Mn, 226, P_Me, 229, P_Mn, 241, P_Cn, 0, P_So, 2, P_Lu, 3, P_So, 7, P_Lu, 8, P_So, 10, P_Ll, 11, P_Lu, 14, P_Ll, 16, P_Lu, 19, P_Ll, 20, P_So, 21, P_Lu, 22, P_So, 24, P_Sm, 25, P_Lu, 30, P_So, 36, P_Lu, 37, P_So, 38, P_Lu, 39, P_So, 40, P_Lu, 41, P_So, 42, P_Lu, 46, P_So, 47, P_Ll, 48, P_Lu, 52, P_Ll, 53, P_Lo, 57, P_Ll, 58, P_So, 60, P_Ll, 62, P_Lu, 64, P_Sm, 69, P_Lul, 71, P_Ll, 74, P_So, 75, P_Sm, 76, P_So, 78, P_Ll, 79, P_So, 80, P_No, 96, P_Nl, 131, P_Lul, 133, P_Nl, 137, P_No, 138, P_So, 140, P_Cn, 144, P_Sm, 149, P_So, 154, P_Sm, 156, P_So, 160, P_Sm, 161, P_So, 163, P_Sm, 164, P_So, 166, P_Sm, 167, P_So, 174, P_Sm, 175, P_So, 206, P_Sm, 208, P_So, 210, P_Sm, 211, P_So, 212, P_Sm, 213, P_So, 244, P_Sm, 0, P_Sm, - 0, P_So, 8, P_Ps, 9, P_Pe, 10, P_Ps, 11, P_Pe, 12, P_So, 32, P_Sm, 34, P_So, 41, P_Ps, 42, P_Pe, 43, P_So, 124, P_Sm, 125, P_So, 155, P_Sm, 180, P_So, 220, P_Sm, 226, P_So, 251, P_Cn, + 0, P_So, 8, P_Ps, 9, P_Pe, 10, P_Ps, 11, P_Pe, 12, P_So, 32, P_Sm, 34, P_So, 41, P_Ps, 42, P_Pe, 43, P_So, 124, P_Sm, 125, P_So, 155, P_Sm, 180, P_So, 220, P_Sm, 226, P_So, 255, P_Cn, 0, P_So, 39, P_Cn, 64, P_So, 75, P_Cn, 96, P_No, 156, P_So, 234, P_No, 0, P_So, 183, P_Sm, 184, P_So, 193, P_Sm, 194, P_So, 248, P_Sm, 0, P_So, 111, P_Sm, 112, P_So, @@ -61,7 +61,7 @@ const unsigned char UnicodeProperty::pro 0, P_So, 48, P_Sm, 69, P_So, 71, P_Sm, 77, P_So, 116, P_Cn, 118, P_So, 150, P_Cn, 152, P_So, 186, P_Cn, 189, P_So, 201, P_Cn, 202, P_So, 210, P_Cn, 236, P_So, 240, P_Cn, 0, P_Lu, 47, P_Cn, 48, P_Ll, 95, P_Cn, 96, P_Lul, 98, P_Lu, 101, P_Ll, 103, P_Lul, 109, P_Lu, 113, P_Ll, 114, P_Lul, 116, P_Ll, 117, P_Lul, 119, P_Ll, 124, P_Lm, 126, P_Lu, 129, P_Ll, 130, P_Lul, 228, P_Ll, 229, P_So, 235, P_Lul, 239, P_Mn, 242, P_Lul, 244, P_Cn, 249, P_Po, 253, P_No, 254, P_Po, 0, P_Ll, 38, P_Cn, 39, P_Ll, 40, P_Cn, 45, P_Ll, 46, P_Cn, 48, P_Lo, 104, P_Cn, 111, P_Lm, 112, P_Po, 113, P_Cn, 127, P_Mn, 128, P_Lo, 151, P_Cn, 160, P_Lo, 167, P_Cn, 168, P_Lo, 175, P_Cn, 176, P_Lo, 183, P_Cn, 184, P_Lo, 191, P_Cn, 192, P_Lo, 199, P_Cn, 200, P_Lo, 207, P_Cn, 208, P_Lo, 215, P_Cn, 216, P_Lo, 223, P_Cn, 224, P_Mn, - 0, P_Po, 2, P_Pi, 3, P_Pf, 4, P_Pi, 5, P_Pf, 6, P_Po, 9, P_Pi, 10, P_Pf, 11, P_Po, 12, P_Pi, 13, P_Pf, 14, P_Po, 23, P_Pd, 24, P_Po, 26, P_Pd, 27, P_Po, 28, P_Pi, 29, P_Pf, 30, P_Po, 32, P_Pi, 33, P_Pf, 34, P_Ps, 35, P_Pe, 36, P_Ps, 37, P_Pe, 38, P_Ps, 39, P_Pe, 40, P_Ps, 41, P_Pe, 42, P_Po, 47, P_Lm, 48, P_Po, 58, P_Pd, 60, P_Po, 64, P_Pd, 65, P_Po, 66, P_Ps, 67, P_Cn, 128, P_So, 154, P_Cn, 155, P_So, 244, P_Cn, + 0, P_Po, 2, P_Pi, 3, P_Pf, 4, P_Pi, 5, P_Pf, 6, P_Po, 9, P_Pi, 10, P_Pf, 11, P_Po, 12, P_Pi, 13, P_Pf, 14, P_Po, 23, P_Pd, 24, P_Po, 26, P_Pd, 27, P_Po, 28, P_Pi, 29, P_Pf, 30, P_Po, 32, P_Pi, 33, P_Pf, 34, P_Ps, 35, P_Pe, 36, P_Ps, 37, P_Pe, 38, P_Ps, 39, P_Pe, 40, P_Ps, 41, P_Pe, 42, P_Po, 47, P_Lm, 48, P_Po, 58, P_Pd, 60, P_Po, 64, P_Pd, 65, P_Po, 66, P_Ps, 67, P_Po, 69, P_Cn, 128, P_So, 154, P_Cn, 155, P_So, 244, P_Cn, 0, P_So, 214, P_Cn, 240, P_So, 252, P_Cn, 0, P_Zs, 1, P_Po, 4, P_So, 5, P_Lm, 6, P_Lo, 7, P_Nl, 8, P_Ps, 9, P_Pe, 10, P_Ps, 11, P_Pe, 12, P_Ps, 13, P_Pe, 14, P_Ps, 15, P_Pe, 16, P_Ps, 17, P_Pe, 18, P_So, 20, P_Ps, 21, P_Pe, 22, P_Ps, 23, P_Pe, 24, P_Ps, 25, P_Pe, 26, P_Ps, 27, P_Pe, 28, P_Pd, 29, P_Ps, 30, P_Pe, 32, P_So, 33, P_Nl, 42, P_Mn, 46, P_Mc, 48, P_Pd, 49, P_Lm, 54, P_So, 56, P_Nl, 59, P_Lm, 60, P_Lo, 61, P_Po, 62, P_So, 64, P_Cn, 65, P_Lo, 151, P_Cn, 153, P_Mn, 155, P_Sk, 157, P_Lm, 159, P_Lo, 160, P_Pd, 161, P_Lo, 251, P_Po, 252, P_Lm, 255, P_Lo, 0, P_Cn, 5, P_Lo, 46, P_Cn, 49, P_Lo, 143, P_Cn, 144, P_So, 146, P_No, 150, P_So, 160, P_Lo, 187, P_Cn, 192, P_So, 228, P_Cn, 240, P_Lo, @@ -72,8 +72,8 @@ const unsigned char UnicodeProperty::pro 0, P_Lo, 21, P_Lm, 22, P_Lo, 0, P_Lo, 141, P_Cn, 144, P_So, 199, P_Cn, 208, P_Lo, 248, P_Lm, 254, P_Po, 0, P_Lo, 12, P_Lm, 13, P_Po, 16, P_Lo, 32, P_Nd, 42, P_Lo, 44, P_Cn, 64, P_Lul, 110, P_Lo, 111, P_Mn, 112, P_Me, 115, P_Po, 116, P_Mn, 126, P_Po, 127, P_Lm, 128, P_Lul, 156, P_Lm, 158, P_Mn, 160, P_Lo, 230, P_Nl, 240, P_Mn, 242, P_Po, 248, P_Cn, - 0, P_Sk, 23, P_Lm, 32, P_Sk, 34, P_Lul, 48, P_Ll, 50, P_Lul, 112, P_Lm, 113, P_Ll, 121, P_Lul, 125, P_Lu, 127, P_Ll, 128, P_Lul, 136, P_Lm, 137, P_Sk, 139, P_Lul, 143, P_Lo, 144, P_Lul, 148, P_Ll, 150, P_Lul, 170, P_Lu, 174, P_Cn, 176, P_Lu, 181, P_Ll, 182, P_Lul, 184, P_Cn, 247, P_Lo, 248, P_Lm, 250, P_Ll, 251, P_Lo, - 0, P_Lo, 2, P_Mn, 3, P_Lo, 6, P_Mn, 7, P_Lo, 11, P_Mn, 12, P_Lo, 35, P_Mc, 37, P_Mn, 39, P_Mc, 40, P_So, 44, P_Cn, 48, P_No, 54, P_So, 56, P_Sc, 57, P_So, 58, P_Cn, 64, P_Lo, 116, P_Po, 120, P_Cn, 128, P_Mc, 130, P_Lo, 180, P_Mc, 196, P_Mn, 197, P_Cn, 206, P_Po, 208, P_Nd, 218, P_Cn, 224, P_Mn, 242, P_Lo, 248, P_Po, 251, P_Lo, 252, P_Po, 253, P_Lo, 254, P_Cn, + 0, P_Sk, 23, P_Lm, 32, P_Sk, 34, P_Lul, 48, P_Ll, 50, P_Lul, 112, P_Lm, 113, P_Ll, 121, P_Lul, 125, P_Lu, 127, P_Ll, 128, P_Lul, 136, P_Lm, 137, P_Sk, 139, P_Lul, 143, P_Lo, 144, P_Lul, 148, P_Ll, 150, P_Lul, 170, P_Lu, 175, P_Cn, 176, P_Lu, 181, P_Ll, 182, P_Lul, 184, P_Cn, 247, P_Lo, 248, P_Lm, 250, P_Ll, 251, P_Lo, + 0, P_Lo, 2, P_Mn, 3, P_Lo, 6, P_Mn, 7, P_Lo, 11, P_Mn, 12, P_Lo, 35, P_Mc, 37, P_Mn, 39, P_Mc, 40, P_So, 44, P_Cn, 48, P_No, 54, P_So, 56, P_Sc, 57, P_So, 58, P_Cn, 64, P_Lo, 116, P_Po, 120, P_Cn, 128, P_Mc, 130, P_Lo, 180, P_Mc, 196, P_Mn, 198, P_Cn, 206, P_Po, 208, P_Nd, 218, P_Cn, 224, P_Mn, 242, P_Lo, 248, P_Po, 251, P_Lo, 252, P_Po, 253, P_Lo, 254, P_Cn, 0, P_Nd, 10, P_Lo, 38, P_Mn, 46, P_Po, 48, P_Lo, 71, P_Mn, 82, P_Mc, 84, P_Cn, 95, P_Po, 96, P_Lo, 125, P_Cn, 128, P_Mn, 131, P_Mc, 132, P_Lo, 179, P_Mn, 180, P_Mc, 182, P_Mn, 186, P_Mc, 188, P_Mn, 189, P_Mc, 193, P_Po, 206, P_Cn, 207, P_Lm, 208, P_Nd, 218, P_Cn, 222, P_Po, 224, P_Lo, 229, P_Mn, 230, P_Lm, 231, P_Lo, 240, P_Nd, 250, P_Lo, 255, P_Cn, 0, P_Lo, 41, P_Mn, 47, P_Mc, 49, P_Mn, 51, P_Mc, 53, P_Mn, 55, P_Cn, 64, P_Lo, 67, P_Mn, 68, P_Lo, 76, P_Mn, 77, P_Mc, 78, P_Cn, 80, P_Nd, 90, P_Cn, 92, P_Po, 96, P_Lo, 112, P_Lm, 113, P_Lo, 119, P_So, 122, P_Lo, 123, P_Mc, 124, P_Mn, 125, P_Mc, 126, P_Lo, 176, P_Mn, 177, P_Lo, 178, P_Mn, 181, P_Lo, 183, P_Mn, 185, P_Lo, 190, P_Mn, 192, P_Lo, 193, P_Mn, 194, P_Lo, 195, P_Cn, 219, P_Lo, 221, P_Lm, 222, P_Po, 224, P_Lo, 235, P_Mc, 236, P_Mn, 238, P_Mc, 240, P_Po, 242, P_Lo, 243, P_Lm, 245, P_Mc, 246, P_Mn, 247, P_Cn, 0, P_Cn, 1, P_Lo, 7, P_Cn, 9, P_Lo, 15, P_Cn, 17, P_Lo, 23, P_Cn, 32, P_Lo, 39, P_Cn, 40, P_Lo, 47, P_Cn, 48, P_Ll, 91, P_Sk, 92, P_Lm, 96, P_Ll, 102, P_Cn, 112, P_Ll, 192, P_Lo, 227, P_Mc, 229, P_Mn, 230, P_Mc, 232, P_Mn, 233, P_Mc, 235, P_Po, 236, P_Mc, 237, P_Mn, 238, P_Cn, 240, P_Nd, 250, P_Cn, @@ -89,10 +89,10 @@ const unsigned char UnicodeProperty::pro 0, P_Mn, 16, P_Po, 23, P_Ps, 24, P_Pe, 25, P_Po, 26, P_Cn, 32, P_Mn, 48, P_Po, 49, P_Pd, 51, P_Pc, 53, P_Ps, 54, P_Pe, 55, P_Ps, 56, P_Pe, 57, P_Ps, 58, P_Pe, 59, P_Ps, 60, P_Pe, 61, P_Ps, 62, P_Pe, 63, P_Ps, 64, P_Pe, 65, P_Ps, 66, P_Pe, 67, P_Ps, 68, P_Pe, 69, P_Po, 71, P_Ps, 72, P_Pe, 73, P_Po, 77, P_Pc, 80, P_Po, 83, P_Cn, 84, P_Po, 88, P_Pd, 89, P_Ps, 90, P_Pe, 91, P_Ps, 92, P_Pe, 93, P_Ps, 94, P_Pe, 95, P_Po, 98, P_Sm, 99, P_Pd, 100, P_Sm, 103, P_Cn, 104, P_Po, 105, P_Sc, 106, P_Po, 108, P_Cn, 112, P_Lo, 117, P_Cn, 118, P_Lo, 253, P_Cn, 255, P_Cf, 0, P_Cn, 1, P_Po, 4, P_Sc, 5, P_Po, 8, P_Ps, 9, P_Pe, 10, P_Po, 11, P_Sm, 12, P_Po, 13, P_Pd, 14, P_Po, 16, P_Nd, 26, P_Po, 28, P_Sm, 31, P_Po, 33, P_Lu, 59, P_Ps, 60, P_Po, 61, P_Pe, 62, P_Sk, 63, P_Pc, 64, P_Sk, 65, P_Ll, 91, P_Ps, 92, P_Sm, 93, P_Pe, 94, P_Sm, 95, P_Ps, 96, P_Pe, 97, P_Po, 98, P_Ps, 99, P_Pe, 100, P_Po, 102, P_Lo, 112, P_Lm, 113, P_Lo, 158, P_Lm, 160, P_Lo, 191, P_Cn, 194, P_Lo, 200, P_Cn, 202, P_Lo, 208, P_Cn, 210, P_Lo, 216, P_Cn, 218, P_Lo, 221, P_Cn, 224, P_Sc, 226, P_Sm, 227, P_Sk, 228, P_So, 229, P_Sc, 231, P_Cn, 232, P_So, 233, P_Sm, 237, P_So, 239, P_Cn, 249, P_Cf, 252, P_So, 254, P_Cn, 0, P_Lo, 12, P_Cn, 13, P_Lo, 39, P_Cn, 40, P_Lo, 59, P_Cn, 60, P_Lo, 62, P_Cn, 63, P_Lo, 78, P_Cn, 80, P_Lo, 94, P_Cn, 128, P_Lo, 251, P_Cn, - 0, P_Po, 3, P_Cn, 7, P_No, 52, P_Cn, 55, P_So, 64, P_Nl, 117, P_No, 121, P_So, 138, P_No, 140, P_So, 141, P_Cn, 144, P_So, 156, P_Cn, 160, P_So, 161, P_Cn, 208, P_So, 253, P_Mn, 254, P_Cn, + 0, P_Po, 3, P_Cn, 7, P_No, 52, P_Cn, 55, P_So, 64, P_Nl, 117, P_No, 121, P_So, 138, P_No, 140, P_So, 143, P_Cn, 144, P_So, 156, P_Cn, 160, P_So, 161, P_Cn, 208, P_So, 253, P_Mn, 254, P_Cn, 0, P_Cn, 128, P_Lo, 157, P_Cn, 160, P_Lo, 209, P_Cn, 224, P_Mn, 225, P_No, 252, P_Cn, 0, P_Lo, 32, P_No, 36, P_Cn, 48, P_Lo, 65, P_Nl, 66, P_Lo, 74, P_Nl, 75, P_Cn, 80, P_Lo, 118, P_Mn, 123, P_Cn, 128, P_Lo, 158, P_Cn, 159, P_Po, 160, P_Lo, 196, P_Cn, 200, P_Lo, 208, P_Po, 209, P_Nl, 214, P_Cn, - 0, P_Lu, 40, P_Ll, 80, P_Lo, 158, P_Cn, 160, P_Nd, 170, P_Cn, + 0, P_Lu, 40, P_Ll, 80, P_Lo, 158, P_Cn, 160, P_Nd, 170, P_Cn, 176, P_Lu, 212, P_Cn, 216, P_Ll, 252, P_Cn, 0, P_Lo, 40, P_Cn, 48, P_Lo, 100, P_Cn, 111, P_Po, 112, P_Cn, 0, P_Lo, 55, P_Cn, 64, P_Lo, 86, P_Cn, 96, P_Lo, 104, P_Cn, 0, P_Lo, 6, P_Cn, 8, P_Lo, 9, P_Cn, 10, P_Lo, 54, P_Cn, 55, P_Lo, 57, P_Cn, 60, P_Lo, 61, P_Cn, 63, P_Lo, 86, P_Cn, 87, P_Po, 88, P_No, 96, P_Lo, 119, P_So, 121, P_No, 128, P_Lo, 159, P_Cn, 167, P_No, 176, P_Cn, 224, P_Lo, 243, P_Cn, 244, P_Lo, 246, P_Cn, 251, P_No, @@ -103,14 +103,15 @@ const unsigned char UnicodeProperty::pro 0, P_Cn, 96, P_No, 127, P_Cn, 0, P_Mc, 1, P_Mn, 2, P_Mc, 3, P_Lo, 56, P_Mn, 71, P_Po, 78, P_Cn, 82, P_No, 102, P_Nd, 112, P_Cn, 127, P_Mn, 130, P_Mc, 131, P_Lo, 176, P_Mc, 179, P_Mn, 183, P_Mc, 185, P_Mn, 187, P_Po, 189, P_Cf, 190, P_Po, 194, P_Cn, 208, P_Lo, 233, P_Cn, 240, P_Nd, 250, P_Cn, 0, P_Mn, 3, P_Lo, 39, P_Mn, 44, P_Mc, 45, P_Mn, 53, P_Cn, 54, P_Nd, 64, P_Po, 68, P_Cn, 80, P_Lo, 115, P_Mn, 116, P_Po, 118, P_Lo, 119, P_Cn, 128, P_Mn, 130, P_Mc, 131, P_Lo, 179, P_Mc, 182, P_Mn, 191, P_Mc, 193, P_Lo, 197, P_Po, 202, P_Mn, 205, P_Po, 206, P_Cn, 208, P_Nd, 218, P_Lo, 219, P_Po, 220, P_Lo, 221, P_Po, 224, P_Cn, 225, P_No, 245, P_Cn, - 0, P_Lo, 18, P_Cn, 19, P_Lo, 44, P_Mc, 47, P_Mn, 50, P_Mc, 52, P_Mn, 53, P_Mc, 54, P_Mn, 56, P_Po, 62, P_Cn, 128, P_Lo, 135, P_Cn, 136, P_Lo, 137, P_Cn, 138, P_Lo, 142, P_Cn, 143, P_Lo, 158, P_Cn, 159, P_Lo, 169, P_Po, 170, P_Cn, 176, P_Lo, 223, P_Mn, 224, P_Mc, 227, P_Mn, 235, P_Cn, 240, P_Nd, 250, P_Cn, + 0, P_Lo, 18, P_Cn, 19, P_Lo, 44, P_Mc, 47, P_Mn, 50, P_Mc, 52, P_Mn, 53, P_Mc, 54, P_Mn, 56, P_Po, 62, P_Mn, 63, P_Cn, 128, P_Lo, 135, P_Cn, 136, P_Lo, 137, P_Cn, 138, P_Lo, 142, P_Cn, 143, P_Lo, 158, P_Cn, 159, P_Lo, 169, P_Po, 170, P_Cn, 176, P_Lo, 223, P_Mn, 224, P_Mc, 227, P_Mn, 235, P_Cn, 240, P_Nd, 250, P_Cn, 0, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Lo, 62, P_Mc, 64, P_Mn, 65, P_Mc, 69, P_Cn, 71, P_Mc, 73, P_Cn, 75, P_Mc, 78, P_Cn, 80, P_Lo, 81, P_Cn, 87, P_Mc, 88, P_Cn, 93, P_Lo, 98, P_Mc, 100, P_Cn, 102, P_Mn, 109, P_Cn, 112, P_Mn, 117, P_Cn, - 0, P_Cn, 128, P_Lo, 176, P_Mc, 179, P_Mn, 185, P_Mc, 186, P_Mn, 187, P_Mc, 191, P_Mn, 193, P_Mc, 194, P_Mn, 196, P_Lo, 198, P_Po, 199, P_Lo, 200, P_Cn, 208, P_Nd, 218, P_Cn, + 0, P_Lo, 53, P_Mc, 56, P_Mn, 64, P_Mc, 66, P_Mn, 69, P_Mc, 70, P_Mn, 71, P_Lo, 75, P_Po, 80, P_Nd, 90, P_Cn, 91, P_Po, 92, P_Cn, 93, P_Po, 94, P_Cn, 128, P_Lo, 176, P_Mc, 179, P_Mn, 185, P_Mc, 186, P_Mn, 187, P_Mc, 191, P_Mn, 193, P_Mc, 194, P_Mn, 196, P_Lo, 198, P_Po, 199, P_Lo, 200, P_Cn, 208, P_Nd, 218, P_Cn, 0, P_Cn, 128, P_Lo, 175, P_Mc, 178, P_Mn, 182, P_Cn, 184, P_Mc, 188, P_Mn, 190, P_Mc, 191, P_Mn, 193, P_Po, 216, P_Lo, 220, P_Mn, 222, P_Cn, - 0, P_Lo, 48, P_Mc, 51, P_Mn, 59, P_Mc, 61, P_Mn, 62, P_Mc, 63, P_Mn, 65, P_Po, 68, P_Lo, 69, P_Cn, 80, P_Nd, 90, P_Cn, 128, P_Lo, 171, P_Mn, 172, P_Mc, 173, P_Mn, 174, P_Mc, 176, P_Mn, 182, P_Mc, 183, P_Mn, 184, P_Cn, 192, P_Nd, 202, P_Cn, + 0, P_Lo, 48, P_Mc, 51, P_Mn, 59, P_Mc, 61, P_Mn, 62, P_Mc, 63, P_Mn, 65, P_Po, 68, P_Lo, 69, P_Cn, 80, P_Nd, 90, P_Cn, 96, P_Po, 109, P_Cn, 128, P_Lo, 171, P_Mn, 172, P_Mc, 173, P_Mn, 174, P_Mc, 176, P_Mn, 182, P_Mc, 183, P_Mn, 184, P_Cn, 192, P_Nd, 202, P_Cn, 0, P_Lo, 26, P_Cn, 29, P_Mn, 32, P_Mc, 34, P_Mn, 38, P_Mc, 39, P_Mn, 44, P_Cn, 48, P_Nd, 58, P_No, 60, P_Po, 63, P_So, 64, P_Cn, 0, P_Cn, 160, P_Lu, 192, P_Ll, 224, P_Nd, 234, P_No, 243, P_Cn, 255, P_Lo, 0, P_Cn, 192, P_Lo, 249, P_Cn, + 0, P_Lo, 9, P_Cn, 10, P_Lo, 47, P_Mc, 48, P_Mn, 55, P_Cn, 56, P_Mn, 62, P_Mc, 63, P_Mn, 64, P_Lo, 65, P_Po, 70, P_Cn, 80, P_Nd, 90, P_No, 109, P_Cn, 112, P_Po, 114, P_Lo, 144, P_Cn, 146, P_Mn, 168, P_Cn, 169, P_Mc, 170, P_Mn, 177, P_Mc, 178, P_Mn, 180, P_Mc, 181, P_Mn, 183, P_Cn, 0, P_Lo, 154, P_Cn, 0, P_Nl, 111, P_Cn, 112, P_Po, 117, P_Cn, 128, P_Lo, 0, P_Lo, 68, P_Cn, @@ -118,7 +119,9 @@ const unsigned char UnicodeProperty::pro 0, P_Lo, 71, P_Cn, 0, P_Lo, 57, P_Cn, 64, P_Lo, 95, P_Cn, 96, P_Nd, 106, P_Cn, 110, P_Po, 112, P_Cn, 208, P_Lo, 238, P_Cn, 240, P_Mn, 245, P_Po, 246, P_Cn, 0, P_Lo, 48, P_Mn, 55, P_Po, 60, P_So, 64, P_Lm, 68, P_Po, 69, P_So, 70, P_Cn, 80, P_Nd, 90, P_Cn, 91, P_No, 98, P_Cn, 99, P_Lo, 120, P_Cn, 125, P_Lo, 144, P_Cn, - 0, P_Lo, 69, P_Cn, 80, P_Lo, 81, P_Mc, 127, P_Cn, 143, P_Mn, 147, P_Lm, 160, P_Cn, + 0, P_Lo, 69, P_Cn, 80, P_Lo, 81, P_Mc, 127, P_Cn, 143, P_Mn, 147, P_Lm, 160, P_Cn, 224, P_Lm, 225, P_Cn, + 0, P_Cn, 236, P_Lo, 237, P_Cn, + 0, P_Lo, 243, P_Cn, 0, P_Lo, 2, P_Cn, 0, P_Lo, 107, P_Cn, 112, P_Lo, 125, P_Cn, 128, P_Lo, 137, P_Cn, 144, P_Lo, 154, P_Cn, 156, P_So, 157, P_Mn, 159, P_Po, 160, P_Cf, 164, P_Cn, 0, P_So, 246, P_Cn, @@ -130,17 +133,18 @@ const unsigned char UnicodeProperty::pro 0, P_Ll, 8, P_Lu, 34, P_Ll, 60, P_Lu, 86, P_Ll, 112, P_Lu, 138, P_Ll, 166, P_Cn, 168, P_Lu, 193, P_Sm, 194, P_Ll, 219, P_Sm, 220, P_Ll, 226, P_Lu, 251, P_Sm, 252, P_Ll, 0, P_Ll, 21, P_Sm, 22, P_Ll, 28, P_Lu, 53, P_Sm, 54, P_Ll, 79, P_Sm, 80, P_Ll, 86, P_Lu, 111, P_Sm, 112, P_Ll, 137, P_Sm, 138, P_Ll, 144, P_Lu, 169, P_Sm, 170, P_Ll, 195, P_Sm, 196, P_Ll, 202, P_Lul, 204, P_Cn, 206, P_Nd, 0, P_Mn, 55, P_So, 59, P_Mn, 109, P_So, 117, P_Mn, 118, P_So, 132, P_Mn, 133, P_So, 135, P_Po, 140, P_Cn, 155, P_Mn, 160, P_Cn, 161, P_Mn, 176, P_Cn, + 0, P_Mn, 7, P_Cn, 8, P_Mn, 25, P_Cn, 27, P_Mn, 34, P_Cn, 35, P_Mn, 37, P_Cn, 38, P_Mn, 43, P_Cn, 0, P_Lo, 197, P_Cn, 199, P_No, 208, P_Mn, 215, P_Cn, + 0, P_Lu, 34, P_Ll, 68, P_Mn, 75, P_Cn, 80, P_Nd, 90, P_Cn, 94, P_Po, 96, P_Cn, 0, P_Lo, 4, P_Cn, 5, P_Lo, 32, P_Cn, 33, P_Lo, 35, P_Cn, 36, P_Lo, 37, P_Cn, 39, P_Lo, 40, P_Cn, 41, P_Lo, 51, P_Cn, 52, P_Lo, 56, P_Cn, 57, P_Lo, 58, P_Cn, 59, P_Lo, 60, P_Cn, 66, P_Lo, 67, P_Cn, 71, P_Lo, 72, P_Cn, 73, P_Lo, 74, P_Cn, 75, P_Lo, 76, P_Cn, 77, P_Lo, 80, P_Cn, 81, P_Lo, 83, P_Cn, 84, P_Lo, 85, P_Cn, 87, P_Lo, 88, P_Cn, 89, P_Lo, 90, P_Cn, 91, P_Lo, 92, P_Cn, 93, P_Lo, 94, P_Cn, 95, P_Lo, 96, P_Cn, 97, P_Lo, 99, P_Cn, 100, P_Lo, 101, P_Cn, 103, P_Lo, 107, P_Cn, 108, P_Lo, 115, P_Cn, 116, P_Lo, 120, P_Cn, 121, P_Lo, 125, P_Cn, 126, P_Lo, 127, P_Cn, 128, P_Lo, 138, P_Cn, 139, P_Lo, 156, P_Cn, 161, P_Lo, 164, P_Cn, 165, P_Lo, 170, P_Cn, 171, P_Lo, 188, P_Cn, 240, P_Sm, 242, P_Cn, 0, P_So, 44, P_Cn, 48, P_So, 148, P_Cn, 160, P_So, 175, P_Cn, 177, P_So, 192, P_Cn, 193, P_So, 208, P_Cn, 209, P_So, 246, P_Cn, - 0, P_No, 13, P_Cn, 16, P_So, 47, P_Cn, 48, P_So, 108, P_Cn, 112, P_So, 155, P_Cn, 230, P_So, - 0, P_So, 3, P_Cn, 16, P_So, 59, P_Cn, 64, P_So, 73, P_Cn, 80, P_So, 82, P_Cn, + 0, P_No, 13, P_Cn, 16, P_So, 47, P_Cn, 48, P_So, 108, P_Cn, 112, P_So, 173, P_Cn, 230, P_So, + 0, P_So, 3, P_Cn, 16, P_So, 60, P_Cn, 64, P_So, 73, P_Cn, 80, P_So, 82, P_Cn, 0, P_So, 251, P_Sk, - 0, P_So, 122, P_Cn, 123, P_So, 164, P_Cn, 165, P_So, - 0, P_So, 209, P_Cn, 224, P_So, 237, P_Cn, 240, P_So, 244, P_Cn, + 0, P_So, 211, P_Cn, 224, P_So, 237, P_Cn, 240, P_So, 247, P_Cn, 0, P_So, 116, P_Cn, 128, P_So, 213, P_Cn, 0, P_So, 12, P_Cn, 16, P_So, 72, P_Cn, 80, P_So, 90, P_Cn, 96, P_So, 136, P_Cn, 144, P_So, 174, P_Cn, - 0, P_Cn, 16, P_So, 25, P_Cn, 128, P_So, 133, P_Cn, 192, P_So, 193, P_Cn, + 0, P_Cn, 16, P_So, 31, P_Cn, 32, P_So, 40, P_Cn, 48, P_So, 49, P_Cn, 51, P_So, 63, P_Cn, 64, P_So, 76, P_Cn, 80, P_So, 95, P_Cn, 128, P_So, 146, P_Cn, 192, P_So, 193, P_Cn, 0, P_Cn, 214, P_Lo, 215, P_Cn, 0, P_Cn, 52, P_Lo, 53, P_Cn, 64, P_Lo, 65, P_Cn, 0, P_Cn, 29, P_Lo, 30, P_Cn, 32, P_Lo, 33, P_Cn, @@ -159,182 +163,191 @@ const unsigned int UnicodeProperty::prop 0x500, 390, 450, 0x600, 450, 520, 0x700, 520, 560, - 0x800, 560, 598, - 0x900, 598, 720, - 0xA00, 720, 870, - 0xB00, 870, 1032, - 0xC00, 1032, 1166, - 0xD00, 1166, 1280, - 0xE00, 1280, 1388, - 0xF00, 1388, 1476, - 0x1000, 1476, 1566, - 0x1100, 1566, 1568, - 0x1200, 1568, 1622, - 0x1300, 1622, 1656, - 0x1400, 1656, 1660, - 0x1500, 1566, 1568, - 0x1600, 1660, 1686, - 0x1700, 1686, 1760, - 0x1800, 1760, 1796, - 0x1900, 1796, 1852, - 0x1A00, 1852, 1916, - 0x1B00, 1916, 1998, - 0x1C00, 1998, 2060, - 0x1D00, 2060, 2078, - 0x1E00, 2078, 2084, - 0x1F00, 2084, 2212, - 0x2000, 2212, 2326, - 0x2100, 2326, 2458, - 0x2200, 2458, 2460, - 0x2300, 2460, 2496, - 0x2400, 2496, 2510, - 0x2500, 2510, 2522, - 0x2600, 2522, 2528, - 0x2700, 2528, 2592, - 0x2800, 2592, 2594, - 0x2900, 2594, 2658, - 0x2A00, 2458, 2460, - 0x2B00, 2658, 2690, - 0x2C00, 2690, 2744, - 0x2D00, 2744, 2806, - 0x2E00, 2806, 2890, - 0x2F00, 2890, 2898, - 0x3000, 2898, 3002, - 0x3100, 3002, 3028, - 0x3200, 3028, 3054, - 0x3300, 2592, 2594, - 0x3400, 3054, 3058, + 0x800, 560, 606, + 0x900, 606, 728, + 0xA00, 728, 878, + 0xB00, 878, 1040, + 0xC00, 1040, 1174, + 0xD00, 1174, 1290, + 0xE00, 1290, 1398, + 0xF00, 1398, 1486, + 0x1000, 1486, 1576, + 0x1100, 1576, 1578, + 0x1200, 1578, 1632, + 0x1300, 1632, 1666, + 0x1400, 1666, 1670, + 0x1500, 1576, 1578, + 0x1600, 1670, 1696, + 0x1700, 1696, 1770, + 0x1800, 1770, 1810, + 0x1900, 1810, 1866, + 0x1A00, 1866, 1930, + 0x1B00, 1930, 2012, + 0x1C00, 2012, 2076, + 0x1D00, 2076, 2094, + 0x1E00, 2094, 2100, + 0x1F00, 2100, 2228, + 0x2000, 2228, 2342, + 0x2100, 2342, 2474, + 0x2200, 2474, 2476, + 0x2300, 2476, 2512, + 0x2400, 2512, 2526, + 0x2500, 2526, 2538, + 0x2600, 2538, 2544, + 0x2700, 2544, 2608, + 0x2800, 2608, 2610, + 0x2900, 2610, 2674, + 0x2A00, 2474, 2476, + 0x2B00, 2674, 2706, + 0x2C00, 2706, 2760, + 0x2D00, 2760, 2822, + 0x2E00, 2822, 2908, + 0x2F00, 2908, 2916, + 0x3000, 2916, 3020, + 0x3100, 3020, 3046, + 0x3200, 3046, 3072, + 0x3300, 2608, 2610, + 0x3400, 3072, 3076, 0x3500, 0, 2, - 0x4D00, 3058, 3066, - 0x4E00, 3054, 3058, + 0x4D00, 3076, 3084, + 0x4E00, 3072, 3076, 0x4F00, 0, 2, - 0x9F00, 3066, 3072, - 0xA000, 3072, 3078, - 0xA100, 1566, 1568, - 0xA400, 3078, 3092, - 0xA500, 1566, 1568, - 0xA600, 3092, 3138, - 0xA700, 3138, 3196, - 0xA800, 3196, 3266, - 0xA900, 3266, 3332, - 0xAA00, 3332, 3430, - 0xAB00, 3430, 3488, - 0xAC00, 3054, 3058, + 0x9F00, 3084, 3090, + 0xA000, 3090, 3096, + 0xA100, 1576, 1578, + 0xA400, 3096, 3110, + 0xA500, 1576, 1578, + 0xA600, 3110, 3156, + 0xA700, 3156, 3214, + 0xA800, 3214, 3284, + 0xA900, 3284, 3350, + 0xAA00, 3350, 3448, + 0xAB00, 3448, 3506, + 0xAC00, 3072, 3076, 0xAD00, 0, 2, - 0xD700, 3488, 3502, - 0xD800, 3502, 3506, + 0xD700, 3506, 3520, + 0xD800, 3520, 3524, 0xD900, 0, 2, - 0xDB00, 3506, 3514, - 0xDC00, 3502, 3506, + 0xDB00, 3524, 3532, + 0xDC00, 3520, 3524, 0xDD00, 0, 2, - 0xDF00, 3514, 3518, - 0xE000, 3518, 3522, + 0xDF00, 3532, 3536, + 0xE000, 3536, 3540, 0xE100, 0, 2, - 0xF800, 3522, 3526, - 0xF900, 1566, 1568, - 0xFA00, 3526, 3534, - 0xFB00, 3534, 3578, - 0xFC00, 1566, 1568, - 0xFD00, 3578, 3602, - 0xFE00, 3602, 3712, - 0xFF00, 3712, 3832, - 0x10000, 3832, 3860, - 0x10100, 3860, 3896, - 0x10200, 3896, 3912, - 0x10300, 3912, 3952, - 0x10400, 3952, 3964, - 0x10500, 3964, 3976, - 0x10600, 1566, 1568, - 0x10700, 3976, 3988, - 0x10800, 3988, 4040, - 0x10900, 4040, 4070, - 0x10A00, 4070, 4136, - 0x10B00, 4136, 4166, - 0x10C00, 4166, 4180, + 0xF800, 3540, 3544, + 0xF900, 1576, 1578, + 0xFA00, 3544, 3552, + 0xFB00, 3552, 3596, + 0xFC00, 1576, 1578, + 0xFD00, 3596, 3620, + 0xFE00, 3620, 3730, + 0xFF00, 3730, 3850, + 0x10000, 3850, 3878, + 0x10100, 3878, 3914, + 0x10200, 3914, 3930, + 0x10300, 3930, 3970, + 0x10400, 3970, 3990, + 0x10500, 3990, 4002, + 0x10600, 1576, 1578, + 0x10700, 4002, 4014, + 0x10800, 4014, 4066, + 0x10900, 4066, 4096, + 0x10A00, 4096, 4162, + 0x10B00, 4162, 4192, + 0x10C00, 4192, 4206, 0x10D00, 0, 2, - 0x10E00, 4180, 4186, + 0x10E00, 4206, 4212, 0x10F00, 0, 2, - 0x11000, 4186, 4236, - 0x11100, 4236, 4302, - 0x11200, 4302, 4360, - 0x11300, 4360, 4432, - 0x11400, 4432, 4464, - 0x11500, 4464, 4490, - 0x11600, 4490, 4536, - 0x11700, 4536, 4562, - 0x11800, 4562, 4576, + 0x11000, 4212, 4262, + 0x11100, 4262, 4328, + 0x11200, 4328, 4388, + 0x11300, 4388, 4460, + 0x11400, 4460, 4520, + 0x11500, 4520, 4546, + 0x11600, 4546, 4596, + 0x11700, 4596, 4622, + 0x11800, 4622, 4636, 0x11900, 0, 2, - 0x11A00, 4576, 4582, + 0x11A00, 4636, 4642, 0x11B00, 0, 2, - 0x12000, 1566, 1568, - 0x12300, 4582, 4586, - 0x12400, 4586, 4596, - 0x12500, 4596, 4600, + 0x11C00, 4642, 4696, + 0x11D00, 0, 2, + 0x12000, 1576, 1578, + 0x12300, 4696, 4700, + 0x12400, 4700, 4710, + 0x12500, 4710, 4714, 0x12600, 0, 2, - 0x13000, 1566, 1568, - 0x13400, 4600, 4604, + 0x13000, 1576, 1578, + 0x13400, 4714, 4718, 0x13500, 0, 2, - 0x14400, 1566, 1568, - 0x14600, 4604, 4608, + 0x14400, 1576, 1578, + 0x14600, 4718, 4722, 0x14700, 0, 2, - 0x16800, 1566, 1568, - 0x16A00, 4608, 4634, - 0x16B00, 4634, 4666, + 0x16800, 1576, 1578, + 0x16A00, 4722, 4748, + 0x16B00, 4748, 4780, 0x16C00, 0, 2, - 0x16F00, 4666, 4682, - 0x17000, 0, 2, - 0x1B000, 4682, 4686, + 0x16F00, 4780, 4800, + 0x17000, 3072, 3076, + 0x17100, 0, 2, + 0x18700, 4800, 4806, + 0x18800, 1576, 1578, + 0x18A00, 4806, 4810, + 0x18B00, 0, 2, + 0x1B000, 4810, 4814, 0x1B100, 0, 2, - 0x1BC00, 4686, 4712, + 0x1BC00, 4814, 4840, 0x1BD00, 0, 2, - 0x1D000, 4712, 4716, - 0x1D100, 4716, 4746, - 0x1D200, 4746, 4754, - 0x1D300, 4754, 4762, - 0x1D400, 4762, 4818, - 0x1D500, 4818, 4872, - 0x1D600, 4872, 4904, - 0x1D700, 4904, 4946, - 0x1D800, 2592, 2594, - 0x1DA00, 4946, 4974, + 0x1D000, 4840, 4844, + 0x1D100, 4844, 4874, + 0x1D200, 4874, 4882, + 0x1D300, 4882, 4890, + 0x1D400, 4890, 4946, + 0x1D500, 4946, 5000, + 0x1D600, 5000, 5032, + 0x1D700, 5032, 5074, + 0x1D800, 2608, 2610, + 0x1DA00, 5074, 5102, 0x1DB00, 0, 2, - 0x1E800, 4974, 4984, - 0x1E900, 0, 2, - 0x1EE00, 4984, 5120, + 0x1E000, 5102, 5122, + 0x1E100, 0, 2, + 0x1E800, 5122, 5132, + 0x1E900, 5132, 5148, + 0x1EA00, 0, 2, + 0x1EE00, 5148, 5284, 0x1EF00, 0, 2, - 0x1F000, 5120, 5144, - 0x1F100, 5144, 5162, - 0x1F200, 5162, 5178, - 0x1F300, 5178, 5182, - 0x1F400, 2592, 2594, - 0x1F500, 5182, 5192, - 0x1F600, 5192, 5204, - 0x1F700, 5204, 5212, - 0x1F800, 5212, 5232, - 0x1F900, 5232, 5246, + 0x1F000, 5284, 5308, + 0x1F100, 5308, 5326, + 0x1F200, 5326, 5342, + 0x1F300, 5342, 5346, + 0x1F400, 2608, 2610, + 0x1F600, 5346, 5358, + 0x1F700, 5358, 5366, + 0x1F800, 5366, 5386, + 0x1F900, 5386, 5420, 0x1FA00, 0, 2, - 0x20000, 3054, 3058, + 0x20000, 3072, 3076, 0x20100, 0, 2, - 0x2A600, 5246, 5252, - 0x2A700, 3054, 3058, + 0x2A600, 5420, 5426, + 0x2A700, 3072, 3076, 0x2A800, 0, 2, - 0x2B700, 5252, 5262, - 0x2B800, 5262, 5272, + 0x2B700, 5426, 5436, + 0x2B800, 5436, 5446, 0x2B900, 0, 2, - 0x2CE00, 5272, 5278, + 0x2CE00, 5446, 5452, 0x2CF00, 0, 2, - 0x2F800, 1566, 1568, - 0x2FA00, 5278, 5282, + 0x2F800, 1576, 1578, + 0x2FA00, 5452, 5456, 0x2FB00, 0, 2, - 0xE0000, 5282, 5292, - 0xE0100, 5292, 5296, + 0xE0000, 5456, 5466, + 0xE0100, 5466, 5470, 0xE0200, 0, 2, - 0xF0000, 3518, 3522, + 0xF0000, 3536, 3540, 0xF0100, 0, 2, - 0xFFF00, 5296, 5302, - 0x100000, 3518, 3522, + 0xFFF00, 5470, 5476, + 0x100000, 3536, 3540, 0x100100, 0, 2, - 0x10FF00, 5296, 5302, + 0x10FF00, 5470, 5476, 0x110000, 0, 2, }; const int UnicodeProperty::nproperty_offsets = (sizeof(UnicodeProperty::property_offsets) / (3*sizeof(unsigned int))); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/uniprop.hh 2018-02-23 12:47:54.095971653 -0500 @@ -5,15 +5,15 @@ class UnicodeProperty { public: enum { - P_C = 000, P_Cn = 000, P_Co = 001, P_Cs = 002, P_Cf = 003, P_Cc = 004, - P_Z = 010, P_Zs = 010, P_Zl = 011, P_Zp = 012, - P_M = 020, P_Mn = 020, P_Mc = 021, P_Me = 022, - P_L = 030, P_Lo = 030, P_Lu = 031, P_Ll = 032, P_Lt = 033, P_Lm = 034, - P_N = 040, P_No = 040, P_Nd = 041, P_Nl = 042, - P_P = 050, P_Po = 050, P_Pc = 051, P_Pd = 052, P_Ps = 053, P_Pe = 054, P_Pi = 055, P_Pf = 056, - P_S = 060, P_So = 060, P_Sm = 061, P_Sc = 062, P_Sk = 063, - P_TMASK = 0370, - P_MAX = 0377 + P_C = 000, P_Cn = 000, P_Co = 001, P_Cs = 002, P_Cf = 003, P_Cc = 004, + P_Z = 010, P_Zs = 010, P_Zl = 011, P_Zp = 012, + P_M = 020, P_Mn = 020, P_Mc = 021, P_Me = 022, + P_L = 030, P_Lo = 030, P_Lu = 031, P_Ll = 032, P_Lt = 033, P_Lm = 034, + P_N = 040, P_No = 040, P_Nd = 041, P_Nl = 042, + P_P = 050, P_Po = 050, P_Pc = 051, P_Pd = 052, P_Ps = 053, P_Pe = 054, P_Pi = 055, P_Pf = 056, + P_S = 060, P_So = 060, P_Sm = 061, P_Sc = 062, P_Sk = 063, + P_TMASK = 0370, + P_MAX = 0377 }; static int property(uint32_t uni); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.cc 2018-02-23 12:47:54.095971653 -0500 @@ -1,6 +1,6 @@ /* util.{cc,hh} -- various bits * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -37,30 +37,30 @@ read_file(String filename, ErrorHandler { FILE *f; if (!filename || filename == "-") { - filename = ""; - f = stdin; + filename = ""; + f = stdin; #if defined(_MSDOS) || defined(_WIN32) - // Set the file mode to binary - _setmode(_fileno(f), _O_BINARY); + // Set the file mode to binary + _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(filename.c_str(), "rb"))) { - errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); - return String(); + errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); + return String(); } StringAccum sa; int amt; do { - if (char *x = sa.reserve(8192)) { - amt = fread(x, 1, 8192, f); - sa.adjust_length(amt); - } else - amt = 0; + if (char *x = sa.reserve(8192)) { + amt = fread(x, 1, 8192, f); + sa.adjust_length(amt); + } else + amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) - errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); + errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); if (f != stdin) - fclose(f); + fclose(f); return sa.take_string(); } @@ -68,9 +68,9 @@ String printable_filename(const String &s) { if (!s || s == "-") - return String::make_stable(""); + return String::make_stable(""); else - return s; + return s; } String @@ -78,19 +78,19 @@ pathname_filename(const String &path) { int slash = path.find_right('/'); if (slash >= 0 && slash != path.length() - 1) - return path.substring(slash + 1); + return path.substring(slash + 1); else - return path; + return path; } static String simplify_filename(String x) { while (x.substring(0, 2) == "./") - x = x.substring(2); + x = x.substring(2); int pos; while ((pos = x.find_left("/./")) >= 0) - x = x.substring(0, pos) + x.substring(pos + 2); + x = x.substring(0, pos) + x.substring(pos + 2); return x; } @@ -104,7 +104,7 @@ String shell_quote(const String &str) { if (!str) - return String::make_stable("\"\""); + return String::make_stable("\"\""); const char *begin = str.begin(); const char *end = str.end(); @@ -114,35 +114,35 @@ shell_quote(const String &str) sa.append('\"'); for (const char *s = begin; s < end; ++s) - if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '\\' || *s == ':' || *s == '.') - /* do nothing */; - else if (*s == '\"') { - sa.append(begin, s); - sa.append("\"\"\"", 3); - begin = s + 1; - } else { - sa.append(begin, s + 1); - begin = s + 1; - } + if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '\\' || *s == ':' || *s == '.') + /* do nothing */; + else if (*s == '\"') { + sa.append(begin, s); + sa.append("\"\"\"", 3); + begin = s + 1; + } else { + sa.append(begin, s + 1); + begin = s + 1; + } if (sa.length() > 1) { - sa.append(begin, end); - sa.append('\"'); - return sa.take_string(); + sa.append(begin, end); + sa.append('\"'); + return sa.take_string(); } #else for (const char *s = begin; s < end; s++) - if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '/' || *s == ':' || *s == '.') - /* do nothing */; - else { - sa.append(begin, s); - sa.append('\\'); - begin = s; - } + if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '/' || *s == ':' || *s == '.') + /* do nothing */; + else { + sa.append(begin, s); + sa.append('\\'); + begin = s; + } if (sa.length()) { - sa.append(begin, end); - return sa.take_string(); + sa.append(begin, end); + return sa.take_string(); } #endif @@ -153,12 +153,25 @@ int mysystem(const char *command, ErrorHandler *errh) { if (no_create) { - errh->message("would run %s", command); - return 0; + errh->message("would run %s", command); + return 0; } else { - if (verbose) - errh->message("running %s", command); - return system(command); + if (verbose) + errh->message("running %s", command); + return system(command); + } +} + +FILE* +mypopen(const char* command, const char* type, ErrorHandler* errh) +{ + if (no_create) { + errh->message("would run %s", command); + return popen("true", type); + } else { + if (verbose) + errh->message("running %s", command); + return popen(command, type); } } @@ -179,34 +192,34 @@ int temporary_file(String &filename, ErrorHandler *errh) { if (no_create) - return 0; // random number suffices + return 0; // random number suffices #if HAVE_MKSTEMP const char *tmpdir = getenv("TMPDIR"); if (tmpdir) - filename = String(tmpdir) + "/otftotfm.XXXXXX"; + filename = String(tmpdir) + "/otftotfm.XXXXXX"; else { # ifdef P_tmpdir - filename = P_tmpdir "/otftotfm.XXXXXX"; + filename = P_tmpdir "/otftotfm.XXXXXX"; # else - filename = "/tmp/otftotfm.XXXXXX"; + filename = "/tmp/otftotfm.XXXXXX"; # endif } int fd = mkstemp(filename.mutable_c_str()); if (fd < 0) - errh->error("temporary file %<%s%>: %s", filename.c_str(), strerror(errno)); + errh->error("temporary file %<%s%>: %s", filename.c_str(), strerror(errno)); return fd; #else // !HAVE_MKSTEMP for (int tries = 0; tries < 5; tries++) { - if (!(filename = my_tmpnam())) - return errh->error("cannot create temporary file"); + if (!(filename = my_tmpnam())) + return errh->error("cannot create temporary file"); # ifdef O_EXCL - int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0600); + int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0600); # else - int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0600); + int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0600); # endif - if (fd >= 0) - return fd; + if (fd >= 0) + return fd; } return errh->error("temporary file %<%s%>: %s", filename.c_str(), strerror(errno)); #endif @@ -217,34 +230,34 @@ parse_unicode_number(const char* begin, { bool allow_lower = (require_prefix == 1); if (require_prefix < 0) - /* do not look for prefix */; + /* do not look for prefix */; else if (begin + 7 == end && begin[0] == 'u' && begin[1] == 'n' && begin[2] == 'i') - begin += 3; + begin += 3; else if (begin + 5 <= end && begin + 7 >= end && begin[0] == 'u') - begin++; + begin++; else if (begin + 3 <= end && begin + 8 >= end && begin[0] == 'U' && begin[1] == '+') - begin += 2, allow_lower = true; + begin += 2, allow_lower = true; else if (require_prefix > 1) - /* some prefix was required */ - return false; + /* some prefix was required */ + return false; uint32_t value; for (value = 0; begin < end; begin++) - if (*begin >= '0' && *begin <= '9') - value = (value << 4) | (*begin - '0'); - else if (*begin >= 'A' && *begin <= 'F') - value = (value << 4) | (*begin - 'A' + 10); - else if (allow_lower && *begin >= 'a' && *begin <= 'f') - value = (value << 4) | (*begin - 'a' + 10); - else - return false; + if (*begin >= '0' && *begin <= '9') + value = (value << 4) | (*begin - '0'); + else if (*begin >= 'A' && *begin <= 'F') + value = (value << 4) | (*begin - 'A' + 10); + else if (allow_lower && *begin >= 'a' && *begin <= 'f') + value = (value << 4) | (*begin - 'a' + 10); + else + return false; if (value > 0 - && (value <= 0xD7FF || (value >= 0xE000 && value <= 0x10FFFF))) { - result = value; - return true; + && (value <= 0xD7FF || (value >= 0xE000 && value <= 0x10FFFF))) { + result = value; + return true; } else - return false; + return false; } #if 0 @@ -253,7 +266,7 @@ shell_command_output(String cmdline, con { FILE *f = tmpfile(); if (!f) - errh->fatal("cannot create temporary file: %s", strerror(errno)); + errh->fatal("cannot create temporary file: %s", strerror(errno)); ignore_result(fwrite(input.data(), 1, input.length(), f)); fflush(f); rewind(f); @@ -261,26 +274,26 @@ shell_command_output(String cmdline, con String new_cmdline = cmdline + " 0<&" + String(fileno(f)); FILE *p = popen(new_cmdline.c_str(), "r"); if (!p) - errh->fatal("%<%s%>: %s", cmdline.c_str(), strerror(errno)); + errh->fatal("%<%s%>: %s", cmdline.c_str(), strerror(errno)); StringAccum sa; int amt; do { - if (char *x = sa.reserve(2048)) { - amt = fread(x, 1, 2048, p); - sa.adjust_length(amt); - } else - amt = 0; + if (char *x = sa.reserve(2048)) { + amt = fread(x, 1, 2048, p); + sa.adjust_length(amt); + } else + amt = 0; } while (amt != 0 && sa.length() < 200000); if (amt != 0) - errh->warning("%<%s%> output too long, truncated", cmdline.c_str()); + errh->warning("%<%s%> output too long, truncated", cmdline.c_str()); else if (!feof(p) || ferror(p)) - errh->error("%<%s%>: %s", cmdline.c_str(), strerror(errno)); + errh->error("%<%s%>: %s", cmdline.c_str(), strerror(errno)); fclose(f); pclose(p); while (strip_newlines && sa && (sa.back() == '\n' || sa.back() == '\r')) - sa.pop_back(); + sa.pop_back(); return sa.take_string(); } #endif diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.hh.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.hh --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.hh.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/util.hh 2018-02-23 12:47:54.095971653 -0500 @@ -2,6 +2,7 @@ #define OTFTOTFM_UTIL_HH #include #include +#include class ErrorHandler; extern bool no_create; @@ -12,7 +13,7 @@ enum { G_ENCODING = 1, G_METRICS = 2, G_ G_PSFONTSMAP = 16, G_BINARY = 32, G_ASCII = 64, G_DOTLESSJ = 128, G_UPDMAP = 256, G_TRUETYPE = 512, G_TYPE42 = 1024 }; -extern int output_flags; +extern unsigned output_flags; String read_file(String filename, ErrorHandler *, bool warn = false); String printable_filename(const String &); @@ -21,6 +22,7 @@ bool same_filename(const String &a, cons String shell_quote(const String &); int temporary_file(String &, ErrorHandler *); int mysystem(const char *command, ErrorHandler *); +FILE* mypopen(const char* command, const char* type, ErrorHandler* errh); bool parse_unicode_number(const char*, const char*, int require_prefix, uint32_t& result); #ifdef WIN32 diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/README.md.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/README.md --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/README.md.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/README.md 2018-02-23 12:47:54.095971653 -0500 @@ -99,7 +99,7 @@ named `FONTNAME.afm` -- `MyriadMM-LightC Copyright and license --------------------- -All source code is Copyright (c) 1997-2016 Eddie Kohler. +All source code is Copyright (c) 1997-2018 Eddie Kohler. This code is distributed under the GNU General Public License, Version 2 (and only Version 2). The GNU General Public License is available via the diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.1 2018-02-23 12:47:54.096971628 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1dotlessj/t1dotlessj.cc 2018-02-23 12:47:54.096971628 -0500 @@ -1,6 +1,6 @@ /* t1dotlessj.cc -- driver for creating dotlessj characters from Type 1 fonts * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -317,7 +317,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1dotlessj (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2003-2016 Eddie Kohler\n\ + printf("Copyright (C) 2003-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -410,10 +410,10 @@ particular purpose.\n"); // write it to output if (!outputf) outputf = stdout; + if (binary) { #if defined(_MSDOS) || defined(_WIN32) - _setmode(_fileno(outputf), _O_BINARY); + _setmode(_fileno(outputf), _O_BINARY); #endif - if (binary) { Type1PFBWriter w(outputf); dotless_font->write(w); } else { diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/cscheck.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/cscheck.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/cscheck.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/cscheck.cc 2018-02-23 12:47:54.096971628 -0500 @@ -1,6 +1,6 @@ /* cscheck.{cc,hh} -- checking Type 1 charstrings for validity * - * Copyright (c) 1999-2016 Eddie Kohler + * Copyright (c) 1999-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.1 2018-02-23 12:47:54.096971628 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1lint/t1lint.cc 2018-02-23 12:47:54.096971628 -0500 @@ -1,6 +1,6 @@ /* t1lint.cc -- driver for checking Type 1 fonts for validity * - * Copyright (c) 1999-2016 Eddie Kohler + * Copyright (c) 1999-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -412,7 +412,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1lint (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 1999-2016 Eddie Kohler\n\ + printf("Copyright (C) 1999-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.1 2018-02-23 12:47:54.096971628 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1rawafm/t1rawafm.cc 2018-02-23 12:47:54.096971628 -0500 @@ -1,6 +1,6 @@ /* t1rawafm.cc -- driver for generating a raw AFM file from a font * - * Copyright (c) 2008-2016 Eddie Kohler + * Copyright (c) 2008-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -315,7 +315,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1rawafm (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2008-2016 Eddie Kohler\n\ + printf("Copyright (C) 2008-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -359,9 +359,6 @@ particular purpose.\n"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } -#if defined(_MSDOS) || defined(_WIN32) - _setmode(_fileno(outf), _O_BINARY); -#endif write_afm(outf, font); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.1 2018-02-23 12:47:54.097971603 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/t1reencode.cc 2018-02-23 12:47:54.097971603 -0500 @@ -1,6 +1,6 @@ /* t1reencode.cc -- driver for reencoding Type 1 fonts * - * Copyright (c) 2005-2016 Eddie Kohler + * Copyright (c) 2005-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -978,7 +978,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1reencode (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 1999-2016 Eddie Kohler\n\ + printf("Copyright (C) 1999-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -1094,10 +1094,10 @@ particular purpose.\n"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } + if (binary) { #if defined(_MSDOS) || defined(_WIN32) - _setmode(_fileno(outf), _O_BINARY); + _setmode(_fileno(outf), _O_BINARY); #endif - if (binary) { Type1PFBWriter w(outf); font->write(w); } else { diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/util.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/util.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/util.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1reencode/util.cc 2018-02-23 12:47:54.097971603 -0500 @@ -1,6 +1,6 @@ /* util.{cc,hh} -- various bits * - * Copyright (c) 2003-2016 Eddie Kohler + * Copyright (c) 2003-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.1 2018-02-23 12:47:54.097971603 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/t1testpage/t1testpage.cc 2018-02-23 12:47:54.097971603 -0500 @@ -1,6 +1,6 @@ /* t1testpage.cc -- driver for generating Type 1 fonts' test pages * - * Copyright (c) 1999-2016 Eddie Kohler + * Copyright (c) 1999-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -624,7 +624,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1testpage (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 1999-2016 Eddie Kohler\n\ + printf("Copyright (C) 1999-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -665,9 +665,6 @@ particular purpose.\n"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } -#if defined(_MSDOS) || defined(_WIN32) - _setmode(_fileno(outf), _O_BINARY); -#endif //font->undo_synthetic(); diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.1.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.1 --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.1.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.1 2018-02-23 12:47:54.097971603 -0500 @@ -1,4 +1,4 @@ -.ds V 2.106 +.ds V 2.107 .de M .BR "\\$1" "(\\$2)\\$3" .. diff -up texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.cc.git4166ff9 texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.cc --- texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.cc.git4166ff9 2016-11-25 13:08:53.000000000 -0500 +++ texlive-base-20170520/source/texk/lcdf-typetools/lcdf-typetools-src/ttftotype42/ttftotype42.cc 2018-02-23 12:47:54.098971578 -0500 @@ -1,6 +1,6 @@ /* ttftotype42.cc -- driver for translating TrueType fonts to Type 42 fonts * - * Copyright (c) 2006-2016 Eddie Kohler + * Copyright (c) 2006-2018 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -355,7 +355,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("ttftotype42 (LCDF typetools) %s\n", VERSION); - printf("Copyright (C) 2006-2016 Eddie Kohler\n\ + printf("Copyright (C) 2006-2018 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n");