From 7eeac44cfb57772b244fad2c075e722459d04451 Mon Sep 17 00:00:00 2001 From: John Wiggins Date: Mon, 22 Feb 2021 16:57:30 +0100 Subject: [PATCH] Get the Qt Quartz backend working again --- enable/qt4/quartz.py | 95 +++++++++++--------------------------------- 1 file changed, 23 insertions(+), 72 deletions(-) diff --git a/enable/qt4/quartz.py b/enable/qt4/quartz.py index 6876bb646..7d99a9e93 100644 --- a/enable/qt4/quartz.py +++ b/enable/qt4/quartz.py @@ -7,10 +7,13 @@ # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! -import numpy as np +from PIL import Image, ImageQt + +# Qt imports. +from pyface.qt import QtCore, QtGui from kiva.api import Font -from kiva.quartz import get_mac_context, ABCGI +from kiva.quartz import ABCGI from .base_window import BaseWindow from .scrollbar import NativeScrollBar @@ -18,57 +21,8 @@ CompiledPath = ABCGI.CGMutablePath -class GraphicsContext(ABCGI.CGLayerContext): - def __init__(self, size_or_array, *args, **kwds): - gc = kwds.pop("window_gc", None) - if not gc: - # Create a tiny base context to spawn the CGLayerContext from. - # We are better off making our Layer from the window gc since - # the data formats will match and so it will be faster to draw the - # layer. - gc = ABCGI.CGBitmapContext((1, 1)) - if isinstance(size_or_array, np.ndarray): - # Initialize the layer with an image. - image = ABCGI.CGImage(size_or_array) - width = image.width - height = image.height - else: - # No initialization. - image = None - width, height = size_or_array - - super(GraphicsContext, self).__init__( - (width, height), gc, *args, **kwds - ) - if image is not None: - self.draw_image(image) - - @classmethod - def create_from_gc(klass, gc, size_or_array, *args, **kwds): - return klass(size_or_array, window_gc=gc, *args, **kwds) - - -class _WindowGraphicsContext(ABCGI.CGContextInABox): - def __init__(self, *args, **kwds): - super(_WindowGraphicsContext, self).__init__(*args, **kwds) - self._begun = False - - def begin(self): - if self._begun: - return - self.save_state() - self.translate_ctm(0, self.height()) - self.scale_ctm(1.0, -1.0) - self._begun = True - - def end(self): - if self._begun: - self.restore_state() - self._begun = False - - @staticmethod - def create_from_gc(gc, size_or_array, *args, **kwds): - return GraphicsContext(size_or_array, window_gc=gc, *args, **kwds) +class GraphicsContext(ABCGI.CGBitmapContext): + pass class Window(BaseWindow): @@ -78,27 +32,24 @@ class Window(BaseWindow): # 'BaseWindow' interface ############################################### def _create_gc(self, size, pix_format=None): - if hasattr(self.control, "winId"): - # From the Qt 4.7 Documentation: - # "On Mac OS X, the type returned depends on which framework Qt was - # linked against. If Qt is using Carbon, the {WId} is actually - # an HIViewRef. If Qt is using Cocoa, {WId} is a pointer to - # an NSView." - # get_mac_context() only works on Cocoa. - self.dc = get_mac_context(self.control.winId()) - if self.dc: - gc = _WindowGraphicsContext(size, self.dc) - gc.begin() - return gc - raise NotImplementedError("Only Qt built against Cocoa is supported") + gc = GraphicsContext(size) + gc.scale_ctm(self.base_pixel_scale, self.base_pixel_scale) + + return gc def _window_paint(self, event): - # Make sure end() is called so that the window's GC is not left in an - # odd state. - self._gc.end() - # Force a new gc to be created for the next paint() - self._gc = None - self.dc = None + if self.control is None: + return + + # self._gc is an image context + w = self._gc.width() + h = self._gc.height() + pilimage = Image.frombuffer("RGBA", (w, h), self._gc, + "raw", "RGBA", 0, 1) + image = ImageQt.toqimage(pilimage) + rect = QtCore.QRectF(0, 0, self.control.width(), self.control.height()) + painter = QtGui.QPainter(self.control) + painter.drawImage(rect, image) def font_metrics_provider():