Skip to content

Commit 8f1ce91

Browse files
authored
Work through bit-rot (#128)
This should fix recent `pip` source install issues. * `Cython` version is now unbounded. `celiagg` needed to be added to the include directories but that's basically it. * `numpy` is now used instead of `oldest-supported-numpy` * `importlib.resources` is now used in place of `pkg_resources`. Unfortunately this breaks the API of `celiagg.example_font`. * Dropped support for Python 3.7
1 parent b76a5dc commit 8f1ce91

File tree

11 files changed

+93
-79
lines changed

11 files changed

+93
-79
lines changed

.github/workflows/test-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
matrix:
1111
os: [ubuntu-latest, windows-latest, macos-latest]
12-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
12+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
1313

1414
runs-on: ${{ matrix.os }}
1515

celiagg/__init__.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#
2424
# Authors: Erik Hvatum <[email protected]>
2525
# John Wiggins
26+
import contextlib
2627
import sys
2728

2829
from . import _celiagg
@@ -38,21 +39,26 @@
3839
HAS_TEXT = _celiagg.has_text_rendering()
3940

4041

42+
@contextlib.contextmanager
4143
def example_font():
4244
""" Returns the path to a TTF font which is included with the library for
4345
testing purposes.
4446
"""
45-
import pkg_resources
46-
47-
# Windows GDI font selection uses names and not file paths.
48-
# Our included font could be added to the system fonts using
49-
# `AddFontResourceEx`, but that's beyond the scope of this function.
50-
if sys.platform in ('win32', 'cygwin'):
51-
return 'Segoe UI'
52-
53-
return pkg_resources.resource_filename(
54-
'celiagg', 'data/Montserrat-Regular.ttf'
55-
)
47+
try:
48+
# Windows GDI font selection uses names and not file paths.
49+
# Our included font could be added to the system fonts using
50+
# `AddFontResourceEx`, but that's beyond the scope of this function.
51+
if sys.platform in ('win32', 'cygwin'):
52+
yield 'Segoe UI'
53+
else:
54+
import importlib.resources
55+
56+
with importlib.resources.path(
57+
'celiagg.data', 'Montserrat-Regular.ttf'
58+
) as path:
59+
yield str(path)
60+
finally:
61+
pass
5662

5763

5864
# Be explicit

celiagg/_celiagg.pyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#
2424
# Authors: Erik Hvatum <[email protected]>
2525

26+
# cython: language_level=3
2627
# distutils: language=c++
2728
from libcpp cimport bool
2829
import cython

celiagg/data/__init__.py

Whitespace-only changes.

celiagg/tests/test_canvas.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,15 @@ def test_bad_method_args(self):
7474

7575
if agg.HAS_TEXT:
7676
text = 'Hello!'
77-
font = agg.Font(agg.example_font(), 12.0)
78-
with self.assertRaises(TypeError):
79-
canvas.draw_text(text, None, transform, gs)
80-
with self.assertRaises(TypeError):
81-
canvas.draw_text(text, font, None, gs)
82-
with self.assertRaises(TypeError):
83-
canvas.draw_text(text, font, transform, None)
84-
canvas.draw_text(text, font, transform, gs)
77+
with agg.example_font() as font_path:
78+
font = agg.Font(font_path, 12.0)
79+
with self.assertRaises(TypeError):
80+
canvas.draw_text(text, None, transform, gs)
81+
with self.assertRaises(TypeError):
82+
canvas.draw_text(text, font, None, gs)
83+
with self.assertRaises(TypeError):
84+
canvas.draw_text(text, font, transform, None)
85+
canvas.draw_text(text, font, transform, gs)
8586

8687
def test_stencil_size_mismatch(self):
8788
canvas = agg.CanvasRGB24(np.zeros((4, 5, 3), dtype=np.uint8))

celiagg/tests/test_font.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,28 @@
3232
class TestFont(unittest.TestCase):
3333
@unittest.skipIf(is_windows, "Don't test FreeTypeFont on Windows")
3434
def test_freetype_font(self):
35-
path = agg.example_font()
35+
with agg.example_font() as path:
36+
# Test default arguments
37+
font = agg.Font(path, 12.0)
38+
self.assertEqual(font.filepath, path)
39+
self.assertEqual(font.height, 12.0)
40+
self.assertEqual(font.face_index, 0)
3641

37-
# Test default arguments
38-
font = agg.Font(path, 12.0)
39-
self.assertEqual(font.filepath, path)
40-
self.assertEqual(font.height, 12.0)
41-
self.assertEqual(font.face_index, 0)
42-
43-
# Then optional
44-
font = agg.Font(path, 12.0, face_index=42)
45-
self.assertEqual(font.face_index, 42)
42+
# Then optional
43+
font = agg.Font(path, 12.0, face_index=42)
44+
self.assertEqual(font.face_index, 42)
4645

4746
@unittest.skipIf(not is_windows, "Don't test Win32Font on other platforms")
4847
def test_win32_font(self):
49-
face_name = agg.example_font()
50-
51-
# Test default arguments
52-
font = agg.Font(face_name, 12.0)
53-
self.assertEqual(font.face_name, face_name)
54-
self.assertEqual(font.height, 12.0)
55-
self.assertEqual(font.weight, agg.FontWeight.Regular)
56-
self.assertFalse(font.italic)
57-
58-
# Then optional
59-
font = agg.Font(face_name, 12.0, agg.FontWeight.ExtraBold, True)
60-
self.assertEqual(font.weight, agg.FontWeight.ExtraBold)
61-
self.assertTrue(font.italic)
48+
with agg.example_font() as face_name:
49+
# Test default arguments
50+
font = agg.Font(face_name, 12.0)
51+
self.assertEqual(font.face_name, face_name)
52+
self.assertEqual(font.height, 12.0)
53+
self.assertEqual(font.weight, agg.FontWeight.Regular)
54+
self.assertFalse(font.italic)
55+
56+
# Then optional
57+
font = agg.Font(face_name, 12.0, agg.FontWeight.ExtraBold, True)
58+
self.assertEqual(font.weight, agg.FontWeight.ExtraBold)
59+
self.assertTrue(font.italic)

celiagg/tests/test_text.py

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ def test_font_byte_string(self):
3535
gs = agg.GraphicsState()
3636
transform = agg.Transform()
3737

38-
text_unicode = 'Hello!'
39-
font_unicode = agg.Font(agg.example_font(), 12.0)
40-
text_byte = b'Hello!'
41-
font_byte = agg.Font(agg.example_font().encode('utf8'), 12.0)
38+
with agg.example_font() as font_path:
39+
text_unicode = 'Hello!'
40+
font_unicode = agg.Font(font_path, 12.0)
41+
text_byte = b'Hello!'
42+
font_byte = agg.Font(font_path.encode('utf8'), 12.0)
4243

43-
canvas.draw_text(text_unicode, font_unicode, transform, gs)
44-
canvas.draw_text(text_byte, font_unicode, transform, gs)
45-
canvas.draw_text(text_unicode, font_byte, transform, gs)
46-
canvas.draw_text(text_byte, font_byte, transform, gs)
44+
canvas.draw_text(text_unicode, font_unicode, transform, gs)
45+
canvas.draw_text(text_byte, font_unicode, transform, gs)
46+
canvas.draw_text(text_unicode, font_byte, transform, gs)
47+
canvas.draw_text(text_byte, font_byte, transform, gs)
4748

4849
def test_text_rendering(self):
4950
font_cache = agg.FontCache()
@@ -52,18 +53,19 @@ def test_text_rendering(self):
5253
)
5354
canvas.clear(1.0, 1.0, 1.0)
5455

