def asFeaAST(self): b = feaast.Block() if self.is_cursive: allglyphs = set(self.bases.keys()) | set(self.marks.keys()) for g in allglyphs: b.statements.append( feaast.CursivePosStatement( glyphref([g]), g in self.bases and feaast.Anchor(*self.bases[g]), g in self.marks and feaast.Anchor(*self.marks[g]), )) else: if not hasattr(self, "baseslist"): sortByAnchor(self) # e.g. when testing for base in self.baseslist: statementtype = feaast.MarkBasePosStatement if self.font: if categorize_glyph(self.font, base[0][0])[0] == "mark": statementtype = feaast.MarkMarkPosStatement b.statements.append( statementtype( glyphref(base[0]), [[ feaast.Anchor(*base[1]), feaast.MarkClass(self.base_name) ]], )) return b
def parse_anchor_(self): self.expect_symbol_("<") self.expect_keyword_("anchor") location = self.cur_token_location_ if self.next_token_ == "NULL": self.expect_keyword_("NULL") self.expect_symbol_(">") return None if self.next_token_type_ == Lexer.NAME: name = self.expect_name_() anchordef = self.anchors_.resolve(name) if anchordef is None: raise FeatureLibError('Unknown anchor "%s"' % name, self.cur_token_location_) self.expect_symbol_(">") return ast.Anchor(location, anchordef.x, anchordef.y, anchordef.contourpoint, xDeviceTable=None, yDeviceTable=None) x, y = self.expect_number_(), self.expect_number_() contourpoint = None if self.next_token_ == "contourpoint": self.expect_keyword_("contourpoint") contourpoint = self.expect_number_() if self.next_token_ == "<": xDeviceTable = self.parse_device_() yDeviceTable = self.parse_device_() else: xDeviceTable, yDeviceTable = None, None self.expect_symbol_(">") return ast.Anchor(location, x, y, contourpoint, xDeviceTable, yDeviceTable)
def _anchor(self, adjustment): adv, dx, dy, adv_adjust_by, dx_adjust_by, dy_adjust_by = adjustment assert not adv_adjust_by dx_device = dx_adjust_by and dx_adjust_by.items() or None dy_device = dy_adjust_by and dy_adjust_by.items() or None return ast.Anchor( dx or 0, dy or 0, xDeviceTable=dx_device or None, yDeviceTable=dy_device or None, )
def asFeaAST(self): b = feaast.Block() # if any( # isinstance(x[0], VariableScalar) or isinstance(x[1], VariableScalar) # for x in list(self.bases.values()) + list(self.marks.values()) # ): # raise ValueError("Can't directly express a variable anchor in FEA") if self.is_cursive: allglyphs = set(self.bases.keys()) | set(self.marks.keys()) for g in allglyphs: b.statements.append( feaast.CursivePosStatement( _glyphref([g]), g in self.bases and feaast.Anchor(*self.bases[g]), g in self.marks and feaast.Anchor(*self.marks[g]), )) else: if not hasattr(self, "baseslist"): sortByAnchor(self) # e.g. when testing for base in self.baseslist: statementtype = feaast.MarkBasePosStatement if self.font: if categorize_glyph(self.font, base[0][0])[0] == "mark": statementtype = feaast.MarkMarkPosStatement if self.force_markmark: statementtype = feaast.MarkMarkPosStatement b.statements.append( statementtype( _glyphref(base[0]), [[ feaast.Anchor(*base[1]), feaast.MarkClass(self.base_name) ]], )) return b
def feaPreamble(self, ff): if self.is_cursive: return [] sortByAnchor(self) if not "mark_classes_done" in ff.scratch: ff.scratch["mark_classes_done"] = {} b = feaast.Block() for mark in self.markslist: if not (self.base_name, tuple( mark[0])) in ff.scratch["mark_classes_done"]: b.statements.append( feaast.MarkClassDefinition( feaast.MarkClass(self.base_name), feaast.Anchor(*mark[1]), _glyphref(mark[0]), )) ff.scratch["mark_classes_done"][(self.base_name, tuple(mark[0]))] = True return [b]