summaryrefslogtreecommitdiff
path: root/Build/source/texk/lcdf-typetools/lcdf-typetools-2.95/include/efont/otfname.hh
blob: c91fc5af95f34f4b9db53367c5762daf21be6dee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// -*- related-file-name: "../../libefont/otfname.cc" -*-
#ifndef EFONT_OTFNAME_HH
#define EFONT_OTFNAME_HH
#include <efont/otf.hh>
#include <efont/otfdata.hh>	// for ntohl()
#include <lcdf/error.hh>
namespace Efont { namespace OpenType {

class Name { public:

    Name(const String &, ErrorHandler * = 0);
    // default destructor

    bool ok() const			{ return _error >= 0; }
    int error() const			{ return _error; }

    enum NameID { N_COPYRIGHT = 0, N_FAMILY = 1, N_SUBFAMILY = 2,
		  N_UNIQUEID = 3, N_FULLNAME = 4, N_VERSION = 5,
		  N_POSTSCRIPT = 6, N_TRADEMARK = 7, N_MANUFACTURER = 8,
		  N_DESIGNER = 9, N_DESCRIPTION = 10, N_VENDOR_URL = 11,
		  N_DESIGNER_URL = 12, N_LICENSE_DESCRIPTION = 13,
		  N_LICENSE_URL = 14, N_PREF_FAMILY = 16,
		  N_PREF_SUBFAMILY = 17, N_MAC_COMPAT_FULLNAME = 18,
		  N_SAMPLE_TEXT = 19, N_POSTSCRIPT_CID = 20 };
    enum Platform { P_UNICODE = 0, P_MACINTOSH = 1, P_MICROSOFT = 3,
		    E_MS_UNICODE_BMP = 1, E_MAC_ROMAN = 0,
		    L_MS_ENGLISH_AMERICAN = 0x409 };
    enum { HEADER_SIZE = 6, NAMEREC_SIZE = 12 };

    typedef uint8_t namerecord_t[NAMEREC_SIZE];
    typedef const namerecord_t *const_iterator;

    inline static int nameid(const namerecord_t &);
    inline static int platform(const namerecord_t &);
    inline static int encoding(const namerecord_t &);
    inline static int language(const namerecord_t &);

    inline const_iterator begin() const;
    inline const_iterator end() const;
    String name(const_iterator) const;
    String utf8_name(const_iterator) const;
    String english_name(int nameid) const;

    // check version string for backwards compatibility
    bool version_chaincontext_reverse_backtrack() const;

    struct PlatformPred {
	inline PlatformPred(int nameid, int platform = -1, int encoding = -1, int language = -1);
	inline bool operator()(const namerecord_t &) const;
      private:
	int _nameid, _platform, _encoding, _language;
    };

    struct EnglishPlatformPred {
	EnglishPlatformPred(int nameid)	: _nameid(nameid) { }
	inline bool operator()(const namerecord_t &) const;
      private:
	int _nameid;
    };

  private:

    String _str;
    int _error;

    int parse_header(ErrorHandler *);

};


#define USHORT_AT(d)		(ntohs(*reinterpret_cast<const uint16_t *>(d)))

inline int Name::nameid(const namerecord_t &nr)
{
    return USHORT_AT(reinterpret_cast<const uint8_t *>(&nr) + 6);
}

inline int Name::platform(const namerecord_t &nr)
{
    return USHORT_AT(reinterpret_cast<const uint8_t *>(&nr));
}

inline int Name::encoding(const namerecord_t &nr)
{
    return USHORT_AT(reinterpret_cast<const uint8_t *>(&nr) + 2);
}

inline int Name::language(const namerecord_t &nr)
{
    return USHORT_AT(reinterpret_cast<const uint8_t *>(&nr) + 4);
}

inline Name::const_iterator Name::begin() const
{
    return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE);
}

inline Name::const_iterator Name::end() const
{
    if (_error >= 0) {
	int count = USHORT_AT(_str.data() + 2);
	return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE + NAMEREC_SIZE * count);
    } else
	return reinterpret_cast<const_iterator>(_str.udata() + HEADER_SIZE);
}

#undef USHORT_AT


inline Name::PlatformPred::PlatformPred(int nid, int p, int e, int l)
    : _nameid(nid), _platform(p), _encoding(e), _language(l)
{
}

inline bool Name::PlatformPred::operator()(const namerecord_t &i) const
{
    return (_nameid == nameid(i))
	&& (_platform < 0 || _platform == platform(i))
	&& (_encoding < 0 || _encoding == encoding(i))
	&& (_language < 0 || _language == language(i));
}

inline bool Name::EnglishPlatformPred::operator()(const namerecord_t &i) const
{
    if (_nameid == nameid(i)) {
	int p = platform(i), e = encoding(i), l = language(i);
	return (p == P_MACINTOSH && e == E_MAC_ROMAN && l == 0)
	    || (p == P_MICROSOFT && e == E_MS_UNICODE_BMP && l == L_MS_ENGLISH_AMERICAN);
    } else
	return false;
}

}}
#endif