File: FontFeatures.py

package info (click to toggle)
python-fontfeatures 1.9.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,096 kB
  • sloc: python: 9,112; makefile: 22
file content (91 lines) | stat: -rw-r--r-- 2,906 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""Routines for converting FontFeatures objects to and from XML."""

from lxml import etree


def toXML(self):
    """Serializes a FontFeatures object to a lxml Element object."""
    root = etree.Element("fontfeatures")
    root.append(xml_glyph_classes(self))

    routines = etree.Element("routines")
    for r in self.routines:
        routines.append(r.toXML())
    root.append(routines)

    features = etree.Element("features")
    for f, routines in self.features.items():
        f_el = etree.Element("feature")
        f_el.set("name", f)
        for r in routines:
            f_el.append(r.toXML())
        features.append(f_el)
    root.append(features)

    anchor_el = etree.Element("anchors")
    for glyph, anchors in self.anchors.items():
        glyph_el = etree.Element("glyph")
        glyph_el.set("name", glyph)
        for name, pos in anchors.items():
            a_el = etree.Element("anchor")
            a_el.set("name", name)
            a_el.set("x", str(pos[0]))
            a_el.set("y", str(pos[1]))
            glyph_el.append(a_el)
        anchor_el.append(glyph_el)
    root.append(anchor_el)

    glyphclasses = etree.Element("glyphclasses")
    for glyph, classname in self.glyphclasses.items():
        glyph_el = etree.Element("glyph")
        glyph_el.set("name", glyph)
        glyph_el.set("class", classname)
        glyphclasses.append(glyph_el)
    root.append(glyphclasses)

    return root


def xml_glyph_classes(self):
    root = etree.Element("namedclasses")
    for name, values in self.namedClasses.items():
        gc = etree.Element("class")
        gc.set("name", name)
        for g in values:
            glyph_el = etree.Element("glyph")
            glyph_el.text = g
            gc.append(glyph_el)
        root.append(gc)
    return root


@classmethod
def fromXML(klass, el):
    """Creates a FontFeatures object from a lxml Element object."""
    f = klass()
    from fontFeatures import RoutineReference, Routine

    for part in el:
        if part.tag == "namedclasses":
            for cl_el in part:
                f.namedClasses[cl_el.get("name")] = [g.text for g in cl_el]
        elif part.tag == "routines":
            f.routines = [Routine.fromXML(r) for r in part]
        elif part.tag == "features":
            for feat in part:
                f.features[feat.get("name")] = [
                    RoutineReference.fromXML(x) for x in feat
                ]
        elif part.tag == "anchors":
            for glyph in part:
                f.anchors[glyph.get("name")] = {
                    el.get("name"): (int(el.get("x")), int(el.get("y"))) for el in glyph
                }
        elif part.tag == "glyphclasses":
            for cl_el in part:
                f.glyphclasses[cl_el.get("name")] = cl_el.get("class")

    for refs in f.features.values():
        for ref in refs:
            ref.resolve(f)
    return f