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