From ab61cbe79cd2350e2fd082aa44adac195d7f7b69 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 15 Oct 2021 00:44:51 -0400 Subject: [PATCH] Convert macosx backend to use device_pixel_ratio This was not originally implemented in #19126, but causes some inconsistencies with other backends. This also sets the initial scale as implemented in #18274. --- lib/matplotlib/backends/backend_macosx.py | 19 +++------- src/_macosx.m | 42 ++++++++++++++++++----- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index a692504afb23..25619104134f 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -30,14 +30,6 @@ def __init__(self, figure): FigureCanvasBase.__init__(self, figure) width, height = self.get_width_height() _macosx.FigureCanvas.__init__(self, width, height) - self._dpi_ratio = 1.0 - - def _set_device_scale(self, value): - if self._dpi_ratio != value: - # Need the new value in place before setting figure.dpi, which - # will trigger a resize - self._dpi_ratio, old_value = value, self._dpi_ratio - self.figure.dpi = self.figure.dpi / old_value * self._dpi_ratio def set_cursor(self, cursor): # docstring inherited @@ -60,12 +52,11 @@ def blit(self, bbox=None): self.draw_idle() def resize(self, width, height): - dpi = self.figure.dpi - width /= dpi - height /= dpi - self.figure.set_size_inches(width * self._dpi_ratio, - height * self._dpi_ratio, - forward=False) + # Size from macOS is logical pixels, dpi is physical. + scale = self.figure.dpi / self.device_pixel_ratio + width /= scale + height /= scale + self.figure.set_size_inches(width, height, forward=False) FigureCanvasBase.resize_event(self) self.draw_idle() diff --git a/src/_macosx.m b/src/_macosx.m index ef999ca9ea2d..9eeeab46eb5b 100755 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -237,6 +237,8 @@ @interface View : NSView } - (void)dealloc; - (void)drawRect:(NSRect)rect; +- (void)updateDevicePixelRatio:(double)scale; +- (void)windowDidChangeBackingProperties:(NSNotification*)notification; - (void)windowDidResize:(NSNotification*)notification; - (View*)initWithFrame:(NSRect)rect; - (void)setCanvas: (PyObject*)newCanvas; @@ -706,6 +708,7 @@ static CGFloat _get_device_scale(CGContextRef cr) [window setDelegate: view]; [window makeFirstResponder: view]; [[window contentView] addSubview: view]; + [view updateDevicePixelRatio: [window backingScaleFactor]]; return 0; } @@ -801,6 +804,9 @@ static CGFloat _get_device_scale(CGContextRef cr) Window* window = self->window; if(window) { + CGFloat device_pixel_ratio = [window backingScaleFactor]; + width /= device_pixel_ratio; + height /= device_pixel_ratio; // 36 comes from hard-coded size of toolbar later in code [window setContentSize: NSMakeSize(width, height + 36.)]; } @@ -1654,15 +1660,6 @@ -(void)drawRect:(NSRect)rect CGContextRef cr = [[NSGraphicsContext currentContext] CGContext]; - double new_device_scale = _get_device_scale(cr); - - if (device_scale != new_device_scale) { - device_scale = new_device_scale; - if (!PyObject_CallMethod(canvas, "_set_device_scale", "d", device_scale, NULL)) { - PyErr_Print(); - goto exit; - } - } if (!(renderer = PyObject_CallMethod(canvas, "_draw", "", NULL)) || !(renderer_buffer = PyObject_GetAttrString(renderer, "_renderer"))) { PyErr_Print(); @@ -1683,6 +1680,33 @@ -(void)drawRect:(NSRect)rect PyGILState_Release(gstate); } +- (void)updateDevicePixelRatio:(double)scale +{ + PyObject* change = NULL; + PyGILState_STATE gstate = PyGILState_Ensure(); + + device_scale = scale; + if (!(change = PyObject_CallMethod(canvas, "_set_device_pixel_ratio", "d", device_scale, NULL))) { + PyErr_Print(); + goto exit; + } + if (PyObject_IsTrue(change)) { + [self setNeedsDisplay: YES]; + } + + exit: + Py_XDECREF(change); + + PyGILState_Release(gstate); +} + +- (void)windowDidChangeBackingProperties:(NSNotification *)notification +{ + Window* window = [notification object]; + + [self updateDevicePixelRatio: [window backingScaleFactor]]; +} + - (void)windowDidResize: (NSNotification*)notification { int width, height; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy