Example #1
0
    def get_cached_glyph(self, name):
        if name in self.glyphcache: return self.glyphcache[name]
        paths = BezierPath.fromFonttoolsGlyph(self.font, name)
        pathbounds = []
        paths = list(filter(lambda p: p.length > 0, paths))
        for p in paths:
            p.hasAnchor = False
            p.glyphname = name
            if name in self.anchors:
                for a in self.anchors[name]:
                    if p.pointIsInside(Point(*a)): p.hasAnchor = True
            bounds = p.bounds()
            pathbounds.append(bounds)

        glyphbounds = BoundingBox()
        if pathbounds:
            for p in pathbounds:
                glyphbounds.extend(p)
        else:
            glyphbounds.tr = Point(0, 0)
            glyphbounds.bl = Point(0, 0)
        self.glyphcache[name] = {
            "name": name,
            "paths": paths,
            "pathbounds": pathbounds,
            "glyphbounds": glyphbounds,
            "category": categorize_glyph(self.font, name)[0],
            "pathconvexhull": None  # XXX
        }
        assert (len(self.glyphcache[name]["pathbounds"]) == len(
            self.glyphcache[name]["paths"]))
        return self.glyphcache[name]
Example #2
0
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
Example #3
0
 def recategorize(self, font):
     try:
         self.category = categorize_glyph(font, self.glyph)
         if not self.category[0]:
             self.category = ("unknown", None)
     except Exception as e:
         warnings.warn("Error getting category: %s" % str(e))
         self._fallback_categorize()
Example #4
0
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