Merge remote-tracking branch 'origin/mutedGlyphNames_issue15'

This commit is contained in:
Erik van Blokland 2017-08-16 14:21:51 +02:00
commit 735edc7e61
5 changed files with 109 additions and 12 deletions

View File

@ -175,6 +175,7 @@ class InstanceDescriptor(SimpleDescriptor):
self.localisedStyleMapStyleName = {}
self.localisedStyleMapFamilyName = {}
self.glyphs = {}
self.mutedGlyphNames = []
self.kerning = True
self.info = True

View File

@ -23,14 +23,14 @@
<source filename="masters/masterTest1.ufo" name="master.ufo1">
<info copy="1" />
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="0" />
<dimension name="width" xvalue="0" />
</location>
</source>
<source filename="masters/masterTest2.ufo" name="master.ufo2">
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="1000" />
<dimension name="width" xvalue="0" />
</location>
</source>
</sources>
@ -44,8 +44,8 @@
<stylemapfamilyname xml:lang="de">Montserrat Halbfett</stylemapfamilyname>
<stylemapfamilyname xml:lang="ja">モンセラート SemiBold</stylemapfamilyname>
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="500" />
<dimension name="width" xvalue="0" />
</location>
<glyphs>
<glyph mute="1" name="arrow" />

View File

@ -23,14 +23,14 @@
<source filename="masters/masterTest1.ufo" name="master.ufo1">
<info copy="1" />
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="0" />
<dimension name="width" xvalue="0" />
</location>
</source>
<source filename="masters/masterTest2.ufo" name="master.ufo2">
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="1000" />
<dimension name="width" xvalue="0" />
</location>
</source>
</sources>
@ -44,8 +44,8 @@
<stylemapfamilyname xml:lang="de">Montserrat Halbfett</stylemapfamilyname>
<stylemapfamilyname xml:lang="ja">モンセラート SemiBold</stylemapfamilyname>
<location>
<dimension name="width" xvalue="0" />
<dimension name="weight" xvalue="500" />
<dimension name="width" xvalue="0" />
</location>
<glyphs>
<glyph mute="1" name="arrow" />

View File

