summaryrefslogtreecommitdiffstats
path: root/examples/gdl/glyph.py
blob: 66944e0f52317829b24f6d6a0adb5539bf7242ee (plain)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env python
'Corresponds to a glyph, for analysis purposes, for GDL generation'
__url__ = 'http://github.com/silnrsi/pysilfont'
__copyright__ = 'Copyright (c) 2012 SIL International (http://www.sil.org)'
__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'

import re, traceback
from silfont.gdl.psnames import Name
from xml.etree.cElementTree import SubElement

# Convert from Graphite AP name to the standard name, eg upperM -> _upper
def gr_ap(txt) :
    if txt.endswith('M') :
        return "_" + txt[:-1]
    elif txt.endswith('S') :
        return txt[:-1]
    else :
        return txt

# Convert from standard AP name to the Graphite name, eg _upper -> upperM
def ap_gr(txt) :
    if txt.startswith('_') :
        return txt[1:] + 'M'
    else :
        return txt + 'S'


class Glyph(object) :

    isDia = False

    def __init__(self, name, gid = 0) :
        self.clear()
        self.setName(name)
        self.gdl = None
        self.gid = gid
        self.uid = ""     # this is a string!
        self.comment = ""
        self.isDia = False

    def clear(self) :
        self.anchors = {}
        self.classes = set()
        self.gdl_properties = {}
        self.properties = {}

    def setName(self, name) :
        self.psname = name
        self.name = next(self.parseNames())

    def setAnchor(self, name, x, y, t = None) :
        send = True
        if name in self.anchors :
            if x is None and y is None :
                del self.anchors[name]
                return True
            if x is None : x = self.anchors[name][0]
            if y is None : y = self.anchors[name][1]
            send = self.anchors[name] != (x, y)
        self.anchors[name] = (x, y)
        return send
        # if not name.startswith("_") and t != 'basemark' :
        #     self.isBase = True

    def parseNames(self) :
        if self.psname :
            for name in self.psname.split("/") :
                res = Name(name)
                yield res
        else :
            yield None

    def GDLName(self) :
        if self.gdl :
            return self.gdl
        elif self.name :
            return self.name.GDL()
        else :
            return None

    def setGDL(self, name) :
        self.gdl = name

    def readAP(self, elem, font) :
        self.uid = elem.get('UID', None)
        for p in elem.iterfind('property') :
            n = p.get('name')
            if n == 'GDLName' :
                self.setGDL(p.get('value'))
            elif n.startswith('GDL_') :
                self.gdl_properties[n[4:]] = p.get('value')
            else :
                self.properties[n] = p.get('value')
        for p in elem.iterfind('point') :
            l = p.find('location')
            self.setAnchor(ap_gr(p.get('type')), int(l.get('x', 0)), int(l.get('y', 0)))
        p = elem.find('note')
        if p is not None and p.text :
            self.comment = p.text
        if 'classes' in self.properties :
            for c in self.properties['classes'].split() :
                if c not in self.classes :
                    self.classes.add(c)
                    font.addGlyphClass(c, self, editable = True)

    def createAP(self, elem, font, autoGdlFile) :
        e = SubElement(elem, 'glyph')
        if self.psname : e.set('PSName', self.psname)
        if self.uid : e.set('UID', self.uid)
        if self.gid is not None : e.set('GID', str(self.gid))
        ce = None
        if 'classes' in self.properties and self.properties['classes'].strip() :
            tempClasses = self.properties['classes']
            self.properties['classes'] = " ".join(font.filterAutoClasses(self.properties['classes'].split(), autoGdlFile))

        for k in sorted(self.anchors.keys()) :
            v = self.anchors[k]
            p = SubElement(e, 'point')
            p.set('type', gr_ap(k))
            p.text = "\n        "
            l = SubElement(p, 'location')
            l.set('x', str(v[0]))
            l.set('y', str(v[1]))
            l.tail = "\n    "
            if ce is not None : ce.tail = "\n    "
            ce = p

        for k in sorted(self.gdl_properties.keys()) :
            if k == "*skipPasses*" : continue  # not set in GDL

            v = self.gdl_properties[k]
            if v :
                p = SubElement(e, 'property')
                p.set('name', 'GDL_' + k)
                p.set('value', v)
                if ce is not None : ce.tail = "\n    "
                ce = p

        if self.gdl and (not self.name or self.gdl != self.name.GDL()) :
            p = SubElement(e, 'property')
            p.set('name', 'GDLName')
            p.set('value', self.GDLName())
            if ce is not None : ce.tail = "\n    "
            ce = p

        for k in sorted(self.properties.keys()) :
            v = self.properties[k]
            if v :
                p = SubElement(e, 'property')
                p.set('name', k)
                p.set('value', v)
                if ce is not None : ce.tail = "\n    "
                ce = p

        if self.comment :
            p = SubElement(e, 'note')
            p.text = self.comment
            if ce is not None : ce.tail = "\n    "
            ce = p

        if 'classes' in self.properties and self.properties['classes'].strip() :
            self.properties['classes'] = tempClasses
        if ce is not None :
            ce.tail = "\n"
            e.text = "\n    "
        e.tail = "\n"
        return e

def isMakeGDLSpecialClass(name) :
#    if re.match(r'^cn?(Takes)?.*?Dia$', name) : return True
#    if name.startswith('clig') : return True
#    if name.startswith('cno_') : return True
    if re.match(r'^\*GC\d+\*$', name) : return True   # auto-pseudo glyph with name = *GCXXXX*
    return False