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