55-
font = agg.Font(agg.example_font(), 24.0)
56-
gs = agg.GraphicsState()
57-
paint = agg.SolidPaint(1.0, 0.0, 0.0, 1.0)
58-
transform = agg.Transform()
59-
60-
text = 'Hello!'
61-
width = font_cache.width(font, text)
62-
draw_x, draw_y = 25.0, 50.0
63-
transform.translate(draw_x, draw_y)
64-
cursor = canvas.draw_text(
65-
text, font, transform, gs, stroke=paint, fill=paint
66-
)
56+
with agg.example_font() as font_path:
57+
font = agg.Font(font_path, 24.0)
58+
gs = agg.GraphicsState()
59+
paint = agg.SolidPaint(1.0, 0.0, 0.0, 1.0)
60+
transform = agg.Transform()
61+
62+
text = 'Hello!'
63+
width = font_cache.width(font, text)
64+
draw_x, draw_y = 25.0, 50.0
65+
transform.translate(draw_x, draw_y)
66+
cursor = canvas.draw_text(
67+
text, font, transform, gs, stroke=paint, fill=paint
68+
)
6769
self.assertIsNotNone(cursor)
6870
# Text cursor Y is unchanged, X is `width` pixels away from `draw_x`
6971
self.assertAlmostEqual(cursor[0] - width, draw_x)
@@ -80,21 +82,25 @@ def test_text_measurement(self):
8082
canvas = agg.CanvasRGB24(
8183
np.zeros((100, 100, 3), dtype=np.uint8), font_cache=font_cache,
8284
)
83-
font = agg.Font(agg.example_font(), 12.0)
8485
gs = agg.GraphicsState()
8586
paint = agg.SolidPaint(1.0, 0.0, 0.0, 1.0)
8687
text = 'Some appropriate string'
8788
transform = agg.Transform()
8889

