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
|
#ifndef OTFTOTFM_GLYPHFILTER_HH
#define OTFTOTFM_GLYPHFILTER_HH
#include <efont/otf.hh>
#include <lcdf/vector.hh>
class Metrics;
class GlyphFilter { public:
GlyphFilter() : _sorted(true) { }
operator bool() const { return _patterns.size() != 0; }
inline bool allow_substitution(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const;
inline bool allow_alternate(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const;
void add_substitution_filter(const String&, bool is_exclude, ErrorHandler*);
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
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&);
};
private:
enum { T_EXCLUDE = 1, T_NEGATE = 2, T_TYPEMASK = 3,
T_SRC = 0, T_DST = 4 };
enum { D_NAME, D_UNIPROP, D_UNIRANGE };
Vector<Pattern> _patterns;
bool _sorted;
bool allow(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode, int ptype) const;
void add_pattern(const String&, int ptype, ErrorHandler*);
void sort();
};
inline bool
GlyphFilter::allow_substitution(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const
{
return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_SRC));
}
inline bool
GlyphFilter::allow_alternate(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const
{
return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_DST));
}
inline bool operator==(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
{
return a.type == b.type && a.data == b.data && a.u.unirange.low == b.u.unirange.low && a.u.unirange.high == b.u.unirange.high && a.pattern == b.pattern;
}
inline bool operator<(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
{
return GlyphFilter::Pattern::compare(a, b) < 0;
}
inline bool operator!=(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
{
return !(a == b);
}
bool operator==(const GlyphFilter&, const GlyphFilter&);
inline bool operator!=(const GlyphFilter& a, const GlyphFilter& b)
{
return !(a == b);
}
inline bool
GlyphFilter::check_eq(GlyphFilter& o)
{
sort();
o.sort();
return *this == o;
}
GlyphFilter operator+(const GlyphFilter&, const GlyphFilter&);
inline StringAccum&
operator<<(StringAccum& sa, const GlyphFilter& gf)
{
gf.unparse(sa);
return sa;
}
#endif
|