Skip to content

Commit 3770dfe

Browse files
authored
Merge pull request #28967 from QuLogic/msvc-casts
Fix MSVC cast warnings
2 parents 6e60725 + 4d40c1b commit 3770dfe

File tree

9 files changed

+116
-31
lines changed

9 files changed

+116
-31
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Passing floating-point values to ``RendererAgg.draw_text_image``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Any floating-point values passed to the *x* and *y* parameters were truncated to integers
5+
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

+3-3
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
@@ -163,7 +163,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
163163

164164
for ox, oy, info in shifted.glyphs:
165165
info.font.draw_glyph_to_bitmap(
166-
image, ox, oy - info.metrics.iceberg, info.glyph,
166+
image, int(ox), int(oy - info.metrics.iceberg), info.glyph,
167167
antialiased=antialiased)
168168
for x1, y1, x2, y2 in shifted.rects:
169169
height = max(int(y2 - y1) - 1, 0)
@@ -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

+3-3
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class FT2Font(Buffer):
198198
def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ...
199199
def clear(self) -> None: ...
200200
def draw_glyph_to_bitmap(
201-
self, image: FT2Image, x: float, y: float, glyph: Glyph, antialiased: bool = ...
201+
self, image: FT2Image, x: int, y: int, glyph: Glyph, antialiased: bool = ...
202202
) -> None: ...
203203
def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ...
204204
def get_bitmap_offset(self) -> tuple[int, int]: ...
@@ -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/_backend_agg.h

+16-9
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face,
350350
agg::trans_affine hatch_trans;
351351
hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
352352
hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
353-
hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
353+
hatch_trans *= agg::trans_affine_scaling(static_cast<double>(hatch_size),
354+
static_cast<double>(hatch_size));
354355
hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
355356
hatch_path_curve_t hatch_path_curve(hatch_path_trans);
356357
hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);
@@ -739,16 +740,19 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
739740

740741
set_clipbox(gc.cliprect, theRasterizer);
741742

743+
auto image_height = static_cast<double>(image.shape(0)),
744+
image_width = static_cast<double>(image.shape(1));
745+
742746
agg::trans_affine mtx;
743-
mtx *= agg::trans_affine_translation(0, -image.shape(0));
747+
mtx *= agg::trans_affine_translation(0, -image_height);
744748
mtx *= agg::trans_affine_rotation(-angle * (agg::pi / 180.0));
745749
mtx *= agg::trans_affine_translation(x, y);
746750

747751
agg::path_storage rect;
748752
rect.move_to(0, 0);
749-
rect.line_to(image.shape(1), 0);
750-
rect.line_to(image.shape(1), image.shape(0));
751-
rect.line_to(0, image.shape(0));
753+
rect.line_to(image_width, 0);
754+
rect.line_to(image_width, image_height);
755+
rect.line_to(0, image_height);
752756
rect.line_to(0, 0);
753757
agg::conv_transform<agg::path_storage> rect2(rect, mtx);
754758

@@ -842,12 +846,15 @@ inline void RendererAgg::draw_image(GCAgg &gc,
842846
agg::trans_affine mtx;
843847
agg::path_storage rect;
844848

845-
mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.shape(0))));
849+
auto image_height = static_cast<double>(image.shape(0)),
850+
image_width = static_cast<double>(image.shape(1));
851+
852+
mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image_height)));
846853

847854
rect.move_to(0, 0);
848-
rect.line_to(image.shape(1), 0);
849-
rect.line_to(image.shape(1), image.shape(0));
850-
rect.line_to(0, image.shape(0));
855+
rect.line_to(image_width, 0);
856+
rect.line_to(image_width, image_height);
857+
rect.line_to(0, image_height);
851858
rect.line_to(0, 0);
852859

853860
agg::conv_transform<agg::path_storage> rect2(rect, mtx);