89-
# Measure before drawing
90-
width_before = font_cache.width(font, text)
90+
with agg.example_font() as font_path:
91+
font = agg.Font(font_path, 12.0)
92+
93+
# Measure before drawing
94+
width_before = font_cache.width(font, text)
9195

92-
# Draw with a transform
93-
transform.translate(25, 75)
94-
transform.rotate(0.75)
95-
canvas.draw_text(text, font, transform, gs, stroke=paint, fill=paint)
96+
# Draw with a transform
97+
transform.translate(25, 75)
98+
transform.rotate(0.75)
99+
canvas.draw_text(
100+
text, font, transform, gs, stroke=paint, fill=paint
101+
)
96102

97-
# Measure after drawing
98-
width_after = font_cache.width(font, text)
103+
# Measure after drawing
104+
width_after = font_cache.width(font, text)
99105

100106
self.assertEqual(width_after, width_before)

docs/source/example.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ Draw some text
7474
--------------
7575

7676
Next up, some text. We'll use the `Montserrat <https://github.com/JulietaUla/Montserrat>`_ font which is included with
77-
celiagg, conveniently available via the ``example_font`` function. A ``font``
77+
celiagg, conveniently available via the ``example_font`` context manager. A ``font``
7878
object is created with a point size of 96. The ``transform`` gets a
7979
translation of (30, 220) set. This corresponds to a point which is 30 pixels
8080
from the left side of the image and 220 pixels from the *top* of the image.
8181
(celiagg defaults to a top-left origin, but also supports bottom-left origin)
8282
The text will be drawn starting from that point.
8383

8484
.. literalinclude:: simple_ex.py
85-
:lines: 18-20
85+
:lines: 18-21
8686
:linenos:
8787
:lineno-match:
8888

docs/source/simple_ex.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
canvas.clear(1.0, 1.0, 1.0)
1616
canvas.draw_shape(path, transform, state, stroke=red_paint)
1717

18-
font = agg.Font(agg.example_font(), 96.0)
19-
transform.translate(30.0, 220.0)
20-
canvas.draw_text("celiagg", font, transform, state, fill=orange_paint)
18+
with agg.example_font() as font_path:
19+
font = agg.Font(font_path, 96.0)
20+
transform.translate(30.0, 220.0)
21+
canvas.draw_text("celiagg", font, transform, state, fill=orange_paint)
2122

2223
image = Image.fromarray(canvas.array, "RGB")
2324
image.save("example.png")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["cython<3", "oldest-supported-numpy", "setuptools", "wheel"]
2+
requires = ["cython", "numpy", "setuptools", "wheel"]
33
build-backend = "setuptools.build_meta"
44

55
[tool.cibuildwheel]

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def create_extension():
161161

162162
include_dirs = ['agg-svn/agg-2.4/include',
163163
'agg-svn/agg-2.4',
164+
'celiagg',
164165
numpy.get_include()]
165166
if platform.system() == "Windows":
166167
# Visual studio does not support/need these
@@ -254,5 +255,5 @@ def create_extension():
254255
package_data={
255256
'celiagg': ['data/*'],
256257
},
257-
python_requires=">=3.7",
258+
python_requires=">=3.8",
258259
)

0 commit comments

Comments
 (0)