aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/designspaceLib/types.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/designspaceLib/types.py')
-rw-r--r--Lib/fontTools/designspaceLib/types.py29
1 files changed, 27 insertions, 2 deletions
diff --git a/Lib/fontTools/designspaceLib/types.py b/Lib/fontTools/designspaceLib/types.py
index 8afea96c..80ba9d6d 100644
--- a/Lib/fontTools/designspaceLib/types.py
+++ b/Lib/fontTools/designspaceLib/types.py
@@ -1,12 +1,15 @@
from __future__ import annotations
from dataclasses import dataclass
-from typing import Dict, List, Optional, Union
+from typing import Dict, List, Optional, Union, cast
from fontTools.designspaceLib import (
+ AxisDescriptor,
DesignSpaceDocument,
+ DesignSpaceDocumentError,
RangeAxisSubsetDescriptor,
SimpleLocationDict,
+ ValueAxisSubsetDescriptor,
VariableFontDescriptor,
)
@@ -89,6 +92,10 @@ def userRegionToDesignRegion(doc: DesignSpaceDocument, userRegion: Region) -> Re
designRegion = {}
for name, value in userRegion.items():
axis = doc.getAxis(name)
+ if axis is None:
+ raise DesignSpaceDocumentError(
+ f"Cannot find axis named '{name}' for region."
+ )
if isinstance(value, (float, int)):
designRegion[name] = axis.map_forward(value)
else:
@@ -107,16 +114,34 @@ def getVFUserRegion(doc: DesignSpaceDocument, vf: VariableFontDescriptor) -> Reg
# - it's a single location = use it to know which rules should apply in the VF
for axisSubset in vf.axisSubsets:
axis = doc.getAxis(axisSubset.name)
- if isinstance(axisSubset, RangeAxisSubsetDescriptor):
+ if axis is None:
+ raise DesignSpaceDocumentError(
+ f"Cannot find axis named '{axisSubset.name}' for variable font '{vf.name}'."
+ )
+ if hasattr(axisSubset, "userMinimum"):
+ # Mypy doesn't support narrowing union types via hasattr()
+ # TODO(Python 3.10): use TypeGuard
+ # https://mypy.readthedocs.io/en/stable/type_narrowing.html
+ axisSubset = cast(RangeAxisSubsetDescriptor, axisSubset)
+ if not hasattr(axis, "minimum"):
+ raise DesignSpaceDocumentError(
+ f"Cannot select a range over '{axis.name}' for variable font '{vf.name}' "
+ "because it's a discrete axis, use only 'userValue' instead."
+ )
+ axis = cast(AxisDescriptor, axis)
vfUserRegion[axis.name] = Range(
max(axisSubset.userMinimum, axis.minimum),
min(axisSubset.userMaximum, axis.maximum),
axisSubset.userDefault or axis.default,
)
else:
+ axisSubset = cast(ValueAxisSubsetDescriptor, axisSubset)
vfUserRegion[axis.name] = axisSubset.userValue
# Any axis not mentioned explicitly has a single location = default value
for axis in doc.axes:
if axis.name not in vfUserRegion:
+ assert isinstance(
+ axis.default, (int, float)
+ ), f"Axis '{axis.name}' has no valid default value."
vfUserRegion[axis.name] = axis.default
return vfUserRegion