aboutsummaryrefslogtreecommitdiffstats
path: root/Lib/defconQt/objects/defcon.py
blob: 5de02973024fbc97dabf20d8920b873585445282 (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
175
176
177
178
179
180
181
182
183
184
from defcon import Font, Contour, Glyph, Point
from defcon.objects.base import BaseObject

class TFont(Font):
    def __init__(self, *args, **kwargs):
        if not "glyphClass" in kwargs:
            kwargs["glyphClass"] = TGlyph
        if not "glyphContourClass" in kwargs:
            kwargs["glyphContourClass"] = TContour
        if not "glyphPointClass" in kwargs:
            kwargs["glyphPointClass"] = TPoint
        super(TFont, self).__init__(*args, **kwargs)

    # XXX: had to copy all of this so as to exclude template glyphs from
    # save. It pains me that's the only thing to be done w current upstream
    def save(self, path=None, formatVersion=None):
        saveAs = False
        if path is not None and path != self._path:
            saveAs = True
        else:
            path = self._path
        ## work out the format version
        # if None is given, fallback to the one that
        # came in when the UFO was loaded
        if formatVersion is None and self._ufoFormatVersion is not None:
            formatVersion = self._ufoFormatVersion
        # otherwise fallback to 2
        elif self._ufoFormatVersion is None:
            formatVersion = 2
        ## make a UFOWriter
        ufoWriter = ufoLib.UFOWriter(path, formatVersion=formatVersion)
        ## save objects
        saveInfo = False
        saveKerning = False
        saveGroups = False
        saveFeatures = False
        ## lib should always be saved
        saveLib = True
        # if in a save as, save all objects
        if saveAs:
            saveInfo = True
            saveKerning = True
            saveGroups = True
            saveFeatures = True
        ## if changing ufo format versions, save all objects
        if self._ufoFormatVersion != formatVersion:
            saveInfo = True
            saveKerning = True
            saveGroups = True
            saveFeatures = True
        # save info, kerning and features if they are dirty
        if self._info is not None and self._info.dirty:
            saveInfo = True
        if self._kerning is not None and self._kerning.dirty:
            saveKerning = True
        if self._features is not None and self._features.dirty:
            saveFeatures = True
        # always save groups and lib if they are loaded
        # as they contain sub-objects that may not notify
        # the main object about changes.
        if self._groups is not None:
            saveGroups = True
        if self._lib is not None:
            saveLib = True
        # save objects as needed
        if saveInfo:
            ufoWriter.writeInfo(self.info)
            self._stampInfoDataState()
            self.info.dirty = False
        if saveKerning:
            ufoWriter.writeKerning(self.kerning)
            self._stampKerningDataState()
            self.kerning.dirty = False
        if saveGroups:
            ufoWriter.writeGroups(self.groups)
            self._stampGroupsDataState()
        if saveFeatures and formatVersion > 1:
            ufoWriter.writeFeatures(self.features.text)
            self._stampFeaturesDataState()
        if saveLib:
            # if making format version 1, do some
            # temporary down conversion before
            # passing the lib to the writer
            libCopy = dict(self.lib)
            if formatVersion == 1:
                self._convertToFormatVersion1RoboFabData(libCopy)
            ufoWriter.writeLib(libCopy)
            self._stampLibDataState()
        ## save glyphs
        # for a save as operation, load all the glyphs
        # and mark them as dirty.
        if saveAs:
            for glyph in self:
                glyph.dirty = True
        glyphSet = ufoWriter.getGlyphSet()
        for glyphName, glyphObject in self._glyphs.items():
            if glyphObject.template: continue
            if glyphObject.dirty:
                glyphSet.writeGlyph(glyphName, glyphObject, glyphObject.drawPoints)
                self._stampGlyphDataState(glyphObject)
        # remove deleted glyphs
        if not saveAs and self._scheduledForDeletion:
            for glyphName in self._scheduledForDeletion:
                if glyphName in glyphSet:
                    glyphSet.deleteGlyph(glyphName)
        glyphSet.writeContents()
        self._glyphSet = glyphSet
        self._scheduledForDeletion = []
        self._path = path
        self._ufoFormatVersion = formatVersion
        self.dirty = False

class TGlyph(Glyph):
    def __init__(self, *args, **kwargs):
        super(TGlyph, self).__init__(*args, **kwargs)
        self._template = False

    def _get_template(self):
        return self._template

    def _set_template(self, value):
        self._template = value

    template = property(_get_template, _set_template, doc="A boolean indicating whether the glyph is a template glyph.")

    def _set_dirty(self, value):
        BaseObject._set_dirty(self, value)
        if value:
            self.template = False

    dirty = property(BaseObject._get_dirty, _set_dirty)

class TContour(Contour):
    def __init__(self, pointClass=None):
        if pointClass is None:
            pointClass = TPoint
        super(TContour, self).__init__(pointClass)

    def drawPoints(self, pointPen):
        """
        Draw the contour with **pointPen**.
        """
        pointPen.beginPath()
        for point in self._points:
            pointPen.addPoint((point.x, point.y), segmentType=point.segmentType, smooth=point.smooth, name=point.name, selected=point.selected)
        pointPen.endPath()

class TPoint(Point):
    __slots__ = ["_selected"]

    def __init__(self, pt, segmentType=None, smooth=False, name=None, selected=False):
        super(TPoint, self).__init__(pt, segmentType, smooth, name)
        self._selected = selected

    def _get_selected(self):
        return self._selected

    def _set_selected(self, value):
        self._selected = value

    selected = property(_get_selected, _set_selected, doc="A boolean indicating the selected state of the point.")

class CharacterSet(object):
    __slots__ = ["_name", "_glyphNames"]

    def __init__(self, glyphNames, name=None):
        self._name = name
        self._glyphNames = glyphNames

    def _get_name(self):
        return self._name

    def _set_name(self, name):
        self._name = name

    name = property(_get_name, _set_name, doc="Character set name.")

    def _get_glyphNames(self):
        return self._glyphNames

    def _set_glyphNames(self, glyphNames):
        self._glyphNames = glyphNames

    glyphNames = property(_get_glyphNames, _set_glyphNames, doc="List of glyph names.")