• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#######################################################
2designspaceLib: Read, write, and edit designspace files
3#######################################################
4
5Implements support for reading and manipulating ``designspace`` files.
6Allows the users to define axes, rules, sources, variable fonts and instances,
7and their STAT information.
8
9.. toctree::
10   :maxdepth: 1
11
12   python
13   xml
14   scripting
15
16
17Notes
18=====
19
20Paths and filenames
21-------------------
22
23A designspace file needs to store many references to UFO files.
24
25-  designspace files can be part of versioning systems and appear on
26   different computers. This means it is not possible to store absolute
27   paths.
28-  So, all paths are relative to the designspace document path.
29-  Using relative paths allows designspace files and UFO files to be
30   **near** each other, and that they can be **found** without enforcing
31   one particular structure.
32-  The **filename** attribute in the ``SourceDescriptor`` and
33   ``InstanceDescriptor`` classes stores the preferred relative path.
34-  The **path** attribute in these objects stores the absolute path. It
35   is calculated from the document path and the relative path in the
36   filename attribute when the object is created.
37-  Only the **filename** attribute is written to file.
38-  Both **filename** and **path** must use forward slashes (``/``) as
39   path separators, even on Windows.
40
41Right before we save we need to identify and respond to the following
42situations:
43
44In each descriptor, we have to do the right thing for the filename
45attribute. Before writing to file, the ``documentObject.updatePaths()``
46method prepares the paths as follows:
47
48**Case 1**
49
50::
51
52    descriptor.filename == None
53    descriptor.path == None
54
55**Action**
56
57-  write as is, descriptors will not have a filename attr. Useless, but
58   no reason to interfere.
59
60**Case 2**
61
62::
63
64    descriptor.filename == "../something"
65    descriptor.path == None
66
67**Action**
68
69-  write as is. The filename attr should not be touched.
70
71**Case 3**
72
73::
74
75    descriptor.filename == None
76    descriptor.path == "~/absolute/path/there"
77
78**Action**
79
80-  calculate the relative path for filename. We're not overwriting some
81   other value for filename, it should be fine.
82
83**Case 4**
84
85::
86
87    descriptor.filename == '../somewhere'
88    descriptor.path == "~/absolute/path/there"
89
90**Action**
91
92-  There is a conflict between the given filename, and the path. The
93   difference could have happened for any number of reasons. Assuming
94   the values were not in conflict when the object was created, either
95   could have changed. We can't guess.
96-  Assume the path attribute is more up to date. Calculate a new value
97   for filename based on the path and the document path.
98
99Recommendation for editors
100--------------------------
101
102-  If you want to explicitly set the **filename** attribute, leave the
103   path attribute empty.
104-  If you want to explicitly set the **path** attribute, leave the
105   filename attribute empty. It will be recalculated.
106-  Use ``documentObject.updateFilenameFromPath()`` to explicitly set the
107   **filename** attributes for all instance and source descriptors.
108
109
110Common Lib Key Registry
111=======================
112
113public.skipExportGlyphs
114-----------------------
115
116This lib key works the same as the UFO lib key with the same name. The
117difference is that applications using a Designspace as the corner stone of the
118font compilation process should use the lib key in that Designspace instead of
119any of the UFOs. If the lib key is empty or not present in the Designspace, all
120glyphs should be exported, regardless of what the same lib key in any of the
121UFOs says.
122
123
124Implementation and differences
125==============================
126
127The designspace format has gone through considerable development.
128
129 -  the format was originally written for MutatorMath.
130 -  the format is now also used in fontTools.varlib.
131 -  not all values are be required by all implementations.
132
133Varlib vs. MutatorMath
134----------------------
135
136There are some differences between the way MutatorMath and fontTools.varlib handle designspaces.
137
138 -  Varlib does not support anisotropic interpolations.
139 -  MutatorMath will extrapolate over the boundaries of
140    the axes. Varlib can not (at the moment).
141 -  Varlib requires much less data to define an instance than
142    MutatorMath.
143 -  The goals of Varlib and MutatorMath are different, so not all
144    attributes are always needed.
145
146
147Rules and generating static UFO instances
148-----------------------------------------
149
150When making instances as UFOs from a designspace with rules, it can
151be useful to evaluate the rules so that the characterset of the UFO
152reflects, as much as possible, the state of a variable font when seen
153at the same location. This can be done by some swapping and renaming of
154glyphs.
155
156While useful for proofing or development work, it should be noted that
157swapping and renaming leaves the UFOs with glyphnames that are no longer
158descriptive. For instance, after a swap ``dollar.bar`` could contain a shape
159without a bar. Also, when the swapped glyphs are part of other GSUB variations
160it can become complex very quickly. So proceed with caution.
161
162 -  Assuming ``rulesProcessingLast = True``:
163 -  We need to swap the glyphs so that the original shape is still available.
164    For instance, if a rule swaps ``a`` for ``a.alt``, a glyph
165    that references ``a`` in a component would then show the new ``a.alt``.
166 -  But that can lead to unexpected results, the two glyphs may have different
167    widths or height. So, glyphs that are not specifically referenced in a rule
168    **should not change appearance**. That means that the implementation that swaps
169    ``a`` and ``a.alt`` also swap all components that reference these
170    glyphs in order to preserve their appearance.
171 -  The swap function also needs to take care of swapping the names in
172    kerning data and any GPOS code.
173
174Version history
175===============
176
177Version 5.0
178-----------
179
180The format was extended to describe the entire design space of a reasonably
181regular font family in one file, with global data about the family to reduce
182repetition in sub-sections. "Reasonably regular" means that the sources and
183instances across the previously multiple Designspace files are positioned on a
184grid and derive their metadata (like style name) in a way that's compatible with
185the STAT model, based on their axis positions. Axis mappings must be the same
186across the entire space.
187
1881. Each axis can have labels attached to stops within the axis range, analogous to the
189   `OpenType STAT <https://docs.microsoft.com/en-us/typography/opentype/spec/stat>`_
190   table. Free-standing labels for locations are also allowed. The data is intended
191   to be compiled into a ``STAT`` table.
1922. The axes can be discrete, to say that they do not interpolate, like a distinctly
193   constructed upright and italic variant of a family.
1943. The data can be used to derive style and PostScript names for instances.
1954. A new ``variable-fonts`` element can subdivide the Designspace into multiple subsets that
196   mix and match the globally available axes. It is possible for these sub-spaces to have
197   a different default location from the global default location. It is required if the
198   Designspace contains a discrete axis and you want to produce a variable font.
199
200What is currently not supported is e.g.
201
2021. A setup where different sources sit at the same logical location in the design space,
203   think "MyFont Regular" and "MyFont SmallCaps Regular". (this situation could be
204   encoded by adding a "SmallCaps" discrete axis, if that makes sense).
2052. Anisotropic locations for axis labels.
206
207Older versions
208--------------
209
210-  In some implementations that preceed Variable Fonts, the `copyInfo`
211   flag in a source indicated the source was to be treated as the default.
212   This is no longer compatible with the assumption that the default font
213   is located on the default value of each axis.
214-  Older implementations did not require axis records to be present in
215   the designspace file. The axis extremes for instance were generated
216   from the locations used in the sources. This is no longer possible.
217
218