8000 Sync v1 with changes to master by benkiel · Pull Request #845 · robotools/fontParts · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Sync v1 with changes to master #845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f72b3c1
Update fonttools from 4.53.1 to 4.54.1 (#746)
pyup-bot Sep 24, 2024
2bfa558
Update base.py (#750)
benkiel Oct 3, 2024
f67a570
Fix copyData based on #758 (#765)
benkiel Nov 8, 2024
7e324a3
Update fonttools from 4.54.1 to 4.55.0 (#771)
pyup-bot Nov 14, 2024
88fea44
Stop testing 3.8, start testing 3.12, 3.13
benkiel Nov 18, 2024
1051890
Update fonttools from 4.55.0 to 4.55.1 (#799)
pyup-bot Dec 3, 2024
55cd574
Update fonttools from 4.55.1 to 4.55.2 (#806)
pyup-bot Dec 5, 2024
26e8b8c
mark docstrings as raw to avoid SyntaxWarning (#830)
roberto-arista Apr 8, 2025
f5dd599
Upgrade `BaseDict` normalization. (#831)
knutnergaard Apr 28, 2025
c8ef0ca
update NEWS.rst
benkiel Apr 28, 2025
b64286a
Only round for real guideline coordinates x, y (#834)
typemytype May 27, 2025
faca97e
Update NEWS.rst
benkiel May 27, 2025
6d79818
Fixup NEWS.rst
benkiel May 27, 2025
ef12e49
Address #837 and add in some more places where is better for optiona…
benkiel May 30, 2025
a9ac296
Fix bug in `BaseFont.copyData`. (#839)
knutnergaard Jun 4, 2025
c157909
Update NEWS.rst
benkiel Jun 4, 2025
dc032d6
Update NEWS.rst
benkiel Jun 4, 2025
ab4d4e2
`insertGlyph` return the glyph object (#841)
benkiel Jun 11, 2025
e5898e6
Update NEWS.rst
8000 benkiel Jun 11, 2025
8d228a7
Update publish-package.yml (#842)
benkiel Jun 11, 2025
0504c71
Update NEWS.rst
benkiel Jun 11, 2025
103fcd9
Fix PyPi upload, thank you Cosimo
benkiel Jun 11, 2025
8adc476
Update publish-package.yml (#844)
benkiel Jun 11, 2025
1641279
Update publish-package.yml
benkiel Jun 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ jobs:
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
platform: [ubuntu-latest, macos-latest, windows-latest]
exclude: # Only test on the oldest and latest supported stable Python on macOS and Windows.
- platform: macos-latest
python-version: 3.9
- platform: windows-latest
python-version: 3.9
- platform: macos-latest
python-version: 3.10
- platform: windows-latest
python-version: 3.10
- platform: macos-latest
python-version: 3.11
- platform: windows-latest
python-version: 3.11
- platform: macos-latest
python-version: 3.13
- platform: windows-latest
python-version: 3.13
steps:
- uses: actions/checkout@v3.5.3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ build/*
dist/*
.eggs/
.vscode
*-venv/

documentation/build/*
documentation/.sass-cache/*
Expand All @@ -22,4 +23,4 @@ doc/*
htmlcov

# scm version
Lib/fontParts/_version.py
Lib/fontParts/_version.py
97 changes: 56 additions & 41 deletions Lib/fontParts/base/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ def copyData(self, source):
if isinstance(selfValue, BaseObject):
selfValue.copyData(sourceValue)
else:
setattr(self, attr, sourceValue)

setattr(self, attr, deepcopy(sourceValue))
# ----------
# Exceptions
# ----------
Expand Down Expand Up @@ -260,6 +259,18 @@ class BaseDict(BaseObject):
keyNormalizer = None
valueNormalizer = None

@classmethod
def _normalizeKey(cls, key):
if callable(cls.keyNormalizer):
return cls.keyNormalizer(key)
return key

@classmethod
def _normalizeValue(cls, value):
if callable(cls.valueNormalizer):
return cls.valueNormalizer(value)
return value

def copyData(self, source):
super(BaseDict, self).copyData(source)
self.update(source)
Expand All @@ -276,8 +287,8 @@ def _len(self):

def keys(self):
keys = self._keys()
if self.keyNormalizer is not None:
keys = [self.keyNormalizer.__func__(key) for key in keys]
if self._normalizeKey is not None:
keys = [self._normalizeKey(key) for key in keys]
return keys

def _keys(self):
Expand All @@ -288,13 +299,11 @@ def _keys(self):

def items(self):
items = self._items()
if self.keyNormalizer is not None and self.valueNormalizer is not None:
values = [
(self.keyNormalizer.__func__(key),
self.valueNormalizer.__func__(value))
for (key, value) in items
return [
(self._normalizeKey(key), self._normalizeValue(value))
for (key, value) in items
]
return values


def _items(self):
"""
Expand All @@ -304,8 +313,8 @@ def _items(self):

def values(self):
values = self._values()
if self.valueNormalizer is not None:
values = [self.valueNormalizer.__func__(value) for value in values]
if self._normalizeValue is not None:
values = [self._normalizeValue(value) for value in values]
return values

def _values(self):
Expand All @@ -315,8 +324,8 @@ def _values(self):
return [v for k, v in self.items()]

def __contains__(self, key):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
return self._contains(key)

def _contains(self, key):
Expand All @@ -328,10 +337,10 @@ def _contains(self, key):
has_key = __contains__

def __setitem__(self, key, value):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if self.valueNormalizer is not None:
value = self.valueNormalizer.__func__(value)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
if self._normalizeValue is not None:
value = self._normalizeValue(value)
self._setItem(key, value)

def _setItem(self, key, value):
Expand All @@ -341,11 +350,11 @@ def _setItem(self, key, value):
self.raiseNotImplementedError()

def __getitem__(self, key):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
value = self._getItem(key)
if self.valueNormalizer is not None:
value = self.valueNormalizer.__func__(value)
if self._normalizeValue is not None:
value = self._normalizeValue(value)
return value

def _getItem(self, key):
Expand All @@ -355,13 +364,13 @@ def _getItem(self, key):
self.raiseNotImplementedError()

def get(self, key, default=None):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if default is not None and self.valueNormalizer is not None:
default = self.valueNormalizer.__func__(default)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
if default is not None and self._normalizeValue is not None:
default = self._normalizeValue(default)
value = self._get(key, default=default)
if value is not default and self.valueNormalizer is not None:
value = self.valueNormalizer.__func__(value)
if value is not default and self._normalizeValue is not None:
value = self._normalizeValue(value)
return value

def _get(self, key, default=None):
Expand All @@ -373,8 +382,8 @@ def _get(self, key, default=None):
return default

def __delitem__(self, key):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
self._delItem(key)

def _delItem(self, key):
Expand All @@ -384,13 +393,13 @@ def _delItem(self, key):
self.raiseNotImplementedError()

def pop(self, key, default=None):
if self.keyNormalizer is not None:
key = self.keyNormalizer.__func__(key)
if default is not None and self.valueNormalizer is not None:
default = self.valueNormalizer.__func__(default)
if self._normalizeKey is not None:
key = self._normalizeKey(key)
if default is not None and self._normalizeValue is not None:
default = self._normalizeValue(default)
value = self._pop(key, default=default)
if self.valueNormalizer is not None:
value = self.valueNormalizer.__func__(value)
if self._normalizeValue is not None:
value = self._normalizeValue(value)
return value

def _pop(self, key, default=None):
Expand Down Expand Up @@ -418,11 +427,11 @@ def _iter(self):

def update(self, other):
other = deepcopy(other)
if self.keyNormalizer is not None and self.valueNormalizer is not None:
if self._normalizeKey is not None and self._normalizeValue is not None:
d = {}
for key, value in other.items():
key = self.keyNormalizer.__func__(key)
value = self.valueNormalizer.__func__(value)
key = self._normalizeKey(key)
value = self._normalizeValue(value)
d[key] = value
value = d
self._update(other)
Expand Down Expand Up @@ -830,8 +839,14 @@ def _setIdentifier(self, value):


def reference(obj):
# import weakref
# return weakref.ref(obj)
"""
This code returns a simple function that returns the given object.
This is a backwards compatibility function that is under review.
See #749. We used to use weak references, but they proved
problematic (see issue #71), so this function was put in place to
make sure existing code continued to function. The need for it is
questionable, so it may be deleted soon.
"""
def wrapper():
return obj
return wrapper
Expand Down
4 changes: 2 additions & 2 deletions Lib/fontParts/base/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def copyData(self, source):
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
6 changes: 3 additions & 3 deletions Lib/fontParts/base/glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,7 @@ def _fromMathGlyph(self, mathGlyph, toThisGlyph=False, filterRedundantPoints=Tru
a = copied.appendAnchor(
name=anchor.get("name"),
position=(anchor["x"], anchor["y"]),
color=anchor["color"]
color=anchor.get("color")
)
identifier = anchor.get("identifier")
if identifier is not None:
Expand All @@ -1705,8 +1705,8 @@ def _fromMathGlyph(self, mathGlyph, toThisGlyph=False, filterRedundantPoints=Tru
g = copied.appendGuideline(
position=(guideline["x"], guideline["y"]),
angle=guideline["angle"],
name=guideline["name"],
color=guideline["color"]
name=guideline.get("name"),
color=guideline.get("color")
)
identifier = guideline.get("identifier")
if identifier is not None:
Expand Down
2 changes: 1 addition & 1 deletion Lib/fontParts/base/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def findGlyph(self, glyphName):
"""
glyphName = normalizers.normalizeGlyphName(glyphName)
groupNames = self._findGlyph(glyphName)
groupNames = [self.keyNormalizer.__func__(
groupNames = [self._normalizeKey(
groupName) for groupName in groupNames]
return groupNames

Expand Down
8 changes: 6 additions & 2 deletions Lib/fontParts/base/guideline.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,9 @@ def _round(self, **kwargs):

Subclasses may override this method.
"""
self.x = normalizers.normalizeVisualRounding(self.x)
self.y = normalizers.normalizeVisualRounding(self.y)
x = self._get_x()
if x is not None:
self.x = normalizers.normalizeVisualRounding(normalizers.normalizeX(x))
y = self._get_y()
if y is not None:
self.y = normalizers.normalizeVisualRounding(normalizers.normalizeY(y))
22 changes: 11 additions & 11 deletions Lib/fontParts/base/kerning.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _round(self, multiple=1):
# -------------

def interpolate(self, factor, minKerning, maxKerning, round=True, suppressError=True):
"""
r"""
Interpolates all pairs between two :class:`BaseKerning` objects:

>>> myKerning.interpolate(kerningOne, kerningTwo)
Expand Down Expand Up @@ -221,7 +221,7 @@ def _testKerningGroupCompatibility(minKerning, maxKerning, suppressError=False):
# ---------------------

def remove(self, pair):
"""
r"""
Removes a pair from the Kerning. **pair** will
be a ``tuple`` of two :ref:`type-string`\s.

Expand All @@ -245,7 +245,7 @@ def asDict(self, returnIntegers=True):
# -------------------

def __contains__(self, pair):
"""
r"""
Tests to see if a pair is in the Kerning.
**pair** will be a ``tuple`` of two :ref:`type-string`\s.

Expand All @@ -258,7 +258,7 @@ def __contains__(self, pair):
return super(BaseKerning, self).__contains__(pair)

def __delitem__(self, pair):
"""
r"""
Removes **pair** from the Kerning. **pair** is a ``tuple`` of two
:ref:`type-string`\s.::

Expand All @@ -267,7 +267,7 @@ def __delitem__(self, pair):
super(BaseKerning, self).__delitem__(pair)

def __getitem__(self, pair):
"""
r"""
Returns the kerning value of the pair. **pair** is a ``tuple`` of
two :ref:`type-string`\s.

Expand Down Expand Up @@ -309,7 +309,7 @@ def __len__(self):
return super(BaseKerning, self).__len__()

def __setitem__(self, pair, value):
"""
r"""
Sets the **pair** to the list of **value**. **pair** is the
pair as a ``tuple`` of two :ref:`type-string`\s and **value**

Expand All @@ -330,7 +330,7 @@ def clear(self):
super(BaseKerning, self).clear()

def get(self, pair, default=None):
"""
r"""
Returns the value for the kerning pair.
**pair** is a ``tuple`` of two :ref:`type-string`\s, and the returned
values will either be :ref:`type-int-float` or ``None``
Expand All @@ -350,7 +350,7 @@ def get(self, pair, default=None):
return super(BaseKerning, self).get(pair, default)

def find(self, pair, default=None):
"""
r"""
Returns the value for the kerning pair - even if the pair only exists
implicitly (one or both sides may be members of a kerning group).

Expand Down Expand Up @@ -379,7 +379,7 @@ def _find(self, pair, default=None):
return lookupKerningValue(pair, self, groups, fallback=default)

def items(self):
"""
r"""
Returns a list of ``tuple``\s of each pair and value. Pairs are a
``tuple`` of two :ref:`type-string`\s and values are :ref:`type-int-float`.

Expand All @@ -401,7 +401,7 @@ def keys(self):
return super(BaseKerning, self).keys()

def pop(self, pair, default=None):
"""
r"""
Removes the **pair** from the Kerning and returns the value as an ``int``.
If no pair is found, **default** is returned. **pair** is a
``tuple`` of two :ref:`type-string`\s. This must return either
Expand All @@ -428,7 +428,7 @@ def update(self, otherKerning):
super(BaseKerning, self).update(otherKerning)

def values(self):
"""
r"""
Returns a ``list`` of each pair's values, the values will be
:ref:`type-int-float`\s.

Expand Down
Loading
0