1 #ifndef OTFTOTFM_GLYPHFILTER_HH
2 #define OTFTOTFM_GLYPHFILTER_HH
3 #include <efont/otf.hh>
4 #include <lcdf/vector.hh>
5 class Metrics;
6
7 class GlyphFilter { public:
8
GlyphFilter()9 GlyphFilter() : _sorted(true) { }
10
operator bool() const11 operator bool() const { return _patterns.size() != 0; }
12
13 inline bool allow_substitution(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const;
14 inline bool allow_alternate(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const;
15
16 void add_substitution_filter(const String&, bool is_exclude, ErrorHandler*);
17 void add_alternate_filter(const String&, bool is_exclude, ErrorHandler*);
18
19 friend bool operator==(const GlyphFilter&, const GlyphFilter&);
20 inline bool check_eq(GlyphFilter&); // may alter both GlyphFilters
21
22 GlyphFilter& operator+=(const GlyphFilter&);
23
24 void unparse(StringAccum&) const;
25
26 struct Pattern {
27 uint16_t type;
28 uint16_t data;
29 union {
30 struct {
31 int mask;
32 int value;
33 } uniprop;
34 struct {
35 uint32_t low;
36 uint32_t high;
37 } unirange;
38 } u;
39 String pattern;
40 Pattern(uint16_t type);
41 static int compare(const Pattern&, const Pattern&);
42 };
43
44 private:
45
46 enum { T_EXCLUDE = 1, T_NEGATE = 2, T_TYPEMASK = 3,
47 T_SRC = 0, T_DST = 4 };
48 enum { D_NAME, D_UNIPROP, D_UNIRANGE };
49
50 Vector<Pattern> _patterns;
51 bool _sorted;
52
53 bool allow(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode, int ptype) const;
54 void add_pattern(const String&, int ptype, ErrorHandler*);
55 void sort();
56
57 };
58
59 inline bool
allow_substitution(Efont::OpenType::Glyph glyph,const Vector<PermString> & glyph_names,uint32_t unicode) const60 GlyphFilter::allow_substitution(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const
61 {
62 return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_SRC));
63 }
64
65 inline bool
allow_alternate(Efont::OpenType::Glyph glyph,const Vector<PermString> & glyph_names,uint32_t unicode) const66 GlyphFilter::allow_alternate(Efont::OpenType::Glyph glyph, const Vector<PermString>& glyph_names, uint32_t unicode) const
67 {
68 return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_DST));
69 }
70
operator ==(const GlyphFilter::Pattern & a,const GlyphFilter::Pattern & b)71 inline bool operator==(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
72 {
73 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;
74 }
75
operator <(const GlyphFilter::Pattern & a,const GlyphFilter::Pattern & b)76 inline bool operator<(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
77 {
78 return GlyphFilter::Pattern::compare(a, b) < 0;
79 }
80
operator !=(const GlyphFilter::Pattern & a,const GlyphFilter::Pattern & b)81 inline bool operator!=(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b)
82 {
83 return !(a == b);
84 }
85
86 bool operator==(const GlyphFilter&, const GlyphFilter&);
87
operator !=(const GlyphFilter & a,const GlyphFilter & b)88 inline bool operator!=(const GlyphFilter& a, const GlyphFilter& b)
89 {
90 return !(a == b);
91 }
92
93 inline bool
check_eq(GlyphFilter & o)94 GlyphFilter::check_eq(GlyphFilter& o)
95 {
96 sort();
97 o.sort();
98 return *this == o;
99 }
100
101 GlyphFilter operator+(const GlyphFilter&, const GlyphFilter&);
102
103 inline StringAccum&
operator <<(StringAccum & sa,const GlyphFilter & gf)104 operator<<(StringAccum& sa, const GlyphFilter& gf)
105 {
106 gf.unparse(sa);
107 return sa;
108 }
109
110 #endif
111