• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from __future__ import print_function, division, absolute_import
2from __future__ import unicode_literals
3from fontTools.voltLib.error import VoltLibError
4
5
6class Statement(object):
7    def __init__(self, location=None):
8        self.location = location
9
10    def build(self, builder):
11        pass
12
13
14class Expression(object):
15    def __init__(self, location=None):
16        self.location = location
17
18    def build(self, builder):
19        pass
20
21
22class Block(Statement):
23    def __init__(self, location=None):
24        Statement.__init__(self, location)
25        self.statements = []
26
27    def build(self, builder):
28        for s in self.statements:
29            s.build(builder)
30
31
32class VoltFile(Block):
33    def __init__(self):
34        Block.__init__(self, location=None)
35
36
37class LookupBlock(Block):
38    def __init__(self, name, location=None):
39        Block.__init__(self, location)
40        self.name = name
41
42    def build(self, builder):
43        builder.start_lookup_block(self.location, self.name)
44        Block.build(self, builder)
45        builder.end_lookup_block()
46
47
48class GlyphDefinition(Statement):
49    def __init__(self, name, gid, gunicode, gtype, components, location=None):
50        Statement.__init__(self, location)
51        self.name = name
52        self.id = gid
53        self.unicode = gunicode
54        self.type = gtype
55        self.components = components
56
57
58class GroupDefinition(Statement):
59    def __init__(self, name, enum, location=None):
60        Statement.__init__(self, location)
61        self.name = name
62        self.enum = enum
63        self.glyphs_ = None
64
65    def glyphSet(self, groups=None):
66        if groups is not None and self.name in groups:
67            raise VoltLibError(
68                'Group "%s" contains itself.' % (self.name),
69                self.location)
70        if self.glyphs_ is None:
71            if groups is None:
72                groups = set({self.name})
73            else:
74                groups.add(self.name)
75            self.glyphs_ = self.enum.glyphSet(groups)
76        return self.glyphs_
77
78
79class GlyphName(Expression):
80    """A single glyph name, such as cedilla."""
81    def __init__(self, glyph, location=None):
82        Expression.__init__(self, location)
83        self.glyph = glyph
84
85    def glyphSet(self):
86        return (self.glyph,)
87
88
89class Enum(Expression):
90    """An enum"""
91    def __init__(self, enum, location=None):
92        Expression.__init__(self, location)
93        self.enum = enum
94
95    def __iter__(self):
96        for e in self.glyphSet():
97            yield e
98
99    def glyphSet(self, groups=None):
100        glyphs = []
101        for element in self.enum:
102            if isinstance(element, (GroupName, Enum)):
103                glyphs.extend(element.glyphSet(groups))
104            else:
105                glyphs.extend(element.glyphSet())
106        return tuple(glyphs)
107
108
109class GroupName(Expression):
110    """A glyph group"""
111    def __init__(self, group, parser, location=None):
112        Expression.__init__(self, location)
113        self.group = group
114        self.parser_ = parser
115
116    def glyphSet(self, groups=None):
117        group = self.parser_.resolve_group(self.group)
118        if group is not None:
119            self.glyphs_ = group.glyphSet(groups)
120            return self.glyphs_
121        else:
122            raise VoltLibError(
123                'Group "%s" is used but undefined.' % (self.group),
124                self.location)
125
126
127class Range(Expression):
128    """A glyph range"""
129    def __init__(self, start, end, parser, location=None):
130        Expression.__init__(self, location)
131        self.start = start
132        self.end = end
133        self.parser = parser
134
135    def glyphSet(self):
136        return tuple(self.parser.glyph_range(self.start, self.end))
137
138
139class ScriptDefinition(Statement):
140    def __init__(self, name, tag, langs, location=None):
141        Statement.__init__(self, location)
142        self.name = name
143        self.tag = tag
144        self.langs = langs
145
146
147class LangSysDefinition(Statement):
148    def __init__(self, name, tag, features, location=None):
149        Statement.__init__(self, location)
150        self.name = name
151        self.tag = tag
152        self.features = features
153
154
155class FeatureDefinition(Statement):
156    def __init__(self, name, tag, lookups, location=None):
157        Statement.__init__(self, location)
158        self.name = name
159        self.tag = tag
160        self.lookups = lookups
161
162
163class LookupDefinition(Statement):
164    def __init__(self, name, process_base, process_marks, mark_glyph_set,
165                 direction, reversal, comments, context, sub, pos,
166                 location=None):
167        Statement.__init__(self, location)
168        self.name = name
169        self.process_base = process_base
170        self.process_marks = process_marks
171        self.mark_glyph_set = mark_glyph_set
172        self.direction = direction
173        self.reversal = reversal
174        self.comments = comments
175        self.context = context
176        self.sub = sub
177        self.pos = pos
178
179
180class SubstitutionDefinition(Statement):
181    def __init__(self, mapping, location=None):
182        Statement.__init__(self, location)
183        self.mapping = mapping
184
185
186class SubstitutionSingleDefinition(SubstitutionDefinition):
187    pass
188
189
190class SubstitutionMultipleDefinition(SubstitutionDefinition):
191    pass
192
193
194class SubstitutionLigatureDefinition(SubstitutionDefinition):
195    pass
196
197
198class SubstitutionReverseChainingSingleDefinition(SubstitutionDefinition):
199    pass
200
201
202class PositionAttachDefinition(Statement):
203    def __init__(self, coverage, coverage_to, location=None):
204        Statement.__init__(self, location)
205        self.coverage = coverage
206        self.coverage_to = coverage_to
207
208
209class PositionAttachCursiveDefinition(Statement):
210    def __init__(self, coverages_exit, coverages_enter, location=None):
211        Statement.__init__(self, location)
212        self.coverages_exit = coverages_exit
213        self.coverages_enter = coverages_enter
214
215
216class PositionAdjustPairDefinition(Statement):
217    def __init__(self, coverages_1, coverages_2, adjust_pair, location=None):
218        Statement.__init__(self, location)
219        self.coverages_1 = coverages_1
220        self.coverages_2 = coverages_2
221        self.adjust_pair = adjust_pair
222
223
224class PositionAdjustSingleDefinition(Statement):
225    def __init__(self, adjust_single, location=None):
226        Statement.__init__(self, location)
227        self.adjust_single = adjust_single
228
229
230class ContextDefinition(Statement):
231    def __init__(self, ex_or_in, left=None, right=None, location=None):
232        Statement.__init__(self, location)
233        self.ex_or_in = ex_or_in
234        self.left = left if left is not None else []
235        self.right = right if right is not None else []
236
237
238class AnchorDefinition(Statement):
239    def __init__(self, name, gid, glyph_name, component, locked,
240                 pos, location=None):
241        Statement.__init__(self, location)
242        self.name = name
243        self.gid = gid
244        self.glyph_name = glyph_name
245        self.component = component
246        self.locked = locked
247        self.pos = pos
248
249
250class SettingDefinition(Statement):
251    def __init__(self, name, value, location=None):
252        Statement.__init__(self, location)
253        self.name = name
254        self.value = value
255