[designspaceLib] Switch doc files for designspaceLib from CRLF to LF

This commit is contained in:
Jany Belluz 2018-02-14 11:22:55 +00:00
parent 483e1489b4
commit ede5de6fb0
2 changed files with 1264 additions and 1264 deletions

File diff suppressed because it is too large Load Diff

View File

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