[designspaceLib] Switch doc files for designspaceLib from CRLF to LF
This commit is contained in:
parent
483e1489b4
commit
ede5de6fb0
File diff suppressed because it is too large
Load Diff
@ -1,249 +1,249 @@
|
||||
#######################
|
||||
Scripting a designspace
|
||||
#######################
|
||||
|
||||
It can be useful to build a designspace with a script rather than
|
||||
construct one with an interface like
|
||||
`Superpolator <http://superpolator.com>`__ or
|
||||
`DesignSpaceEditor <https://github.com/LettError/designSpaceRoboFontExtension>`__.
|
||||
|
||||
`fontTools.designspaceLib` offers a some tools for building designspaces in
|
||||
Python. This document shows an example.
|
||||
|
||||
********************************
|
||||
Filling-in a DesignSpaceDocument
|
||||
********************************
|
||||
|
||||
So, suppose you installed the `fontTools` package through your favorite
|
||||
``git`` client.
|
||||
|
||||
The ``DesignSpaceDocument`` object represents the document, whether it
|
||||
already exists or not. Make a new one:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from fontTools.designspaceLib import (DesignSpaceDocument, AxisDescriptor,
|
||||
SourceDescriptor, InstanceDescriptor)
|
||||
doc = DesignSpaceDocument()
|
||||
|
||||
We want to create definitions for axes, sources and instances. That
|
||||
means there are a lot of attributes to set. The **DesignSpaceDocument
|
||||
object** uses objects to describe the axes, sources and instances. These
|
||||
are relatively simple objects, think of these as collections of
|
||||
attributes.
|
||||
|
||||
- Attributes of the :ref:`source-descriptor-object`
|
||||
- Attributes of the :ref:`instance-descriptor-object`
|
||||
- Attributes of the :ref:`axis-descriptor-object`
|
||||
- Read about :ref:`subclassing-descriptors`
|
||||
|
||||
Make an axis object
|
||||
===================
|
||||
|
||||
Make a descriptor object and add it to the document.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1 = AxisDescriptor()
|
||||
a1.maximum = 1000
|
||||
a1.minimum = 0
|
||||
a1.default = 0
|
||||
a1.name = "weight"
|
||||
a1.tag = "wght"
|
||||
doc.addAxis(a1)
|
||||
|
||||
- You can add as many axes as you need. OpenType has a maximum of
|
||||
around 64K. DesignSpaceEditor has a maximum of 5.
|
||||
- The ``name`` attribute is the name you'll be using as the axis name
|
||||
in the locations.
|
||||
- The ``tag`` attribute is the one of the registered `OpenType
|
||||
Variation Axis
|
||||
Tags <https://www.microsoft.com/typography/otspec/fvar.htm#VAT>`__
|
||||
|
||||
Option: add label names
|
||||
-----------------------
|
||||
|
||||
The **labelnames** attribute is intended to store localisable, human
|
||||
readable names for this axis if this is not an axis that is registered
|
||||
by OpenType. Think "The label next to the slider". The attribute is a
|
||||
dictionary. The key is the `xml language
|
||||
tag <https://www.w3.org/International/articles/language-tags/>`__, the
|
||||
value is a utf-8 string with the name. Whether or not this attribute is
|
||||
used depends on the font building tool, the operating system and the
|
||||
authoring software. This, at least, is the place to record it.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1.labelNames['fa-IR'] = u"قطر"
|
||||
a1.labelNames['en'] = u"Wéíght"
|
||||
|
||||
Option: add a map
|
||||
-----------------
|
||||
|
||||
The **map** attribute is a list of (input, output) mapping values
|
||||
intended for `axis variations table of
|
||||
OpenType <https://www.microsoft.com/typography/otspec/avar.htm>`__.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)]
|
||||
|
||||
Make a source object
|
||||
====================
|
||||
|
||||
A **source** is an object that points to a UFO file. It provides the
|
||||
outline geometry, kerning and font.info that we want to work with.
|
||||
|
||||
.. code:: python
|
||||
|
||||
s0 = SourceDescriptor()
|
||||
s0.path = "my/path/to/thin.ufo"
|
||||
s0.name = "master.thin"
|
||||
s0.location = dict(weight=0)
|
||||
doc.addSource(s0)
|
||||
|
||||
- You'll need to have at least 2 sources in your document, so go ahead
|
||||
and add another one.
|
||||
- The **location** attribute is a dictionary with the designspace
|
||||
location for this master.
|
||||
- The axis names in the location have to match one of the ``axis.name``
|
||||
values you defined before.
|
||||
- The **path** attribute is the absolute path to an existing UFO.
|
||||
- The **name** attribute is a unique name for this source used to keep
|
||||
track it.
|
||||
|
||||
So go ahead and add another master:
|
||||
|
||||
.. code:: python
|
||||
|
||||
s1 = SourceDescriptor()
|
||||
s1.path = "my/path/to/bold.ufo"
|
||||
s1.name = "master.bold"
|
||||
s1.location = dict(weight=1000)
|
||||
doc.addSource(s1)
|
||||
|
||||
Option: exclude glyphs
|
||||
----------------------
|
||||
|
||||
By default all glyphs in a source will be processed. If you want to
|
||||
exclude certain glyphs, add their names to the ``mutedGlyphNames`` list.
|
||||
|
||||
.. code:: python
|
||||
|
||||
s1.mutedGlyphNames = ["A.test", "A.old"]
|
||||
|
||||
Make an instance object
|
||||
=======================
|
||||
|
||||
An **instance** is description of a UFO that you want to generate with
|
||||
the designspace. For an instance you can define more things. If you want
|
||||
to generate UFO instances with MutatorMath then you can define different
|
||||
names and set flags for if you want to generate kerning and font info
|
||||
and so on. You can also set a path where to generate the instance.
|
||||
|
||||
.. code:: python
|
||||
|
||||
i0 = InstanceDescriptor()
|
||||
i0.familyName = "MyVariableFontPrototype"
|
||||
i0.styleName = "Medium"
|
||||
i0.path = os.path.join(root, "instances","MyVariableFontPrototype-Medium.ufo")
|
||||
i0.location = dict(weight=500)
|
||||
i0.kerning = True
|
||||
i0.info = True
|
||||
doc.addInstance(i0)
|
||||
|
||||
- The ``path`` attribute needs to be the absolute (real or intended)
|
||||
path for the instance. When the document is saved this path will
|
||||
written as relative to the path of the document.
|
||||
- instance paths should be on the same level as the document, or in a
|
||||
level below.
|
||||
- Instances for MutatorMath will generate to UFO.
|
||||
- Instances for variable fonts become **named instances**.
|
||||
|
||||
Option: add more names
|
||||
----------------------
|
||||
|
||||
If you want you can add a PostScript font name, a stylemap familyName
|
||||
and a stylemap styleName.
|
||||
|
||||
.. code:: python
|
||||
|
||||
i0.postScriptFontName = "MyVariableFontPrototype-Medium"
|
||||
i0.styleMapFamilyName = "MyVarProtoMedium"
|
||||
i0.styleMapStyleName = "regular"
|
||||
|
||||
Option: add glyph specific masters
|
||||
----------------------------------
|
||||
|
||||
This bit is not supported by OpenType variable fonts, but it is needed
|
||||
for some designspaces intended for generating instances with
|
||||
MutatorMath. The code becomes a bit verbose, so you're invited to wrap
|
||||
this into something clever.
|
||||
|
||||
.. code:: python
|
||||
|
||||
# we're making a dict with all sorts of
|
||||
#(optional) settings for a glyph.
|
||||
#In this example: the dollar.
|
||||
glyphData = dict(name="dollar", unicodeValue=0x24)
|
||||
|
||||
# you can specify a different location for a glyph
|
||||
glyphData['instanceLocation'] = dict(weight=500)
|
||||
|
||||
# You can specify different masters
|
||||
# for this specific glyph.
|
||||
# You can also give those masters new
|
||||
# locations. It's a miniature designspace.
|
||||
# Remember the "name" attribute we assigned to the sources?
|
||||
glyphData['masters'] = [
|
||||
dict(font="master.thin",
|
||||
glyphName="dollar.nostroke",
|
||||
location=dict(weight=0)),
|
||||
dict(font="master.bold",
|
||||
glyphName="dollar.nostroke",
|
||||
location=dict(weight=1000)),
|
||||
]
|
||||
|
||||
# With all of that set up, store it in the instance.
|
||||
i4.glyphs['dollar'] = glyphData
|
||||
|
||||
******
|
||||
Saving
|
||||
******
|
||||
|
||||
.. code:: python
|
||||
|
||||
path = "myprototype.designspace"
|
||||
doc.write(path)
|
||||
|
||||
************************
|
||||
Reading old designspaces
|
||||
************************
|
||||
|
||||
Old designspace files might not contain ``axes`` definitions. This is
|
||||
how you reconstruct the axes from the extremes of the source locations
|
||||
|
||||
.. code:: python
|
||||
|
||||
doc.checkAxes()
|
||||
|
||||
This is how you check the default font.
|
||||
|
||||
.. code:: python
|
||||
|
||||
doc.checkDefault()
|
||||
|
||||
***********
|
||||
Generating?
|
||||
***********
|
||||
|
||||
You can generate the UFO's with MutatorMath:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from mutatorMath.ufo import build
|
||||
build("whatevs/myprototype.designspace")
|
||||
|
||||
- Assuming the outline data in the masters is compatible.
|
||||
|
||||
Or you can use the file in making a **variable font** with varlib.
|
||||
#######################
|
||||
Scripting a designspace
|
||||
#######################
|
||||
|
||||
It can be useful to build a designspace with a script rather than
|
||||
construct one with an interface like
|
||||
`Superpolator <http://superpolator.com>`__ or
|
||||
`DesignSpaceEditor <https://github.com/LettError/designSpaceRoboFontExtension>`__.
|
||||
|
||||
`fontTools.designspaceLib` offers a some tools for building designspaces in
|
||||
Python. This document shows an example.
|
||||
|
||||
********************************
|
||||
Filling-in a DesignSpaceDocument
|
||||
********************************
|
||||
|
||||
So, suppose you installed the `fontTools` package through your favorite
|
||||
``git`` client.
|
||||
|
||||
The ``DesignSpaceDocument`` object represents the document, whether it
|
||||
already exists or not. Make a new one:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from fontTools.designspaceLib import (DesignSpaceDocument, AxisDescriptor,
|
||||
SourceDescriptor, InstanceDescriptor)
|
||||
doc = DesignSpaceDocument()
|
||||
|
||||
We want to create definitions for axes, sources and instances. That
|
||||
means there are a lot of attributes to set. The **DesignSpaceDocument
|
||||
object** uses objects to describe the axes, sources and instances. These
|
||||
are relatively simple objects, think of these as collections of
|
||||
attributes.
|
||||
|
||||
- Attributes of the :ref:`source-descriptor-object`
|
||||
- Attributes of the :ref:`instance-descriptor-object`
|
||||
- Attributes of the :ref:`axis-descriptor-object`
|
||||
- Read about :ref:`subclassing-descriptors`
|
||||
|
||||
Make an axis object
|
||||
===================
|
||||
|
||||
Make a descriptor object and add it to the document.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1 = AxisDescriptor()
|
||||
a1.maximum = 1000
|
||||
a1.minimum = 0
|
||||
a1.default = 0
|
||||
a1.name = "weight"
|
||||
a1.tag = "wght"
|
||||
doc.addAxis(a1)
|
||||
|
||||
- You can add as many axes as you need. OpenType has a maximum of
|
||||
around 64K. DesignSpaceEditor has a maximum of 5.
|
||||
- The ``name`` attribute is the name you'll be using as the axis name
|
||||
in the locations.
|
||||
- The ``tag`` attribute is the one of the registered `OpenType
|
||||
Variation Axis
|
||||
Tags <https://www.microsoft.com/typography/otspec/fvar.htm#VAT>`__
|
||||
|
||||
Option: add label names
|
||||
-----------------------
|
||||
|
||||
The **labelnames** attribute is intended to store localisable, human
|
||||
readable names for this axis if this is not an axis that is registered
|
||||
by OpenType. Think "The label next to the slider". The attribute is a
|
||||
dictionary. The key is the `xml language
|
||||
tag <https://www.w3.org/International/articles/language-tags/>`__, the
|
||||
value is a utf-8 string with the name. Whether or not this attribute is
|
||||
used depends on the font building tool, the operating system and the
|
||||
authoring software. This, at least, is the place to record it.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1.labelNames['fa-IR'] = u"قطر"
|
||||
a1.labelNames['en'] = u"Wéíght"
|
||||
|
||||
Option: add a map
|
||||
-----------------
|
||||
|
||||
The **map** attribute is a list of (input, output) mapping values
|
||||
intended for `axis variations table of
|
||||
OpenType <https://www.microsoft.com/typography/otspec/avar.htm>`__.
|
||||
|
||||
.. code:: python
|
||||
|
||||
a1.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)]
|
||||
|
||||
Make a source object
|
||||
====================
|
||||
|
||||
A **source** is an object that points to a UFO file. It provides the
|
||||
outline geometry, kerning and font.info that we want to work with.
|
||||
|
||||
.. code:: python
|
||||
|
||||
s0 = SourceDescriptor()
|
||||
s0.path = "my/path/to/thin.ufo"
|
||||
s0.name = "master.thin"
|
||||
s0.location = dict(weight=0)
|
||||
doc.addSource(s0)
|
||||
|
||||
- You'll need to have at least 2 sources in your document, so go ahead
|
||||
and add another one.
|
||||
- The **location** attribute is a dictionary with the designspace
|
||||
location for this master.
|
||||
- The axis names in the location have to match one of the ``axis.name``
|
||||
values you defined before.
|
||||
- The **path** attribute is the absolute path to an existing UFO.
|
||||
- The **name** attribute is a unique name for this source used to keep
|
||||
track it.
|
||||
|
||||
So go ahead and add another master:
|
||||
|
||||
.. code:: python
|
||||
|
||||
s1 = SourceDescriptor()
|
||||
s1.path = "my/path/to/bold.ufo"
|
||||
s1.name = "master.bold"
|
||||
s1.location = dict(weight=1000)
|
||||
doc.addSource(s1)
|
||||
|
||||
Option: exclude glyphs
|
||||
----------------------
|
||||
|
||||
By default all glyphs in a source will be processed. If you want to
|
||||
exclude certain glyphs, add their names to the ``mutedGlyphNames`` list.
|
||||
|
||||
.. code:: python
|
||||
|
||||
s1.mutedGlyphNames = ["A.test", "A.old"]
|
||||
|
||||
Make an instance object
|
||||
=======================
|
||||
|
||||
An **instance** is description of a UFO that you want to generate with
|
||||
the designspace. For an instance you can define more things. If you want
|
||||
to generate UFO instances with MutatorMath then you can define different
|
||||
names and set flags for if you want to generate kerning and font info
|
||||
and so on. You can also set a path where to generate the instance.
|
||||
|
||||
.. code:: python
|
||||
|
||||
i0 = InstanceDescriptor()
|
||||
i0.familyName = "MyVariableFontPrototype"
|
||||
i0.styleName = "Medium"
|
||||
i0.path = os.path.join(root, "instances","MyVariableFontPrototype-Medium.ufo")
|
||||
i0.location = dict(weight=500)
|
||||
i0.kerning = True
|
||||
i0.info = True
|
||||
doc.addInstance(i0)
|
||||
|
||||
- The ``path`` attribute needs to be the absolute (real or intended)
|
||||
path for the instance. When the document is saved this path will
|
||||
written as relative to the path of the document.
|
||||
- instance paths should be on the same level as the document, or in a
|
||||
level below.
|
||||
- Instances for MutatorMath will generate to UFO.
|
||||
- Instances for variable fonts become **named instances**.
|
||||
|
||||
Option: add more names
|
||||
----------------------
|
||||
|
||||
If you want you can add a PostScript font name, a stylemap familyName
|
||||
and a stylemap styleName.
|
||||
|
||||
.. code:: python
|
||||
|
||||
i0.postScriptFontName = "MyVariableFontPrototype-Medium"
|
||||
i0.styleMapFamilyName = "MyVarProtoMedium"
|
||||
i0.styleMapStyleName = "regular"
|
||||
|
||||
Option: add glyph specific masters
|
||||
----------------------------------
|
||||
|
||||
This bit is not supported by OpenType variable fonts, but it is needed
|
||||
for some designspaces intended for generating instances with
|
||||
MutatorMath. The code becomes a bit verbose, so you're invited to wrap
|
||||
this into something clever.
|
||||
|
||||
.. code:: python
|
||||
|
||||
# we're making a dict with all sorts of
|
||||
#(optional) settings for a glyph.
|
||||
#In this example: the dollar.
|
||||
glyphData = dict(name="dollar", unicodeValue=0x24)
|
||||
|
||||
# you can specify a different location for a glyph
|
||||
glyphData['instanceLocation'] = dict(weight=500)
|
||||
|
||||
# You can specify different masters
|
||||
# for this specific glyph.
|
||||
# You can also give those masters new
|
||||
# locations. It's a miniature designspace.
|
||||
# Remember the "name" attribute we assigned to the sources?
|
||||
glyphData['masters'] = [
|
||||
dict(font="master.thin",
|
||||
glyphName="dollar.nostroke",
|
||||
location=dict(weight=0)),
|
||||
dict(font="master.bold",
|
||||
glyphName="dollar.nostroke",
|
||||
location=dict(weight=1000)),
|
||||
]
|
||||
|
||||
# With all of that set up, store it in the instance.
|
||||
i4.glyphs['dollar'] = glyphData
|
||||
|
||||
******
|
||||
Saving
|
||||
******
|
||||
|
||||
.. code:: python
|
||||
|
||||
path = "myprototype.designspace"
|
||||
doc.write(path)
|
||||
|
||||
************************
|
||||
Reading old designspaces
|
||||
************************
|
||||
|
||||
Old designspace files might not contain ``axes`` definitions. This is
|
||||
how you reconstruct the axes from the extremes of the source locations
|
||||
|
||||
.. code:: python
|
||||
|
||||
doc.checkAxes()
|
||||
|
||||
This is how you check the default font.
|
||||
|
||||
.. code:: python
|
||||
|
||||
doc.checkDefault()
|
||||
|
||||
***********
|
||||
Generating?
|
||||
***********
|
||||
|
||||
You can generate the UFO's with MutatorMath:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from mutatorMath.ufo import build
|
||||
build("whatevs/myprototype.designspace")
|
||||
|
||||
- Assuming the outline data in the masters is compatible.
|
||||
|
||||
Or you can use the file in making a **variable font** with varlib.
|
||||
|
Loading…
x
Reference in New Issue
Block a user