8000 Fix MSVC cast warnings by QuLogic · Pull Request #28967 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Fix MSVC cast warnings #28967

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

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions doc/api/next_api_changes/deprecations/28967-ES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Passing floating-point values to ``RendererAgg.draw_text_image``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Any floating-point values passed to the *x* and *y* parameters were truncated to integers
silently. This behaviour is now deprecated, and only `int` values should be used.

Passing floating-point values to ``FT2Image``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Any floating-point values passed to the `.FT2Image` constructor, or the *x0*, *y0*, *x1*,
and *y1* parameters of `.FT2Image.draw_rect_filled` were truncated to integers silently.
This behaviour is now deprecated, and only `int` values should be used.
6 changes: 3 additions & 3 deletions lib/matplotlib/_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
w = xmax - xmin
h = ymax - ymin - self.box.depth
d = ymax - ymin - self.box.height
image = FT2Image(np.ceil(w), np.ceil(h + max(d, 0)))
image = FT2Image(int(np.ceil(w)), int(np.ceil(h + max(d, 0))))

# Ideally, we could just use self.glyphs and self.rects here, shifting
# their coordinates by (-xmin, -ymin), but this yields slightly
Expand All @@ -163,7 +163,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:

for ox, oy, info in shifted.glyphs:
info.font.draw_glyph_to_bitmap(
image, ox, oy - info.metrics.iceberg, info.glyph,
image, int(ox), int(oy - info.metrics.iceberg), info.glyph,
antialiased=antialiased)
for x1, y1, x2, y2 in shifted.rects:
height = max(int(y2 - y1) - 1, 0)
Expand All @@ -172,7 +172,7 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
y = int(center - (height + 1) / 2)
else:
y = int(y1)
image.draw_rect_filled(int(x1), y, np.ceil(x2), y + height)
image.draw_rect_filled(int(x1), y, int(np.ceil(x2)), y + height)
return RasterParse(0, 0, w, h + d, d, image)


Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/ft2font.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class FT2Font(Buffer):
def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ...
def clear(self) -> None: ...
def draw_glyph_to_bitmap(
self, image: FT2Image, x: float, y: float, glyph: Glyph, antialiased: bool = ...
self, image: FT2Image, x: int, y: int, glyph: Glyph, antialiased: bool = ...
) -> None: ...
def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ...
def get_bitmap_offset(self) -> tuple[int, int]: ...
Expand Down Expand Up @@ -281,8 +281,8 @@ class FT2Font(Buffer):

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

Expand Down
25 changes: 16 additions & 9 deletions src/_backend_agg.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face,
agg::trans_affine hatch_trans;
hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
hatch_trans *= agg::trans_affine_scaling(static_cast<double>(hatch_size),
static_cast<double>(hatch_size));
hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
hatch_path_curve_t hatch_path_curve(hatch_path_trans);
hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);
Expand Down Expand Up @@ -739,16 +740,19 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in

set_clipbox(gc.cliprect, theRasterizer);

auto image_height = static_cast<double>(image.shape(0)),
image_width = static_cast<double>(image.shape(1));

agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(0, -image.shape(0));
mtx *= agg::trans_affine_translation(0, -image_height);
mtx *= agg::trans_affine_rotation(-angle * (agg::pi / 180.0));
mtx *= agg::trans_affine_translation(x, y);

agg::path_storage rect;
rect.move_to(0, 0);
rect.line_to(image.shape(1), 0);
rect.line_to(image.shape(1), image.shape(0));
rect.line_to(0, image.shape(0));
rect.line_to(image_width, 0);
rect.line_to(image_width, image_height);
rect.line_to(0, image_height);
rect.line_to(0, 0);
agg::conv_transform<agg::path_storage> rect2(rect, mtx);

Expand Down Expand Up @@ -842,12 +846,15 @@ inline void RendererAgg::draw_image(GCAgg &gc,
agg::trans_affine mtx;
agg::path_storage rect;

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

mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image_height)));

