Skip to content
1 change: 0 additions & 1 deletion Lib/fontParts/base/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from fontParts.base import normalizers
from fontParts.base.annotations import (
PairType,
CollectionType,
PairCollectionType,
SextupleCollectionType,
IntFloatType,
Expand Down
10 changes: 5 additions & 5 deletions Lib/fontParts/base/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ def copyData(self, source: BaseFont) -> None:
else:
layer = self.newLayer(layerName)
layer.copyData(source.getLayer(layerName))
for guideline in self.guidelines:
self.appendGuideline(guideline)
for guideline in source.guidelines:
self.appendGuideline(guideline=guideline)
super(BaseFont, self).copyData(source)

# ---------------
Expand Down Expand Up @@ -293,7 +293,7 @@ def _save(
self,
path: Optional[str],
showProgress: bool,
formatVersion: Optional[float],
formatVersion: Optional[int],
fileStructure: Optional[str],
**kwargs: Any,
) -> None:
Expand Down Expand Up @@ -1843,11 +1843,11 @@ def appendGuideline(

def _appendGuideline( # type: ignore[return]
self,
position: Optional[PairCollectionType[IntFloatType]],
position: PairCollectionType[IntFloatType],
angle: Optional[float],
name: Optional[str],
color: Optional[QuadrupleCollectionType[IntFloatType]],
**kwargs,
**kwargs: Any,
) -> BaseGuideline:
r"""Append a new guideline to the native font.

Expand Down
7 changes: 4 additions & 3 deletions Lib/fontParts/base/glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ def _set_base_unicodes(self, value: CollectionType[int]) -> None:
value = normalizers.normalizeGlyphUnicodes(value)
self._set_unicodes(value)

def _get_unicodes(self) -> Tuple[int, ...]: # type: ignore[return]
def _get_unicodes(self) -> CollectionType[int]: # type: ignore[return]
"""Get the Unicode values assigned to the glyph.

This is the environment implementation of
Expand Down Expand Up @@ -3232,10 +3232,11 @@ def _get_base_image(self) -> BaseImage:
image.glyph = self
return image

def _get_image(self) -> BaseImage: # type: ignore[return]
def _get_image(self) -> Optional[BaseImage]: # type: ignore[return]
"""Get the image for the native glyph.

:return: The :class:`BaseImage` subclass instance belonging to the glyph.
:return: The :class:`BaseImage` subclass instance belonging to the glyph,
or :obj:`None` if the glyph has no image.
:raises NotImplementedError: If the method has not been overridden by a
subclass.

Expand Down
6 changes: 3 additions & 3 deletions Lib/fontParts/base/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

if TYPE_CHECKING:
from fontParts.base.font import BaseFont
from fontparts.base import BaseItems
from fontparts.base import BaseKeys
from fontparts.base import BaseValues
from fontParts.base.base import BaseKeys
from fontParts.base.base import BaseItems
from fontParts.base.base import BaseValues

ValueType = Tuple[str, ...]
GroupsDict = Dict[str, ValueType]
Expand Down
4 changes: 2 additions & 2 deletions Lib/fontParts/base/guideline.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def _set_name(self, value: Optional[str]) -> None:
""",
)

def _get_base_color(self) -> Optional[Color]:
def _get_base_color(self) -> Optional[QuadrupleType[float]]:
value = self._get_color()
if value is not None:
value = Color(value)
Expand All @@ -548,7 +548,7 @@ def _set_base_color(
value = normalizers.normalizeColor(value)
self._set_color(value)

def _get_color(self) -> Optional[QuadrupleCollectionType[IntFloatType]]:
def _get_color(self) -> Optional[QuadrupleType[float]]:
"""Get the native guideline's color.

This is the environment implementation of the :attr:`BaseGuideline.color`
Expand Down
8 changes: 5 additions & 3 deletions Lib/fontParts/base/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,19 +804,21 @@ def _set_name(self, value: str, **kwargs: Any) -> None:
""",
)

def _get_base_color(self) -> QuadrupleCollectionType[IntFloatType]:
def _get_base_color(self) -> Optional[QuadrupleCollectionType[IntFloatType]]:
value = self._get_color()
if value is not None:
value = normalizers.normalizeColor(value)
value = Color(value)
return value

def _set_base_color(self, value: QuadrupleCollectionType[IntFloatType]) -> None:
def _set_base_color(
self, value: Optional[QuadrupleCollectionType[IntFloatType]]
) -> None:
if value is not None:
value = normalizers.normalizeColor(value)
self._set_color(value)

def _get_color(self) -> QuadrupleCollectionType[IntFloatType]: # type: ignore[return]
def _get_color(self) -> Optional[QuadrupleCollectionType[IntFloatType]]: # type: ignore[return]
"""Get the color of the layer.

This is the environment implementation of
Expand Down
8 changes: 4 additions & 4 deletions Lib/fontParts/base/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
if TYPE_CHECKING:
from fontParts.base.glyph import BaseGlyph
from fontParts.base.font import BaseFont
from fontparts.base.layer import BaseLayer
from fontparts.base import BaseItems
from fontparts.base import BaseKeys
from fontparts.base import BaseValues
from fontParts.base.layer import BaseLayer
from fontParts.base.base import BaseItems
from fontParts.base.base import BaseValues
from fontParts.base.base import BaseKeys


class BaseLib(BaseDict, DeprecatedLib, RemovedLib):
Expand Down
56 changes: 31 additions & 25 deletions Lib/fontParts/fontshell/anchor.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
from __future__ import annotations
from typing import cast, Optional

import defcon
from fontParts.base import BaseAnchor
from fontParts.base.annotations import (
QuadrupleType,
QuadrupleCollectionType,
IntFloatType,
)
from fontParts.fontshell.base import RBaseObject


class RAnchor(RBaseObject, BaseAnchor):
wrapClass = defcon.Anchor

def _init(self, wrap=None):
if wrap is None:
wrap = self.wrapClass()
wrap.x = 0
wrap.y = 0
super(RAnchor, self)._init(wrap=wrap)
def _init(self, pathOrObject: Optional[defcon.Anchor] = None) -> None:
if self.wrapClass is not None:
if pathOrObject is None:
pathOrObject = self.wrapClass()
pathOrObject.x = 0
pathOrObject.y = 0
super(RAnchor, self)._init(pathOrObject=pathOrObject)

# --------
# Position
# --------

# x

def _get_x(self):
def _get_x(self) -> float:
return self.naked().x

def _set_x(self, value):
def _set_x(self, value: float) -> None:
self.naked().x = value

# y

def _get_y(self):
def _get_y(self) -> float:
return self.naked().y

def _set_y(self, value):
def _set_y(self, value: float) -> None:
self.naked().y = value

# --------------
Expand All @@ -39,32 +48,29 @@ def _set_y(self, value):

# identifier

def _get_identifier(self):
anchor = self.naked()
return anchor.identifier
def _get_identifier(self) -> Optional[str]:
return self.naked().identifier

def _getIdentifier(self):
anchor = self.naked()
return anchor.generateIdentifier()
def _getIdentifier(self) -> str:
return self.naked().generateIdentifier()

def _setIdentifier(self, value):
def _setIdentifier(self, value: str) -> None:
self.naked().identifier = value

# name

def _get_name(self):
def _get_name(self) -> Optional[str]:
return self.naked().name

def _set_name(self, value):
def _set_name(self, value: str) -> None:
self.naked().name = value

# color

def _get_color(self):
value = self.naked().color
if value is not None:
value = tuple(value)
return value
def _get_color(self) -> Optional[QuadrupleType[float]]:
return self.naked().color

def _set_color(self, value):
def _set_color(
self, value: Optional[QuadrupleCollectionType[IntFloatType]]
) -> None:
self.naked().color = value
27 changes: 17 additions & 10 deletions Lib/fontParts/fontshell/base.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
class RBaseObject(object):
wrapClass = None
from __future__ import annotations
from typing import Generic, Optional, Type, TypeVar

def _init(self, wrap=None):
if wrap is None and self.wrapClass is not None:
wrap = self.wrapClass()
if wrap is not None:
self._wrapped = wrap
RBaseObjectType = TypeVar("RBaseObjectType", bound="RBaseObject")

def changed(self):

class RBaseObject(Generic[RBaseObjectType]):
wrapClass: Optional[Type[RBaseObjectType]] = None
dirty: bool

def _init(self, pathOrObject: Optional[RBaseObjectType] = None) -> None:
if pathOrObject is None and self.wrapClass is not None:
pathOrObject = self.wrapClass() # pylint: disable=E1102
if pathOrObject is not None:
self._wrapped = pathOrObject

def changed(self) -> None:
self.naked().dirty = True

def naked(self):
def naked(self) -> RBaseObjectType:
if hasattr(self, "_wrapped"):
return self._wrapped
return None
return None # type: ignore[return-value]
42 changes: 32 additions & 10 deletions Lib/fontParts/fontshell/component.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
from __future__ import annotations
from typing import Optional, Type

import defcon
from fontParts.base import BaseComponent
from fontParts.base.annotations import (
SextupleType,
SextupleCollectionType,
IntFloatType,
)
from fontParts.fontshell.base import RBaseObject


class RComponent(RBaseObject, BaseComponent):
wrapClass = defcon.Component
wrapClass: Type[defcon.Component] = defcon.Component

# ----------
# Attributes
# ----------

# baseGlyph

def _get_baseGlyph(self):
return self.naked().baseGlyph
def _get_baseGlyph(self) -> Optional[str]:
component = self.naked()
return component.baseGlyph if component else None

def _set_baseGlyph(self, value):
self.naked().baseGlyph = value
def _set_baseGlyph(self, value: str) -> None:
component = self.naked()
if component is not None:
component.baseGlyph = value

# transformation

def _get_transformation(self):
return self.naked().transformation
def _get_transformation(self) -> SextupleType[float]:
component = self.naked()
if component is None:
raise ValueError("Naked cannot be None.")
return component.transformation

def _set_transformation(self, value):
self.naked().transformation = value
def _set_transformation(self, value: SextupleCollectionType[IntFloatType]) -> None:
component = self.naked()
if component is not None:
component.transformation = value

# --------------
# Identification
Expand All @@ -44,14 +60,20 @@ def _set_index(self, value):

def _get_identifier(self):
component = self.naked()
if component is None:
return None
return component.identifier

def _getIdentifier(self):
component = self.naked()
if component is None:
return None
return component.generateIdentifier()

def _setIdentifier(self, value):
self.naked().identifier = value
component = self.naked()
if component is not None:
component.identifier = value

# -------------
# Normalization
Expand Down
Loading
Loading