Skip to content

Commit 0af0f65

Browse files
committed
Deprecate passing floats to FT2Image
These were silently truncated to int anyway, so we should make the types explicit.
1 parent 3c3e216 commit 0af0f65

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

doc/api/next_api_changes/deprecations/288XX-ES.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ Passing floating-point values to ``RendererAgg.draw_text_image``
33

44
Any floating-point values passed to the *x* and *y* parameters were truncated to integers
55
silently. This behaviour is now deprecated, and only `int` values should be used.
6+
7+
Passing floating-point values to ``FT2Image``
8+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9+
10+
Any floating-point values passed to the `.FT2Image` constructor, or the *x0*, *y0*, *x1*,
11+
and *y1* parameters of `.FT2Image.draw_rect_filled` were truncated to integers silently.
12+
This behaviour is now deprecated, and only `int` values should be used.

lib/matplotlib/_mathtext.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
153153
w = xmax - xmin
154154
h = ymax - ymin - self.box.depth
155155
d = ymax - ymin - self.box.height
156-
image = FT2Image(np.ceil(w), np.ceil(h + max(d, 0)))
156+
image = FT2Image(int(np.ceil(w)), int(np.ceil(h + max(d, 0))))
157157

158158
# Ideally, we could just use self.glyphs and self.rects here, shifting
159159
# their coordinates by (-xmin, -ymin), but this yields slightly
@@ -172,7 +172,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
172172
y = int(center - (height + 1) / 2)
173173
else:
174174
y = int(y1)
175-
image.draw_rect_filled(int(x1), y, np.ceil(x2), y + height)
175+
image.draw_rect_filled(int(x1), y, int(np.ceil(x2)), y + height)
176176
return RasterParse(0, 0, w, h + d, d, image)
177177

178178

lib/matplotlib/ft2font.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,8 @@ class FT2Font(Buffer):
281281

282282
@final
283283
class FT2Image(Buffer):
284-
def __init__(self, width: float, height: float) -> None: ...
285-
def draw_rect_filled(self, x0: float, y0: float, x1: float, y1: float) -> None: ...
284+
def __init__(self, width: int, height: int) -> None: ...
285+
def draw_rect_filled(self, x0: int, y0: int, x1: int, y1: int) -> None: ...
286286
if sys.version_info[:2] >= (3, 12):
287287
def __buffer__(self, flags: int) -> memoryview: ...
288288

src/ft2font_wrapper.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ P11X_DECLARE_ENUM(
207207
* FT2Image
208208
* */
209209

210+
using double_or_long = std::variant<double, long>;
211+
210212
const char *PyFT2Image__doc__ = R"""(
211213
An image buffer for drawing glyphs.
212214
)""";
@@ -227,9 +229,32 @@ const char *PyFT2Image_draw_rect_filled__doc__ = R"""(
227229
The bounds of the rectangle from (x0, y0) to (x1, y1).
228230
)""";
229231

232+
static long
233+
_double_to_long(const char *name, double_or_long &var)
234+
{
235+
if (auto value = std::get_if<double>(&var)) {
236+
auto api = py::module_::import("matplotlib._api");
237+
auto warn = api.attr("warn_deprecated");
238+
warn("since"_a="3.10", "name"_a=name, "obj_type"_a="parameter as float",
239+
"alternative"_a="int({})"_s.format(name));
240+
return static_cast<long>(*value);
241+
} else if (auto value = std::get_if<long>(&var)) {
242+
return *value;
243+
} else {
244+
throw std::runtime_error("Should not happen");
245+
}
246+
}
247+
230248
static void
231-
PyFT2Image_draw_rect_filled(FT2Image *self, double x0, double y0, double x1, double y1)
249+
PyFT2Image_draw_rect_filled(FT2Image *self,
250+
double_or_long vx0, double_or_long vy0,
251+
double_or_long vx1, double_or_long vy1)
232252
{
253+
auto x0 = _double_to_long("x0", vx0);
254+
auto y0 = _double_to_long("y0", vy0);
255+
auto x1 = _double_to_long("x1", vx1);
256+
auto y1 = _double_to_long("y1", vy1);
257+
233258
self->draw_rect_filled(x0, y0, x1, y1);
234259
}
235260

@@ -1634,7 +1659,14 @@ PYBIND11_MODULE(ft2font, m)
16341659

16351660
py::class_<FT2Image>(m, "FT2Image", py::is_final(), py::buffer_protocol(),
16361661
PyFT2Image__doc__)
1637-
.def(py::init<double, double>(), "width"_a, "height"_a, PyFT2Image_init__doc__)
1662+
.def(py::init(
1663+
[](double_or_long width, double_or_long height) {
1664+
return new FT2Image(
1665+
_double_to_long("width", width),
1666+
_double_to_long("height", height)
1667+
);
1668+
}),
1669+
"width"_a, "height"_a, PyFT2Image_init__doc__)
16381670
.def("draw_rect_filled", &PyFT2Image_draw_rect_filled,
16391671
"x0"_a, "y0"_a, "x1"_a, "y1"_a,
16401672
PyFT2Image_draw_rect_filled__doc__)

0 commit comments

Comments
 (0)