[designspaceLib] Update documentation and add version 5
This commit is contained in:
parent
a7974986c3
commit
5a842cc249
@ -1,6 +1,6 @@
|
||||
# fontTools Documentation
|
||||
|
||||
The fontTools project documentation updates continuously on Read the Docs as the project source changes.
|
||||
The fontTools project documentation updates continuously on Read the Docs as the project source changes.
|
||||
|
||||
The documentation is hosted at https://fonttools.readthedocs.io/.
|
||||
|
||||
@ -19,7 +19,7 @@ You must have a Python 3 interpreter and the `pip` Python package manager instal
|
||||
Pull the fontTools project source files, create a Python virtual environment, and then install fontTools and the documentation build dependencies by executing the following commands in the root of the fontTools source repository:
|
||||
|
||||
```
|
||||
$ pip install -e . [all]
|
||||
$ pip install -e .[all]
|
||||
$ pip install -r Doc/docs-requirements.txt
|
||||
```
|
||||
|
||||
@ -112,7 +112,7 @@ Build a local set of HTML documentation files with the instructions above and re
|
||||
|
||||
### Submit a Pull Request
|
||||
|
||||
Submit a Github pull request with your proposed improvements to the documentation.
|
||||
Submit a Github pull request with your proposed improvements to the documentation.
|
||||
|
||||
Thanks for your contribution!
|
||||
|
||||
|
@ -1,18 +1,217 @@
|
||||
##############
|
||||
designspaceLib
|
||||
##############
|
||||
#######################################################
|
||||
designspaceLib: Read, write, and edit designspace files
|
||||
#######################################################
|
||||
|
||||
MutatorMath started out with its own reader and writer for designspaces.
|
||||
Since then the use of designspace has broadened and it would be useful
|
||||
to have a reader and writer that are independent of a specific system.
|
||||
Implements support for reading and manipulating ``designspace`` files.
|
||||
Allows the users to define axes, rules, sources, variable fonts and instances,
|
||||
and their STAT information.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
readme
|
||||
python
|
||||
xml
|
||||
scripting
|
||||
|
||||
.. automodule:: fontTools.designspaceLib
|
||||
:inherited-members:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
Paths and filenames
|
||||
-------------------
|
||||
|
||||
A designspace file needs to store many references to UFO files.
|
||||
|
||||
- designspace files can be part of versioning systems and appear on
|
||||
different computers. This means it is not possible to store absolute
|
||||
paths.
|
||||
- So, all paths are relative to the designspace document path.
|
||||
- Using relative paths allows designspace files and UFO files to be
|
||||
**near** each other, and that they can be **found** without enforcing
|
||||
one particular structure.
|
||||
- The **filename** attribute in the ``SourceDescriptor`` and
|
||||
``InstanceDescriptor`` classes stores the preferred relative path.
|
||||
- The **path** attribute in these objects stores the absolute path. It
|
||||
is calculated from the document path and the relative path in the
|
||||
filename attribute when the object is created.
|
||||
- Only the **filename** attribute is written to file.
|
||||
- Both **filename** and **path** must use forward slashes (``/``) as
|
||||
path separators, even on Windows.
|
||||
|
||||
Right before we save we need to identify and respond to the following
|
||||
situations:
|
||||
|
||||
In each descriptor, we have to do the right thing for the filename
|
||||
attribute. Before writing to file, the ``documentObject.updatePaths()``
|
||||
method prepares the paths as follows:
|
||||
|
||||
**Case 1**
|
||||
|
||||
::
|
||||
|
||||
descriptor.filename == None
|
||||
descriptor.path == None
|
||||
|
||||
**Action**
|
||||
|
||||
- write as is, descriptors will not have a filename attr. Useless, but
|
||||
no reason to interfere.
|
||||
|
||||
**Case 2**
|
||||
|
||||
::
|
||||
|
||||
descriptor.filename == "../something"
|
||||
descriptor.path == None
|
||||
|
||||
**Action**
|
||||
|
||||
- write as is. The filename attr should not be touched.
|
||||
|
||||
**Case 3**
|
||||
|
||||
::
|
||||
|
||||
descriptor.filename == None
|
||||
descriptor.path == "~/absolute/path/there"
|
||||
|
||||
**Action**
|
||||
|
||||
- calculate the relative path for filename. We're not overwriting some
|
||||
other value for filename, it should be fine.
|
||||
|
||||
**Case 4**
|
||||
|
||||
::
|
||||
|
||||
descriptor.filename == '../somewhere'
|
||||
descriptor.path == "~/absolute/path/there"
|
||||
|
||||
**Action**
|
||||
|
||||
- There is a conflict between the given filename, and the path. The
|
||||
difference could have happened for any number of reasons. Assuming
|
||||
the values were not in conflict when the object was created, either
|
||||
could have changed. We can't guess.
|
||||
- Assume the path attribute is more up to date. Calculate a new value
|
||||
for filename based on the path and the document path.
|
||||
|
||||
Recommendation for editors
|
||||
--------------------------
|
||||
|
||||
- If you want to explicitly set the **filename** attribute, leave the
|
||||
path attribute empty.
|
||||
- If you want to explicitly set the **path** attribute, leave the
|
||||
filename attribute empty. It will be recalculated.
|
||||
- Use ``documentObject.updateFilenameFromPath()`` to explicitly set the
|
||||
**filename** attributes for all instance and source descriptors.
|
||||
|
||||
|
||||
Common Lib Key Registry
|
||||
=======================
|
||||
|
||||
public.skipExportGlyphs
|
||||
-----------------------
|
||||
|
||||
This lib key works the same as the UFO lib key with the same name. The
|
||||
difference is that applications using a Designspace as the corner stone of the
|
||||
font compilation process should use the lib key in that Designspace instead of
|
||||
any of the UFOs. If the lib key is empty or not present in the Designspace, all
|
||||
glyphs should be exported, regardless of what the same lib key in any of the
|
||||
UFOs says.
|
||||
|
||||
|
||||
Implementation and differences
|
||||
==============================
|
||||
|
||||
The designspace format has gone through considerable development.
|
||||
|
||||
- the format was originally written for MutatorMath.
|
||||
- the format is now also used in fontTools.varlib.
|
||||
- not all values are be required by all implementations.
|
||||
|
||||
Varlib vs. MutatorMath
|
||||
----------------------
|
||||
|
||||
There are some differences between the way MutatorMath and fontTools.varlib handle designspaces.
|
||||
|
||||
- Varlib does not support anisotropic interpolations.
|
||||
- MutatorMath will extrapolate over the boundaries of
|
||||
the axes. Varlib can not (at the moment).
|
||||
- Varlib requires much less data to define an instance than
|
||||
MutatorMath.
|
||||
- The goals of Varlib and MutatorMath are different, so not all
|
||||
attributes are always needed.
|
||||
|
||||
|
||||
Rules and generating static UFO instances
|
||||
-----------------------------------------
|
||||
|
||||
When making instances as UFOs from a designspace with rules, it can
|
||||
be useful to evaluate the rules so that the characterset of the UFO
|
||||
reflects, as much as possible, the state of a variable font when seen
|
||||
at the same location. This can be done by some swapping and renaming of
|
||||
glyphs.
|
||||
|
||||
While useful for proofing or development work, it should be noted that
|
||||
swapping and renaming leaves the UFOs with glyphnames that are no longer
|
||||
descriptive. For instance, after a swap ``dollar.bar`` could contain a shape
|
||||
without a bar. Also, when the swapped glyphs are part of other GSUB variations
|
||||
it can become complex very quickly. So proceed with caution.
|
||||
|
||||
- Assuming ``rulesProcessingLast = True``:
|
||||
- We need to swap the glyphs so that the original shape is still available.
|
||||
For instance, if a rule swaps ``a`` for ``a.alt``, a glyph
|
||||
that references ``a`` in a component would then show the new ``a.alt``.
|
||||
- But that can lead to unexpected results, the two glyphs may have different
|
||||
widths or height. So, glyphs that are not specifically referenced in a rule
|
||||
**should not change appearance**. That means that the implementation that swaps
|
||||
``a`` and ``a.alt`` also swap all components that reference these
|
||||
glyphs in order to preserve their appearance.
|
||||
- The swap function also needs to take care of swapping the names in
|
||||
kerning data and any GPOS code.
|
||||
|
||||
Version history
|
||||
===============
|
||||
|
||||
Version 5.0
|
||||
-----------
|
||||
|
||||
The format was extended to describe the entire design space of a reasonably
|
||||
regular font family in one file, with global data about the family to reduce
|
||||
repetition in sub-sections. "Reasonably regular" means that the sources and
|
||||
instances across the previously multiple Designspace files are positioned on a
|
||||
grid and derive their metadata (like style name) in a way that's compatible with
|
||||
the STAT model, based on their axis positions. Axis mappings must be the same
|
||||
across the entire space.
|
||||
|
||||
1. Each axis can have labels attached to stops within the axis range, analogous to the
|
||||
`OpenType STAT <https://docs.microsoft.com/en-us/typography/opentype/spec/stat>`_
|
||||
table. Free-standing labels for locations are also allowed. The data is intended
|
||||
to be compiled into a ``STAT`` table.
|
||||
2. The axes can be discrete, to say that they do not interpolate, like a distinctly
|
||||
constructed upright and italic variant of a family.
|
||||
3. The data can be used to derive style and PostScript names for instances.
|
||||
4. A new ``variable-fonts`` element can subdivide the Designspace into multiple subsets that
|
||||
mix and match the globally available axes. It is possible for these sub-spaces to have
|
||||
a different default location from the global default location. It is required if the
|
||||
Designspace contains a discrete axis and you want to produce a variable font.
|
||||
|
||||
What is currently not supported is e.g.
|
||||
|
||||
1. A setup where different sources sit at the same logical location in the design space,
|
||||
think "MyFont Regular" and "MyFont SmallCaps Regular". (this situation could be
|
||||
encoded by adding a "SmallCaps" discrete axis, if that makes sense).
|
||||
2. Anisotropic locations for axis labels.
|
||||
|
||||
Older versions
|
||||
--------------
|
||||
|
||||
- In some implementations that preceed Variable Fonts, the `copyInfo`
|
||||
flag in a source indicated the source was to be treated as the default.
|
||||
This is no longer compatible with the assumption that the default font
|
||||
is located on the default value of each axis.
|
||||
- Older implementations did not require axis records to be present in
|
||||
the designspace file. The axis extremes for instance were generated
|
||||
from the locations used in the sources. This is no longer possible.
|
||||
|
||||
|
199
Doc/source/designspaceLib/python.rst
Normal file
199
Doc/source/designspaceLib/python.rst
Normal file
@ -0,0 +1,199 @@
|
||||
################################
|
||||
1 DesignSpaceDocument Python API
|
||||
################################
|
||||
|
||||
An object to read, write and edit interpolation systems for typefaces.
|
||||
Define sources, axes, rules, variable fonts and instances.
|
||||
|
||||
Get an overview of the available classes in the Class Diagram below:
|
||||
|
||||
.. figure:: v5_class_diagram.png
|
||||
:width: 650px
|
||||
:alt: UML class diagram of designspaceLib
|
||||
|
||||
UML class diagram of designspaceLib. Click to enlarge.
|
||||
|
||||
.. contents:: Table of contents
|
||||
:local:
|
||||
|
||||
.. _designspacedocument-object:
|
||||
|
||||
===================
|
||||
DesignSpaceDocument
|
||||
===================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::DesignSpaceDocument
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
.. _axis-descriptor-object:
|
||||
|
||||
AxisDescriptor
|
||||
==============
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::AxisDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members: SimpleDescriptor
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
DiscreteAxisDescriptor
|
||||
======================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::DiscreteAxisDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members: SimpleDescriptor
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
AxisLabelDescriptor
|
||||
-------------------
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::AxisLabelDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
LocationLabelDescriptor
|
||||
=======================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::LocationLabelDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
RuleDescriptor
|
||||
==============
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::RuleDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
Evaluating rules
|
||||
----------------
|
||||
|
||||
.. autofunction:: fontTools.designspaceLib::evaluateRule
|
||||
.. autofunction:: fontTools.designspaceLib::evaluateConditions
|
||||
.. autofunction:: fontTools.designspaceLib::processRules
|
||||
|
||||
|
||||
.. _source-descriptor-object:
|
||||
|
||||
SourceDescriptor
|
||||
================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::SourceDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
VariableFontDescriptor
|
||||
======================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::VariableFontDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
RangeAxisSubsetDescriptor
|
||||
-------------------------
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::RangeAxisSubsetDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
ValueAxisSubsetDescriptor
|
||||
-------------------------
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::ValueAxisSubsetDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
.. _instance-descriptor-object:
|
||||
|
||||
InstanceDescriptor
|
||||
==================
|
||||
|
||||
.. autoclass:: fontTools.designspaceLib::InstanceDescriptor
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
.. _subclassing-descriptors:
|
||||
|
||||
=======================
|
||||
Subclassing descriptors
|
||||
=======================
|
||||
|
||||
The DesignSpaceDocument can take subclassed Reader and Writer objects.
|
||||
This allows you to work with your own descriptors. You could subclass
|
||||
the descriptors. But as long as they have the basic attributes the
|
||||
descriptor does not need to be a subclass.
|
||||
|
||||
.. code:: python
|
||||
|
||||
class MyDocReader(BaseDocReader):
|
||||
axisDescriptorClass = MyAxisDescriptor
|
||||
discreteAxisDescriptorClass = MyDiscreteAxisDescriptor
|
||||
axisLabelDescriptorClass = MyAxisLabelDescriptor
|
||||
locationLabelDescriptorClass = MyLocationLabelDescriptor
|
||||
ruleDescriptorClass = MyRuleDescriptor
|
||||
sourceDescriptorClass = MySourceDescriptor
|
||||
variableFontsDescriptorClass = MyVariableFontDescriptor
|
||||
valueAxisSubsetDescriptorClass = MyValueAxisSubsetDescriptor
|
||||
rangeAxisSubsetDescriptorClass = MyRangeAxisSubsetDescriptor
|
||||
instanceDescriptorClass = MyInstanceDescriptor
|
||||
|
||||
class MyDocWriter(BaseDocWriter):
|
||||
axisDescriptorClass = MyAxisDescriptor
|
||||
discreteAxisDescriptorClass = MyDiscreteAxisDescriptor
|
||||
axisLabelDescriptorClass = MyAxisLabelDescriptor
|
||||
locationLabelDescriptorClass = MyLocationLabelDescriptor
|
||||
ruleDescriptorClass = MyRuleDescriptor
|
||||
sourceDescriptorClass = MySourceDescriptor
|
||||
variableFontsDescriptorClass = MyVariableFontDescriptor
|
||||
valueAxisSubsetDescriptorClass = MyValueAxisSubsetDescriptor
|
||||
rangeAxisSubsetDescriptorClass = MyRangeAxisSubsetDescriptor
|
||||
instanceDescriptorClass = MyInstanceDescriptor
|
||||
|
||||
myDoc = DesignSpaceDocument(MyDocReader, MyDocWriter)
|
||||
|
||||
|
||||
==============
|
||||
Helper modules
|
||||
==============
|
||||
|
||||
fontTools.designspaceLib.split
|
||||
==============================
|
||||
|
||||
See :ref:`Scripting > Working with DesignSpace version 5 <working_with_v5>`
|
||||
for more information.
|
||||
|
||||
.. automodule:: fontTools.designspaceLib.split
|
||||
|
||||
|
||||
fontTools.designspaceLib.stat
|
||||
=============================
|
||||
|
||||
.. automodule:: fontTools.designspaceLib.stat
|
||||
|
||||
|
||||
fontTools.designspaceLib.statNames
|
||||
==================================
|
||||
|
||||
.. automodule:: fontTools.designspaceLib.statNames
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
#######################
|
||||
Scripting a designspace
|
||||
#######################
|
||||
#########################
|
||||
3 Scripting a designspace
|
||||
#########################
|
||||
|
||||
It can be useful to build a designspace with a script rather than
|
||||
construct one with an interface like
|
||||
@ -60,7 +60,7 @@ Make a descriptor object and add it to the document.
|
||||
Variation Axis
|
||||
Tags <https://www.microsoft.com/typography/otspec/fvar.htm#VAT>`__
|
||||
- The default master is expected at the intersection of all
|
||||
default values of all axes.
|
||||
default values of all axes.
|
||||
|
||||
Option: add label names
|
||||
-----------------------
|
||||
@ -88,6 +88,7 @@ OpenType <https://www.microsoft.com/typography/otspec/avar.htm>`__.
|
||||
|
||||
.. code:: python
|
||||
|
||||
# (user space, design space), (user space, design space)...
|
||||
a1.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)]
|
||||
|
||||
Make a source object
|
||||
@ -124,7 +125,7 @@ So go ahead and add another master:
|
||||
s1.name = "master.bold"
|
||||
s1.location = dict(weight=1000)
|
||||
doc.addSource(s1)
|
||||
|
||||
|
||||
|
||||
Option: exclude glyphs
|
||||
----------------------
|
||||
@ -241,7 +242,7 @@ This is how you check the default font.
|
||||
Generating?
|
||||
***********
|
||||
|
||||
You can generate the UFO's with MutatorMath:
|
||||
You can generate the UFOs with MutatorMath:
|
||||
|
||||
.. code:: python
|
||||
|
||||
@ -251,3 +252,39 @@ You can generate the UFO's with MutatorMath:
|
||||
- Assuming the outline data in the masters is compatible.
|
||||
|
||||
Or you can use the file in making a **variable font** with varlib.
|
||||
|
||||
|
||||
.. _working_with_v5:
|
||||
|
||||
**********************************
|
||||
Working with DesignSpace version 5
|
||||
**********************************
|
||||
|
||||
The new version 5 allows "discrete" axes, which do not interpolate across their
|
||||
values. This is useful to store in one place family-wide data such as the STAT
|
||||
information, however it prevents the usual things done on designspaces that
|
||||
interpolate everywhere:
|
||||
|
||||
- checking that all sources are compatible for interpolation
|
||||
- building variable fonts
|
||||
|
||||
In order to allow the above in tools that want to handle designspace v5,
|
||||
the :mod:`fontTools.designspaceLib.split` module provides two methods to
|
||||
split a designspace into interpolable sub-spaces,
|
||||
:func:`splitInterpolable() <fontTools.designspaceLib.split.splitInterpolable>`
|
||||
and then
|
||||
:func:`splitVariableFonts() <fontTools.designspaceLib.split.splitVariableFonts>`.
|
||||
|
||||
|
||||
.. figure:: v5_split_downconvert.png
|
||||
:width: 680px
|
||||
:alt: Example process diagram to check and build DesignSpace 5
|
||||
|
||||
Example process process to check and build Designspace 5.
|
||||
|
||||
|
||||
Also, for older tools that don't know about the other version 5 additions such
|
||||
as the STAT data fields, the function
|
||||
:func:`convert5to4() <fontTools.designspaceLib.split.convert5to4>` allows to
|
||||
strip new information from a designspace version 5 to downgrade it to a
|
||||
collection of version 4 documents, one per variable font.
|
||||
|
BIN
Doc/source/designspaceLib/v5_class_diagram.png
Normal file
BIN
Doc/source/designspaceLib/v5_class_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 267 KiB |
292
Doc/source/designspaceLib/v5_class_diagram.puml
Normal file
292
Doc/source/designspaceLib/v5_class_diagram.puml
Normal file
@ -0,0 +1,292 @@
|
||||
@startuml v5_class_diagram
|
||||
|
||||
title
|
||||
Designspace v5 Class Diagram
|
||||
|
||||
<size:12>Note: the ""Descriptor"" suffix is omitted from most classes
|
||||
end title
|
||||
|
||||
' left to right direction
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<New>> PaleGreen
|
||||
}
|
||||
|
||||
class DesignSpaceDocument {
|
||||
+ formatVersion: str = None
|
||||
+ <color:green><b><<New>> elidedFallbackName: str = None
|
||||
+ rulesProcessingLast: bool = False
|
||||
+ lib: Dict = {}
|
||||
}
|
||||
|
||||
note left of DesignSpaceDocument::elidedFallbackName
|
||||
STAT Style Attributes Header field ""elidedFallbackNameID""
|
||||
end note
|
||||
|
||||
abstract class AbstractAxis {
|
||||
+ tag: str
|
||||
+ name: str
|
||||
+ labelNames: Dict[str, str]
|
||||
+ hidden: bool
|
||||
+ map: List[Tuple[float, float]]
|
||||
+ <color:green><b><<New>> axisOrdering: int
|
||||
}
|
||||
DesignSpaceDocument *-- "*" AbstractAxis: axes >
|
||||
note right of AbstractAxis::axisOrdering
|
||||
STAT Axis Record field
|
||||
end note
|
||||
|
||||
class Axis {
|
||||
+ minimum: float
|
||||
+ maximum: float
|
||||
+ default: float
|
||||
}
|
||||
AbstractAxis <|--- Axis
|
||||
note bottom of Axis
|
||||
This is the usual
|
||||
Axis, with a range
|
||||
of values.
|
||||
end note
|
||||
|
||||
class DiscreteAxis <<New>> {
|
||||
+ values: List[float]
|
||||
+ default: float
|
||||
}
|
||||
AbstractAxis <|--- DiscreteAxis
|
||||
note bottom of DiscreteAxis
|
||||
A discrete axis is not
|
||||
interpolable, e.g.
|
||||
Uprights vs Italics, and
|
||||
so has "discrete" stops
|
||||
instead of a continuous
|
||||
range of values.
|
||||
end note
|
||||
|
||||
Axis .[hidden] DiscreteAxis
|
||||
|
||||
class AxisLabel <<New>> {
|
||||
+ userMinimum: Optional[float]
|
||||
+ userValue: float
|
||||
+ userMaximum: Optional[float]
|
||||
+ name: str
|
||||
+ elidable: bool
|
||||
+ olderSibling: bool
|
||||
+ linkedUserValue: Optional[float]
|
||||
+ labelNames: Dict[str, str]
|
||||
|
||||
+ getFormat(): 1 | 2 | 3
|
||||
}
|
||||
note right of AxisLabel
|
||||
Label for a
|
||||
stop on an Axis
|
||||
(STAT format
|
||||
1,2,3)
|
||||
end note
|
||||
AbstractAxis *-- "*" AxisLabel: <<New>> \n axisLabels >
|
||||
|
||||
class LocationLabel <<New>> {
|
||||
+ name: str
|
||||
+ location: Dict[str, float]
|
||||
+ elidable: bool
|
||||
+ olderSibling: bool
|
||||
+ labelNames: Dict[str, str]
|
||||
}
|
||||
note right of LocationLabel
|
||||
Label for a
|
||||
freestanding
|
||||
location
|
||||
(STAT format 4)
|
||||
end note
|
||||
DesignSpaceDocument *--- "*" LocationLabel: <<New>> \n locationLabels >
|
||||
|
||||
class Rule {
|
||||
+ name: str
|
||||
+ conditionSets: List[ConditionSet]
|
||||
+ subs: Dict[str, str]
|
||||
}
|
||||
DesignSpaceDocument *- "*" Rule: rules >
|
||||
|
||||
class Source {
|
||||
+ name: Optional[str]
|
||||
+ filename: str
|
||||
+ path: str
|
||||
+ layerName: Optional[str]
|
||||
+ <color:brown><s><<Deprecated>> location: Location
|
||||
+ <color:green><b><<New>> designLocation: AnisotropicLocation
|
||||
....
|
||||
+ font: Optional[Font]
|
||||
....
|
||||
+ familyName: Optional[str]
|
||||
+ styleName: Optional[str]
|
||||
+ <color:green><b><<New>> localisedFamilyName: Dict
|
||||
....
|
||||
+ <color:brown><s><<Deprecated>> copyLib: bool
|
||||
+ <color:brown><s><<Deprecated>> copyInfo: bool
|
||||
+ <color:brown><s><<Deprecated>> copyGroups: bool
|
||||
+ <color:brown><s><<Deprecated>> copyFeatures: bool
|
||||
....
|
||||
+ muteKerning: bool
|
||||
+ muteInfo: bool
|
||||
+ mutedGlyphNames: List[str]
|
||||
----
|
||||
+ <color:green><b><<New>> getFullDesignLocation(doc)
|
||||
}
|
||||
DesignSpaceDocument *-- "*" Source: sources >
|
||||
note right of Source::localisedFamilyName
|
||||
New field to allow generation
|
||||
of localised instance names using
|
||||
STAT information.
|
||||
end note
|
||||
note right of Source::copyGroups
|
||||
These fields are already not meaningful
|
||||
anymore in version 4 (the default source
|
||||
will be used as "neutral" for groups, info
|
||||
and features. ''copyLib'' can be emulated
|
||||
by putting content in the designspace's lib.
|
||||
end note
|
||||
|
||||
note as NLocSource
|
||||
The location of
|
||||
sources can still only
|
||||
be defined in design
|
||||
coordinates, and now
|
||||
also by relying on
|
||||
axis defaults.
|
||||
|
||||
To build the final,
|
||||
"full" location, a
|
||||
helper method is
|
||||
provided, that uses
|
||||
axis defaults and
|
||||
axis mappings to
|
||||
fill in the blanks.
|
||||
end note
|
||||
NLocSource . Source::designLocation
|
||||
NLocSource . Source::getFullDesignLocation
|
||||
|
||||
class VariableFont <<New>> {
|
||||
+ filename: str
|
||||
+ lib: Dict
|
||||
}
|
||||
DesignSpaceDocument *--- "*" VariableFont: <<New>> \n variableFonts >
|
||||
note right of VariableFont
|
||||
A variable font is a
|
||||
subset of the designspace
|
||||
where everything interpolates
|
||||
(and so can be compiled into
|
||||
an OpenType variable font).
|
||||
end note
|
||||
|
||||
abstract class AbstractAxisSubset <<New>> {
|
||||
+ name: str
|
||||
}
|
||||
VariableFont *-- "*" AbstractAxisSubset: <<New>> \n axisSubsets >
|
||||
|
||||
note right of AbstractAxisSubset
|
||||
An axis subset selects a range
|
||||
or a spot on each the available
|
||||
axes from the whole designspace.
|
||||
|
||||
By default, only the default value
|
||||
of each axis is used to define the
|
||||
variable font.
|
||||
|
||||
Continuous axes can be specified
|
||||
to include their full range instead;
|
||||
or a subset of the range.
|
||||
|
||||
Discrete axes can be specified
|
||||
to include a different spot than the
|
||||
default.
|
||||
end note
|
||||
|
||||
class RangeAxisSubset <<New>> {
|
||||
+ userMinimum: float
|
||||
+ userDefault: float
|
||||
+ userMaximum: float
|
||||
}
|
||||
AbstractAxisSubset <|-- RangeAxisSubset
|
||||
|
||||
class ValueAxisSubset <<New>> {
|
||||
+ userValue: float
|
||||
}
|
||||
AbstractAxisSubset <|-- ValueAxisSubset
|
||||
|
||||
class Instance {
|
||||
+ filename: str
|
||||
+ path: str
|
||||
+ <color:brown><s><<Deprecated>> location: Location
|
||||
+ <color:green><b><<New>> locationLabel: str
|
||||
+ <color:green><b><<New>> designLocation: AnisotropicLocation
|
||||
+ <color:green><b><<New>> userLocation: SimpleLocation
|
||||
....
|
||||
+ font: Optional[Font]
|
||||
....
|
||||
+ <color:orange><b><<Changed>> name: Optional[str]
|
||||
+ <color:orange><b><<Changed>> familyName: Optional[str]
|
||||
+ <color:orange><b><<Changed>> styleName: Optional[str]
|
||||
+ <color:orange><b><<Changed>> postScriptFontName: Optional[str]
|
||||
+ <color:orange><b><<Changed>> styleMapFamilyName: Optional[str]
|
||||
+ <color:orange><b><<Changed>> styleMapStyleName: Optional[str]
|
||||
+ localisedFamilyName: Dict
|
||||
+ localisedStyleName: Dict
|
||||
+ localisedStyleMapFamilyName: Dict
|
||||
+ localisedStyleMapStyleName: Dict
|
||||
....
|
||||
+ <color:brown><s><<Deprecated>> glyphs: Dict
|
||||
+ <color:brown><s><<Deprecated>> kerning: bool
|
||||
+ <color:brown><s><<Deprecated>> info: bool
|
||||
....
|
||||
+ lib: Dict
|
||||
----
|
||||
+ <color:green><b><<New>> clearLocation()
|
||||
+ <color:green><b><<New>> getLocationLabelDescriptor(doc)
|
||||
+ <color:green><b><<New>> getFullDesignLocation(doc)
|
||||
+ <color:green><b><<New>> getFullUserLocation(doc)
|
||||
}
|
||||
DesignSpaceDocument *-- "*" Instance: instances >
|
||||
note right of Instance::locationLabel
|
||||
The location can now alternatively
|
||||
be a string = name of a LocationLabel
|
||||
(STAT format 4). The instance then
|
||||
adopts the location of that label.
|
||||
See the Decovar example file.
|
||||
end note
|
||||
note right of Instance::styleMapStyleName
|
||||
All the name field are now optional.
|
||||
Their default values will be computed
|
||||
using the provided STAT table data
|
||||
and the STAT rules from the spec.
|
||||
For styleMap{Family,Style}Name, they
|
||||
would be computed using the STAT
|
||||
""linkedUserValue"" fields.
|
||||
end note
|
||||
note right of Instance::glyphs
|
||||
This attribute has been replaced by rules
|
||||
end note
|
||||
note right of Instance::kerning
|
||||
All instances get kerning and info
|
||||
nowadays.
|
||||
end note
|
||||
|
||||
note as NLocInstance
|
||||
The location of instances
|
||||
can now be defined using
|
||||
either:
|
||||
- a STAT LocationLabel
|
||||
- design coordinates
|
||||
- user coordinates.
|
||||
- relying on axis defaults
|
||||
|
||||
To build the final, "full"
|
||||
location, a few helper
|
||||
methods are provided,
|
||||
that aggregate data from
|
||||
these sources and apply
|
||||
the axis mappings.
|
||||
end note
|
||||
NLocInstance . Instance::designLocation
|
||||
NLocInstance . Instance::getFullDesignLocation
|
||||
|
||||
@enduml
|
||||
|
BIN
Doc/source/designspaceLib/v5_split_downconvert.png
Normal file
BIN
Doc/source/designspaceLib/v5_split_downconvert.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
147
Doc/source/designspaceLib/v5_split_downconvert.puml
Normal file
147
Doc/source/designspaceLib/v5_split_downconvert.puml
Normal file
@ -0,0 +1,147 @@
|
||||
@startuml v5_split_downconvert
|
||||
|
||||
title
|
||||
How to split and down-convert a DesignSpace version 5
|
||||
<size:14>so that existing tools can work with it
|
||||
end title
|
||||
|
||||
|
||||
start
|
||||
|
||||
#lightgrey:DesignSpace 5.0
|
||||
- with STAT data
|
||||
- optional instance names
|
||||
- with discrete axes
|
||||
- with multiple VFs]
|
||||
|
||||
note left
|
||||
- STAT data means that compilers will need
|
||||
to write that data to the ouput TTFs
|
||||
- optional instance names means that
|
||||
compilers will need to generate any missing
|
||||
names using the STAT data
|
||||
- discrete axes mean that not all sources
|
||||
are compatible for interpolation
|
||||
- multiple VFs means that compilers will
|
||||
need to output several TTFs for one DS
|
||||
end note
|
||||
|
||||
split
|
||||
split again
|
||||
|
||||
:""splitInterpolating()"";
|
||||
|
||||
note left
|
||||
- Create one DS document per interpolating
|
||||
sub-space, for example: with a discrete
|
||||
axis for Upright vs Italics, create 2
|
||||
DesignSpaces, one for the Uprights, and
|
||||
one for the Italics.
|
||||
- Expand all missing instance names using
|
||||
the STAT data.
|
||||
- Drop all the STAT data because as we start
|
||||
taking out discrete axes, the sub-documents
|
||||
lose STAT data anyway (only the full
|
||||
document at the start of the process should
|
||||
be used to generate the STAT table)
|
||||
end note
|
||||
|
||||
split
|
||||
|
||||
#lightgrey:DesignSpace 5.0
|
||||
- (no STAT data)
|
||||
- (explicit instance names)
|
||||
- (at discrete location #1)
|
||||
- with multiple VFs]
|
||||
|
||||
note left
|
||||
All sources in this sub-space are
|
||||
(supposed to be) compatible for
|
||||
interpolation
|
||||
end note
|
||||
|
||||
split again
|
||||
|
||||
#lightgrey:DesignSpace 5.0
|
||||
- (no STAT data)
|
||||
- (explicit instance names)
|
||||
- (at discrete location #2)
|
||||
- with multiple VFs]
|
||||
detach
|
||||
|
||||
split again
|
||||
|
||||
#lightgrey:etc
|
||||
...]
|
||||
detach
|
||||
|
||||
end split
|
||||
|
||||
:check compatibility;
|
||||
:build compatible master TTFs with cu2qu;
|
||||
|
||||
:""splitVariableFonts()"";
|
||||
|
||||
note left
|
||||
Create one DS document per variable font,
|
||||
for example: the above document may
|
||||
describe a weight and width space, out of
|
||||
which we'll build 3 variable fonts:
|
||||
full weight + width, weight only, width only.
|
||||
end note
|
||||
|
||||
split
|
||||
|
||||
#lightgrey:DesignSpace 5.0
|
||||
- (no STAT data)
|
||||
- (explicit instance names)
|
||||
- (at discrete location #1)
|
||||
- (describing just VF #1)]
|
||||
|
||||
note left
|
||||
This document looks very much
|
||||
like version 4.1, you can just
|
||||
change the version number at
|
||||
the top and feed it to a tool
|
||||
that doesn't know about v5;
|
||||
see ""convert5to4()"".
|
||||
end note
|
||||
|
||||
split again
|
||||
|
||||
#lightgrey:DesignSpace 5.0
|
||||
- (no STAT data)
|
||||
- (explicit instance names)
|
||||
- (at discrete location #1)
|
||||
- (describing just VF #2)]
|
||||
detach
|
||||
|
||||
split again
|
||||
|
||||
#lightgrey:etc
|
||||
...]
|
||||
detach
|
||||
|
||||
end split
|
||||
|
||||
:""varLib.build()"";
|
||||
|
||||
#lightgrey:Variable font TTF
|
||||
No STAT data]
|
||||
|
||||
end split
|
||||
|
||||
:""buildVFStatTable()"";
|
||||
|
||||
note left
|
||||
Apply STAT data using the full document
|
||||
from the start of the process + filtering
|
||||
entries based on this VF's location
|
||||
end note
|
||||
|
||||
#lightgrey:Variable font TTF
|
||||
With STAT data]
|
||||
|
||||
end
|
||||
|
||||
@enduml
|
BIN
Doc/source/designspaceLib/v5_variable_fonts_vs_instances.png
Normal file
BIN
Doc/source/designspaceLib/v5_variable_fonts_vs_instances.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 141 KiB |
1014
Doc/source/designspaceLib/xml.rst
Normal file
1014
Doc/source/designspaceLib/xml.rst
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user