def test_simple_sub(self): pos = Substitution(["a"], ["b"]) r = Routine(rules=[pos], name="dummy") rr = RoutineReference(routine=r) c = Chaining([["a"], ["b"]], lookups=[[rr], None]) self.assertEqual(c.asFea(), "sub a' lookup dummy b';")
def test_complex_pos(self): v = ValueRecord(xAdvance=120) pos1 = Positioning(["a"], [v]) r1 = Routine(rules=[pos1]) rr1 = RoutineReference(routine=r1) c = Chaining([["a"], ["b"]], lookups=[[rr1], None]) c.feaPreamble(FontFeatures()) self.assertEqual(c.asFea(), "pos a' lookup ChainedRoutine1 b';")
def test_complex(self): pos1 = Substitution(["a"], ["b"]) pos2 = Substitution(["b"], ["c"]) r1 = Routine(rules=[pos1], name="dummy1") r2 = Routine(rules=[pos2], name="dummy2") rr1 = RoutineReference(routine=r1) rr2 = RoutineReference(routine=r2) c = Chaining([["a"], ["b"]], lookups=[[rr1, rr2], None]) self.assertEqual(c.asFea(), "sub a' lookup dummy1 lookup dummy2 b';")
def test_simple_pos(self): v = ValueRecord(xAdvance=120) pos = Positioning(["a"], [v]) r = Routine(rules=[pos], name="dummy") rr = RoutineReference(routine=r) c = Chaining([["a"], ["b"]], lookups=[[rr], None]) self.assertEqual(c.asFea(), "pos a' lookup dummy b';") self.assertEqual( etree.tostring(c.toXML()), '<chaining><lookups><slot><routinereference name="dummy"/></slot><slot><lookup/></slot></lookups><input><slot><glyph>a</glyph></slot><slot><glyph>b</glyph></slot></input></chaining>' .encode("utf-8"))
def mitigate(self, rules, which, rule_classes, failing_slot): # What kind of fail is this? problem = None for klass in rule_classes[1:]: if not set(klass).isdisjoint(failing_slot): problem = klass break # Split both into two and try again additional_rules = [] intersection = set(problem) & failing_slot assert intersection for rule in rules: for ix, slot in enumerate(getattr(rule, which)): if (set(slot) == set(problem) or set(slot) == failing_slot) and set(slot) != intersection: new_rule = Chaining( copy.deepcopy(rule.input), precontext=copy.deepcopy(rule.precontext), postcontext=copy.deepcopy(rule.postcontext), lookups=rule.lookups[:]) setattr(new_rule, which, getattr(new_rule, which)[:]) setattr(rule, which, getattr(rule, which)[:]) getattr(rule, which)[ix] = list(set(slot) - intersection) getattr(new_rule, which)[ix] = list(intersection) additional_rules.append(new_rule) rules.extend(additional_rules)
def test_routine_partition(): f = FontFeatures() s1 = Substitution([["A"]], [["A.grk"]], languages=["grek/*"]) s2 = Substitution([["A"]], [["A.esp"]], languages=["latn/ESP "]) r = Routine(rules=[s1, s2], flags=0x2) f.routines.append(r) dummy = Routine(rules=[Substitution([["G"]], [["G"]])]) f.routines.append(dummy) c = Chaining( [["A"], ["V"]], lookups=[ [RoutineReference(routine=dummy), RoutineReference(routine=r)], [RoutineReference(routine=r), RoutineReference(routine=dummy)], ]) r2 = Routine(rules=[c]) f.routines.append(r2) f.addFeature("locl", [r]) f.partitionRoutine(r, lambda rule: tuple(rule.languages or [])) assert len(f.routines) == 4 assert f.routines[0].flags == f.routines[1].flags assert len(f.routines[0].rules) == 1 assert len(f.routines[1].rules) == 1 assert f.routines[0].rules[0].replacement[0][0] == "A.grk" assert f.routines[1].rules[0].replacement[0][0] == "A.esp" assert len(c.lookups[0]) == 3 assert len(f.features["locl"]) == 2
def test_ignore(self): c = Chaining([["a"], ["b"]], lookups=[]) self.assertEqual(c.asFea(), "ignore sub a b;")
def addChainRule(self): self.model().addRule(self.selectedIndexes()[0], Chaining([[]], lookups=[[]])) self.parent.editor.setWindowModified(True)