diff --git a/doc/api/next_api_changes/deprecations/21981-AL.rst b/doc/api/next_api_changes/deprecations/21981-AL.rst index 4c4d6535b5c6..5641f09e4991 100644 --- a/doc/api/next_api_changes/deprecations/21981-AL.rst +++ b/doc/api/next_api_changes/deprecations/21981-AL.rst @@ -1,4 +1,8 @@ ``RendererGTK3Cairo`` and ``RendererGTK4Cairo`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -... have been deprecated. Use ``RendererCairo`` instead, which has gained the -``set_context`` method. +... have been deprecated. Use ``RendererCairo`` instead, which has gained +the ``set_context`` method, which also auto-infers the size of the underlying +surface. + +``RendererCairo.set_ctx_from_surface`` and ``RendererCairo.set_width_height`` +have likewise been deprecated, in favor of ``set_context``. diff --git a/lib/matplotlib/backends/backend_cairo.py b/lib/matplotlib/backends/backend_cairo.py index 053db0aaf00d..b4dbe8172e38 100644 --- a/lib/matplotlib/backends/backend_cairo.py +++ b/lib/matplotlib/backends/backend_cairo.py @@ -134,15 +134,28 @@ def __init__(self, dpi): super().__init__() def set_context(self, ctx): - self.gc.ctx = _to_context(ctx) + surface = ctx.get_target() + if hasattr(surface, "get_width") and hasattr(surface, "get_height"): + size = surface.get_width(), surface.get_height() + elif hasattr(surface, "get_extents"): # GTK4 RecordingSurface. + ext = surface.get_extents() + size = ext.width, ext.height + else: # vector surfaces. + ctx.save() + ctx.reset_clip() + rect, *rest = ctx.copy_clip_rectangle_list() + if rest: + raise TypeError("Cannot infer surface size") + size = rect.width, rect.height + ctx.restore() + self.gc.ctx = ctx + self.width, self.height = size + @_api.deprecated("3.6", alternative="set_context") def set_ctx_from_surface(self, surface): self.gc.ctx = cairo.Context(surface) - # Although it may appear natural to automatically call - # `self.set_width_height(surface.get_width(), surface.get_height())` - # here (instead of having the caller do so separately), this would fail - # for PDF/PS/SVG surfaces, which have no way to report their extents. + @_api.deprecated("3.6") def set_width_height(self, width, height): self.width = width self.height = height @@ -474,9 +487,8 @@ def print_rgba(self, fobj): def _get_printed_image_surface(self): self._renderer.dpi = self.figure.dpi width, height = self.get_width_height() - self._renderer.set_width_height(width, height) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) - self._renderer.set_ctx_from_surface(surface) + self._renderer.set_context(cairo.Context(surface)) self.figure.draw(self._renderer) return surface @@ -516,8 +528,7 @@ def _save(self, fmt, fobj, *, orientation='portrait'): raise ValueError("Unknown format: {!r}".format(fmt)) self._renderer.dpi = self.figure.dpi - self._renderer.set_width_height(width_in_points, height_in_points) - self._renderer.set_ctx_from_surface(surface) + self._renderer.set_context(cairo.Context(surface)) ctx = self._renderer.gc.ctx if orientation == 'landscape': diff --git a/lib/matplotlib/backends/backend_gtk3cairo.py b/lib/matplotlib/backends/backend_gtk3cairo.py index bed912899675..1a532873a294 100644 --- a/lib/matplotlib/backends/backend_gtk3cairo.py +++ b/lib/matplotlib/backends/backend_gtk3cairo.py @@ -26,8 +26,6 @@ def on_draw_event(self, widget, ctx): self.get_style_context(), ctx, allocation.x, allocation.y, allocation.width, allocation.height) - self._renderer.set_width_height( - allocation.width * scale, allocation.height * scale) self._renderer.dpi = self.figure.dpi self.figure.draw(self._renderer) diff --git a/lib/matplotlib/backends/backend_gtk4cairo.py b/lib/matplotlib/backends/backend_gtk4cairo.py index 5a5b4c7e45b8..be4c915f2f32 100644 --- a/lib/matplotlib/backends/backend_gtk4cairo.py +++ b/lib/matplotlib/backends/backend_gtk4cairo.py @@ -27,8 +27,6 @@ def on_draw_event(self, widget, ctx): self.get_style_context(), ctx, allocation.x, allocation.y, allocation.width, allocation.height) - self._renderer.set_width_height( - allocation.width * scale, allocation.height * scale) self._renderer.dpi = self.figure.dpi self.figure.draw(self._renderer) diff --git a/lib/matplotlib/backends/backend_qtcairo.py b/lib/matplotlib/backends/backend_qtcairo.py index 7f77546b02cc..4c1adebe7cf0 100644 --- a/lib/matplotlib/backends/backend_qtcairo.py +++ b/lib/matplotlib/backends/backend_qtcairo.py @@ -21,8 +21,7 @@ def paintEvent(self, event): height = int(self.device_pixel_ratio * self.height()) if (width, height) != self._renderer.get_canvas_width_height(): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) - self._renderer.set_ctx_from_surface(surface) - self._renderer.set_width_height(width, height) + self._renderer.set_context(cairo.Context(surface)) self._renderer.dpi = self.figure.dpi self.figure.draw(self._renderer) buf = self._renderer.gc.ctx.get_target().get_data() diff --git a/lib/matplotlib/backends/backend_tkcairo.py b/lib/matplotlib/backends/backend_tkcairo.py index a132cab6b78e..a6951c03c65a 100644 --- a/lib/matplotlib/backends/backend_tkcairo.py +++ b/lib/matplotlib/backends/backend_tkcairo.py @@ -12,8 +12,7 @@ def draw(self): width = int(self.figure.bbox.width) height = int(self.figure.bbox.height) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) - self._renderer.set_ctx_from_surface(surface) - self._renderer.set_width_height(width, height) + self._renderer.set_context(cairo.Context(surface)) self._renderer.dpi = self.figure.dpi self.figure.draw(self._renderer) buf = np.reshape(surface.get_data(), (height, width, 4)) diff --git a/lib/matplotlib/backends/backend_wxcairo.py b/lib/matplotlib/backends/backend_wxcairo.py index 0ff10d9b27d7..e8a80434ff12 100644 --- a/lib/matplotlib/backends/backend_wxcairo.py +++ b/lib/matplotlib/backends/backend_wxcairo.py @@ -24,8 +24,7 @@ class FigureCanvasWxCairo(_FigureCanvasWxBase, FigureCanvasCairo): def draw(self, drawDC=None): size = self.figure.bbox.size.astype(int) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *size) - self._renderer.set_ctx_from_surface(surface) - self._renderer.set_width_height(*size) + self._renderer.set_context(cairo.Context(surface)) self._renderer.dpi = self.figure.dpi self.figure.draw(self._renderer) self.bitmap = wxcairo.BitmapFromImageSurface(surface)