rect.move_to(0, 0);
rect.line_to(image.shape(1), 0);
rect.line_to(image.shape(1), image.shape(0));
rect.line_to(0, image.shape(0));
rect.line_to(image_width, 0);
rect.line_to(image_width, image_height);
rect.line_to(0, image_height);
rect.line_to(0, 0);

agg::conv_transform<agg::path_storage> rect2(rect, mtx);
Expand Down
30 changes: 28 additions & 2 deletions src/_backend_agg_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,37 @@
static void
PyRendererAgg_draw_text_image(RendererAgg *self,
py::array_t<agg::int8u, py::array::c_style | py::array::forcecast> image_obj,
double x,
double y,
std::variant<double, int> vx,
std::variant<double, int> vy,
double angle,
GCAgg &gc)
{
int x, y;

if (auto value = std::get_if<double>(&vx)) {
auto api = py::module_::import("matplotlib._api");
auto warn = api.attr("warn_deprecated");

Check warning on line 70 in src/_backend_agg_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

src/_backend_agg_wrapper.cpp#L69-L70

Added lines #L69 - L70 were not covered by tests
warn("since"_a="3.10", "name"_a="x", "obj_type"_a="parameter as float",
"alternative"_a="int(x)");
x = static_cast<int>(*value);
} else if (auto value = std::get_if<int>(&vx)) {
x = *value;
} else {
throw std::runtime_error("Should not happen");
}

Check warning on line 78 in src/_backend_agg_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

src/_backend_agg_wrapper.cpp#L78

Added line #L78 was not covered by tests

if (auto value = std::get_if<double>(&vy)) {
auto api = py::module_::import("matplotlib._api");
auto warn = api.attr("warn_deprecated");

Check warning on line 82 in src/_backend_agg_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

src/_backend_agg_wrapper.cpp#L81-L82

Added lines #L81 - L82 were not covered by tests
warn("since"_a="3.10", "name"_a="y", "obj_type"_a="parameter as float",
"alternative"_a="int(y)");
y = static_cast<int>(*value);
} else if (auto value = std::get_if<int>(&vy)) {
y = *value;
} else {
throw std::runtime_error("Should not happen");
}

Check warning on line 90 in src/_backend_agg_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

src/_backend_agg_wrapper.cpp#L90

Added line #L90 was not covered by tests

// TODO: This really shouldn't be mutable, but Agg's renderer buffers aren't const.
auto image = image_obj.mutable_unchecked<2>();

Expand Down
3 changes: 2 additions & 1 deletion src/_image_resample.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ class span_conv_alpha
{
if (m_alpha != 1.0) {
do {
span->a *= m_alpha;
span->a = static_cast<typename color_type::value_type>(
static_cast<typename color_type::calc_type>(span->a) * m_alpha);
++span;
} while (--len);
}
Expand Down
50 changes: 46 additions & 4 deletions src/ft2font_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@
namespace py = pybind11;
using namespace pybind11::literals;

template <typename T>
using double_or_ = std::variant<double, T>;

template <typename T>
static T
_double_to_(const char *name, double_or_<T> &var)
{
if (auto value = std::get_if<double>(&var)) {
auto api = py::module_::import("matplotlib._api");

Check warning on line 24 in src/ft2font_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

src/ft2font_wrapper.cpp#L24

Added line #L24 was not covered by tests
auto warn = api.attr("warn_deprecated");
warn("since"_a="3.10", "name"_a=name, "obj_type"_a="parameter as float",
"alternative"_a="int({})"_s.format(name));
return static_cast<T>(*value);
} else if (auto value = std::get_if<T>(&var)) {
return *value;
} else {
// pybind11 will have only allowed types that match the variant, so this `else`
// can't happen. We only have this case because older macOS doesn't support
// `std::get` and using the conditional `std::get_if` means an `else` to silence
// compiler warnings about "unhandled" cases.
throw std::runtime_error("Should not happen");
}
}

/**********************************************************************
* Enumerations
* */
Expand Down Expand Up @@ -227,8 +251,15 @@
)""";

static void
PyFT2Image_draw_rect_filled(FT2Image *self, double x0, double y0, double x1, double y1)
PyFT2Image_draw_rect_filled(FT2Image *self,
double_or_<long> vx0, double_or_<long> vy0,
double_or_<long> vx1, double_or_<long> vy1)
{
auto x0 = _double_to_<long>("x0", vx0);
auto y0 = _double_to_<long>("y0", vy0);
auto x1 = _double_to_<long>("x1", vx1);
auto y1 = _double_to_<long>("y1", vy1);

self->draw_rect_filled(x0, y0, x1, y1);
}

Expand Down Expand Up @@ -920,7 +951,7 @@
----------
image : FT2Image
The image buffer on which to draw the glyph.
x, y : float
x, y : int
The pixel location at which to draw the glyph.
glyph : Glyph
The glyph to draw.
Expand All @@ -933,9 +964,13 @@
)""";

static void
PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, FT2Image &image, double xd, double yd,
PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, FT2Image &image,
double_or_<int> vxd, double_or_<int> vyd,
PyGlyph *glyph, bool antialiased = true)
{
auto xd = _double_to_<int>("x", vxd);
auto yd = _double_to_<int>("y", vyd);

self->x->draw_glyph_to_bitmap(image, xd, yd, glyph->glyphInd, antialiased);
}