src/_backend_agg_wrapper.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,37 @@ PyRendererAgg_draw_path(RendererAgg *self,
5858
static void
5959
PyRendererAgg_draw_text_image(RendererAgg *self,
6060
py::array_t<agg::int8u, py::array::c_style | py::array::forcecast> image_obj,
61-
double x,
62-
double y,
61+
std::variant<double, int> vx,
62+
std::variant<double, int> vy,
6363
double angle,
6464
GCAgg &gc)
6565
{
66+
int x, y;
67+
68+
if (auto value = std::get_if<double>(&vx)) {
69+
auto api = py::module_::import("matplotlib._api");
70+
auto warn = api.attr("warn_deprecated");
71+
warn("since"_a="3.10", "name"_a="x", "obj_type"_a="parameter as float",
72+
"alternative"_a="int(x)");
73+
x = static_cast<int>(*value);
74+
} else if (auto value = std::get_if<int>(&vx)) {
75+
x = *value;
76+
} else {
77+
throw std::runtime_error("Should not happen");
78+
}
79+
80+
if (auto value = std::get_if<double>(&vy)) {
81+
auto api = py::module_::import("matplotlib._api");
82+
auto warn = api.attr("warn_deprecated");
83+
warn("since"_a="3.10", "name"_a="y", "obj_type"_a="parameter as float",
84+
"alternative"_a="int(y)");
85+
y = static_cast<int>(*value);
86+
} else if (auto value = std::get_if<int>(&vy)) {
87+
y = *value;
88+
} else {
89+
throw std::runtime_error("Should not happen");
90+
}
91+
6692
// TODO: This really shouldn't be mutable, but Agg's renderer buffers aren't const.
6793
auto image = image_obj.mutable_unchecked<2>();
6894

src/_image_resample.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,8 @@ class span_conv_alpha
566566
{
567567
if (m_alpha != 1.0) {
568568
do {
569-
span->a *= m_alpha;
569+
span->a = static_cast<typename color_type::value_type>(
570+
static_cast<typename color_type::calc_type>(span->a) * m_alpha);
570571
++span;
571572
} while (--len);
572573
}

src/ft2font_wrapper.cpp

+46-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,30 @@
1313
namespace py = pybind11;
1414
using namespace pybind11::literals;
1515

16+
template <typename T>
17+
using double_or_ = std::variant<double, T>;
18+
19+
template <typename T>
20+
static T
21+
_double_to_(const char *name, double_or_<T> &var)
22+
{
23+
if (auto value = std::get_if<double>(&var)) {
24+
auto api = py::module_::import("matplotlib._api");
25+
auto warn = api.attr("warn_deprecated");
26+
warn("since"_a="3.10", "name"_a=name, "obj_type"_a="parameter as float",
27+
"alternative"_a="int({})"_s.format(name));
28+
return static_cast<T>(*value);
29+
} else if (auto value = std::get_if<T>(&var)) {
30+
return *value;
31+
} else {
32+
// pybind11 will have only allowed types that match the variant, so this `else`
33+
// can't happen. We only have this case because older macOS doesn't support
34+
// `std::get` and using the conditional `std::get_if` means an `else` to silence
35+
// compiler warnings about "unhandled" cases.
36+
throw std::runtime_error("Should not happen");
37+
}
38+
}
39+
1640
/**********************************************************************
1741
* Enumerations
1842
* */
@@ -227,8 +251,15 @@ const char *PyFT2Image_draw_rect_filled__doc__ = R"""(
227251
)""";
228252

229253
static void
230-
PyFT2Image_draw_rect_filled(FT2Image *self, double x0, double y0, double x1, double y1)
254+
PyFT2Image_draw_rect_filled(FT2Image *self,
255+
double_or_<long> vx0, double_or_<long> vy0,
256+
double_or_<long> vx1, double_or_<long> vy1)
231257
{
258+
auto x0 = _double_to_<long>("x0", vx0);
259+
auto y0 = _double_to_<long>("y0", vy0);
260+
auto x1 = _double_to_<long>("x1", vx1);
261+
auto y1 = _double_to_<long>("y1", vy1);
262+
232263
self->draw_rect_filled(x0, y0, x1, y1);
233264
}
234265

@@ -920,7 +951,7 @@ const char *PyFT2Font_draw_glyph_to_bitmap__doc__ = R"""(
920951
----------
921952
image : FT2Image
922953
The image buffer on which to draw the glyph.
923-
x, y : float
954+
x, y : int
924955
The pixel location at which to draw the glyph.
925956
glyph : Glyph
926957
The glyph to draw.
@@ -933,9 +964,13 @@ const char *PyFT2Font_draw_glyph_to_bitmap__doc__ = R"""(
933964
)""";
934965

935966
static void
936-
PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, FT2Image &image, double xd, double yd,
967+
PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, FT2Image &image,
968+
double_or_<int> vxd, double_or_<int> vyd,
937969
PyGlyph *glyph, bool antialiased = true)
938970
{
971+
auto xd = _double_to_<int>("x", vxd);
972+
auto yd = _double_to_<int>("y", vyd);
973+
939974
self->x->draw_glyph_to_bitmap(image, xd, yd, glyph->glyphInd, antialiased);
940975
}
941976

@@ -1625,7 +1660,14 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16251660

16261661
py::class_<FT2Image>(m, "FT2Image", py::is_final(), py::buffer_protocol(),
16271662
PyFT2Image__doc__)
1628-
.def(py::init<double, double>(), "width"_a, "height"_a, PyFT2Image_init__doc__)
1663+
.def(py::init(
1664+
[](double_or_<long> width, double_or_<long> height) {
1665+
return new FT2Image(
1666+
_double_to_<long>("width", width),
1667+
_double_to_<long>("height", height)
1668+
);
1669+
}),
1670+
"width"_a, "height"_a, PyFT2Image_init__doc__)
16291671
.def("draw_rect_filled", &PyFT2Image_draw_rect_filled,
16301672
"x0"_a, "y0"_a, "x1"_a, "y1"_a,
16311673
PyFT2Image_draw_rect_filled__doc__)

src/tri/_tri.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ py::tuple TriContourGenerator::create_contour(const double& level)
751751
Contour contour;
752752

753753
find_boundary_lines(contour, level);
754-
find_interior_lines(contour, level, false, false);
754+
find_interior_lines(contour, level, false);
755755

756756
return contour_line_to_segs_and_kinds(contour);
757757
}
@@ -766,8 +766,8 @@ py::tuple TriContourGenerator::create_filled_contour(const double& lower_level,
766766
Contour contour;
767767

768768
find_boundary_lines_filled(contour, lower_level, upper_level);
769-
find_interior_lines(contour, lower_level, false, true);
770-
find_interior_lines(contour, upper_level, true, true);
769+
find_interior_lines(contour, lower_level, false);
770+
find_interior_lines(contour, upper_level, true);
771771

772772
return contour_to_segs_and_kinds(contour);
773773
}
@@ -880,8 +880,7 @@ void TriContourGenerator::find_boundary_lines_filled(Contour& contour,
880880

881881
void TriContourGenerator::find_interior_lines(Contour& contour,
882882
const double& level,
883-
bool on_upper,
884-
bool filled)
883+
bool on_upper)
885884
{
886885
const Triangulation& triang = _triangulation;
887886
int ntri = triang.get_ntri();

src/tri/_tri.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -407,12 +407,10 @@ class TriContourGenerator final
407407
* intersect any boundary.
408408
* contour: Contour to add new lines to.
409409
* level: Contour level.
410-
* on_upper: Whether on upper or lower contour level.
411-
* filled: Whether contours are filled or not. */
410+
* on_upper: Whether on upper or lower contour level. */
412411
void find_interior_lines(Contour& contour,
413412
const double& level,
414-
bool on_upper,
415-
bool filled);
413+
bool on_upper);
416414

417415
/* Follow contour line around boundary of the Triangulation from the
418416
* specified TriEdge to its end which can be on either the lower or upper

0 commit comments

Comments
 (0)