@ -39,6 +39,63 @@ import os
Parking the glyphs under a swapname is a bit lazy, but at least it guarantees the glyphs have the right parent.
"""
""" These are some UFO specific tools for use with Mutator.
build() is a convenience function for reading and executing a designspace file.
documentPath: filepath to the .designspace document
outputUFOFormatVersion: ufo format for output
verbose: True / False for lots or no feedback
logPath: filepath to a log file
progressFunc: an optional callback to report progress.
see mutatorMath.ufo.tokenProgressFunc
"""
def build(
documentPath,
outputUFOFormatVersion=2,
roundGeometry=True,
verbose=True, # not supported
logPath=None, # not supported
progressFunc=None, # not supported
processRules=True
):
"""
Simple builder for UFO designspaces.
"""
import os, glob
if os.path.isdir(documentPath):
# process all *.designspace documents in this folder
todo = glob.glob(os.path.join(documentPath, "*.designspace"))
else:
# process the
todo = [documentPath]
results = []
for path in todo:
reader = DesignSpaceProcessor(ufoVersion=outputUFOFormatVersion)
reader.roundGeometry = roundGeometry
reader.read(path)
reader.generateUFO(processRules=processRules)
# reader = DesignSpaceDocumentReader(
# path,
# ufoVersion=outputUFOFormatVersion,
# roundGeometry=roundGeometry,
# verbose=verbose,
# logPath=logPath,
# progressFunc=progressFunc
# )
reader = None
return results
def swapGlyphNames(font, oldName, newName, swapNameExtension = "_______________swap"):
if not oldName in font or not newName in font:
return None
@ -51,6 +108,7 @@ def swapGlyphNames(font, oldName, newName, swapNameExtension = "_______________s
p = font[swapName].getPointPen()
font[oldName].drawPoints(p)
font[swapName].width = font[oldName].width
# lib?
font[oldName].clear()
p = font[oldName].getPointPen()
@ -255,7 +313,9 @@ class DesignSpaceProcessor(DesignSpaceDocument):
# this is the source
self._copyFontInfo(self.fonts[sourceDescriptor.name].info, font.info)
if sourceDescriptor.copyLib:
font.lib.update(self.fonts[sourceDescriptor.name].lib)
# excplicitly copy the font.lib items
for key, value in self.fonts[sourceDescriptor.name].lib.items():
font.lib[key] = value
if sourceDescriptor.copyFeatures:
featuresText = self.fonts[sourceDescriptor.name].features.text
if isinstance(featuresText, str):
@ -353,6 +413,11 @@ class DesignSpaceProcessor(DesignSpaceDocument):
for oldName, newName in zip(self.glyphNames, resultNames):
if oldName != newName:
swapGlyphNames(font, oldName, newName)
# copy the glyph lib?
#for sourceDescriptor in self.sources:
# if sourceDescriptor.copyLib:
# pass
# pass
# store designspace location in the font.lib
font.lib['designspace'] = list(instanceDescriptor.location.items())
return font
@ -505,6 +570,8 @@ if __name__ == "__main__":
f2.info.descender = -100
f1.info.copyright = u"This is the copyright notice from master 1"
f2.info.copyright = u"This is the copyright notice from master 2"
f1.lib['ufoProcessor.test.lib.entry'] = "Lib entry for master 1"
f2.lib['ufoProcessor.test.lib.entry'] = "Lib entry for master 2"
f1.save(path1, 2)
f2.save(path2, 2)
return path1, path2, path3, path4, path5
@ -542,6 +609,7 @@ if __name__ == "__main__":
s1.name = "test.master.1"
s1.copyInfo = True
s1.copyFeatures = True
s1.copyLib = True
d.addSource(s1)
s2 = SourceDescriptor()
s2.path = m2
@ -563,6 +631,7 @@ if __name__ == "__main__":
i.kerning = True
if counter == 2:
i.glyphs['glyphTwo'] = dict(name="glyphTwo", mute=True)
i.copyLib = True
d.addInstance(i)
d.write(docPath)

View File

@ -18,7 +18,7 @@ A couple of differences between things that use designspaces:
* The goals of Varlib and MutatorMath are different, so not all attributes are always needed.
* Need to expand the description of FDK use of designspace files.
The DesignSpaceDocument object can read and write .designspace data. It imports the axes, sources and instances to very basic **descriptor** objects that store the data in attributes. Data is added to the document by creating such descriptor objects, filling them with data and then adding them to the document. This makes it easy to integrate this object in different contexts.
The DesignSpaceDocument object can read and write `.designspace` data. It imports the axes, sources and instances to very basic **descriptor** objects that store the data in attributes. Data is added to the document by creating such descriptor objects, filling them with data and then adding them to the document. This makes it easy to integrate this object in different contexts.
The **DesignSpaceDocument** object can be subclassed to work with different objects, as long as they have the same attributes.
@ -45,6 +45,10 @@ Some validation is done when reading.
* If no source has a `copyInfo` flag, mutatorMath will be used to select one. This source gets its `copyInfo` flag set. If you save the document this flag will be set.
* Use `doc.checkDefault()` to set the default font.
# Localisation
Some of the descriptors support localised names. The names are stored in dictionaries using the language code as key. That means that there are now two places to store names: the old attribute and the new localised dictionary, `obj.stylename` and `obj.localisedStyleName['en']`.
# Rules
**The `rule` element is experimental.** Some ideas behind how rules could work in designspaces come from Superpolator. Such rules can maybe be used to describe some of the conditional GSUB functionality of OpenType 1.8. The definition of a rule is not that complicated. A rule has a name, and it has a number of conditions. The rule also contains a list of glyphname pairs: the glyphs that need to be substituted.
@ -90,19 +94,41 @@ doc.addSource(s1)
```
# `InstanceDescriptor` object
## Attributes ##
* `filename`: string. Relative path to the instance file, **as it is in the document**. The file may or may not exist. MutatorMath.
* `path`: string. Absolute path to the source file, calculated from the document path and the string in the filename attr. The file may or may not exist. MutatorMath.
* `name`: string. Unique identifier name of the instance, used to identify it if it needs to be referenced from elsewhere in the document.
* `location`: dict. Axis values for this source. MutatorMath + Varlib.
* `familyName`: string. Family name of this instance. MutatorMath + Varlib.
* `localisedFamilyName`: dict. A dictionary of localised family name strings, keyed by language code.
* `styleName`: string. Style name of this source. MutatorMath + Varlib.
* `postScriptFontName`: string. Postscript FontName for this instance. MutatorMath.
* `styleMapFamilyName`: string. StyleMap FamilyName for this instance. MutatorMath.
* `styleMapStyleName`: string. StyleMap StyleName for this instance. MutatorMath.
* `localisedStyleName`: dict. A dictionary of localised stylename strings, keyed by language code.
* `postScriptFontName`: string. Postscript fontname for this instance. MutatorMath.
* `styleMapFamilyName`: string. StyleMap familyname for this instance. MutatorMath.
* `localisedStyleMapFamilyName`: A dictionary of localised style map familyname strings, keyed by language code.
* `localisedStyleMapStyleName`: A dictionary of localised style map stylename strings, keyed by language code.
* `styleMapStyleName`: string. StyleMap stylename for this instance. MutatorMath.
* `glyphs`: dict for special master definitions for glyphs. If glyphs need special masters (to record the results of executed rules for example). MutatorMath.
* `mutedGlyphNames`: list of glyphnames that should be suppressed in the generation of this instance.
* `kerning`: bool. Indicates if this instance needs its kerning calculated. MutatorMath.
* `info`: bool. Indicated if this instance needs the interpolating font.info calculated.
## Methods ##
These methods give easier access to the localised names.
* `setStyleName(styleName, languageCode="en")`
* `getStyleName(languageCode="en")`
* `setFamilyName(familyName, languageCode="en")`
* `getFamilyName(self, languageCode="en")`
* `setStyleMapStyleName(styleMapStyleName, languageCode="en")`
* `getStyleMapStyleName(languageCode="en")`
* `setStyleMapFamilyName(styleMapFamilyName, languageCode="en")`
* `getStyleMapFamilyName(languageCode="en")`
## Example ##
```python
i2 = InstanceDescriptor()
i2.path = instancePath2
@ -314,8 +340,8 @@ myDoc = DesignSpaceDocument(KeyedDocReader, KeyedDocWriter)
* MutatorMath only
### Attributes
* `mute`: optional attribute, number 1 or 0. Indicate if this glyph should be ignored as a master.
* `<glyph mute="1" name="A"/>`
* `mute`: optional, number, andts
* MutatorMath only
### Example
@ -372,6 +398,7 @@ myDoc = DesignSpaceDocument(KeyedDocReader, KeyedDocWriter)
### Attributes
* `name`: string. The name of the glyph.
* `unicode`: string. Unicode value for this glyph, in hexadecimal.
* `mute`: optional attribute, number 1 or 0. Indicate if this glyph should be supressed in the output.
# 4.2.1 `note` element
* String. The value corresponds to glyph.note in UFO.