Expand Down Expand Up @@ -1625,7 +1660,14 @@

py::class_<FT2Image>(m, "FT2Image", py::is_final(), py::buffer_protocol(),
PyFT2Image__doc__)
.def(py::init<double, double>(), "width"_a, "height"_a, PyFT2Image_init__doc__)
.def(py::init(
[](double_or_<long> width, double_or_<long> height) {
return new FT2Image(
_double_to_<long>("width", width),
_double_to_<long>("height", height)
);
}),
"width"_a, "height"_a, PyFT2Image_init__doc__)
.def("draw_rect_filled", &PyFT2Image_draw_rect_filled,
"x0"_a, "y0"_a, "x1"_a, "y1"_a,
PyFT2Image_draw_rect_filled__doc__)
Expand Down
9 changes: 4 additions & 5 deletions src/tri/_tri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ py::tuple TriContourGenerator::create_contour(const double& level)
Contour contour;

find_boundary_lines(contour, level);
find_interior_lines(contour, level, false, false);
find_interior_lines(contour, level, false);

return contour_line_to_segs_and_kinds(contour);
}
Expand All @@ -766,8 +766,8 @@ py::tuple TriContourGenerator::create_filled_contour(const double& lower_level,
Contour contour;

find_boundary_lines_filled(contour, lower_level, upper_level);
find_interior_lines(contour, lower_level, false, true);
find_interior_lines(contour, upper_level, true, true);
find_interior_lines(contour, lower_level, false);
find_interior_lines(contour, upper_level, true);

return contour_to_segs_and_kinds(contour);
}
Expand Down Expand Up @@ -880,8 +880,7 @@ void TriContourGenerator::find_boundary_lines_filled(Contour& contour,

void TriContourGenerator::find_interior_lines(Contour& contour,
const double& level,
bool on_upper,
bool filled)
bool on_upper)
{
const Triangulation& triang = _triangulation;
int ntri = triang.get_ntri();
Expand Down
6 changes: 2 additions & 4 deletions src/tri/_tri.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,12 +407,10 @@ class TriContourGenerator final
* intersect any boundary.
* contour: Contour to add new lines to.
* level: Contour level.
* on_upper: Whether on upper or lower contour level.
* filled: Whether contours are filled or not. */
* on_upper: Whether on upper or lower contour level. */
void find_interior_lines(Contour& contour,
const double& level,
bool on_upper,
bool filled);
bool on_upper);

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