Commit 3f077ec3 authored by Christoph Reiter's avatar Christoph Reiter 🐍

quartz: fix pixelated image surfaces in retina/hidpi mode

gtk+ currently depends on the scaling factor and the cairo device scale
of both the backend surfaces and image surfaces to be equal.

Until now we didn't apply a cairo device scale at all and depended on the
automatic scaling of CGContexts. This works when drawing with cairo but
fails in case of image surfaces, which get requested at a too small size.

To make the quartz backend behave more like the X11 one, set the cairo device
scale on the surface in gdk_quartz_ref_cairo_surface(). As this conflicts
with the default scaling done by CGContext (we would get double scaling)
undo the CGContext scaling using CGContextScaleCTM().

This patch is based on the following patches by Brion Vibber:
    https://bugzilla.gnome.org/show_bug.cgi?id=740199#c4
    https://bugs.freedesktop.org/show_bug.cgi?id=69796#c4

https://bugzilla.gnome.org/show_bug.cgi?id=763779
parent 3a584882
......@@ -121,6 +121,7 @@ gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
gboolean antialias)
{
CGContextRef cg_context;
CGSize scale;
if (GDK_WINDOW_DESTROYED (window_impl->wrapper))
return NULL;
......@@ -141,6 +142,12 @@ gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
CGContextSaveGState (cg_context);
CGContextSetAllowsAntialiasing (cg_context, antialias);
/* Undo the default scaling transform, since we apply our own
* in gdk_quartz_ref_cairo_surface () */
scale = CGContextConvertSizeToDeviceSpace (cg_context,
CGSizeMake (1.0, 1.0));
CGContextScaleCTM (cg_context, 1.0 / scale.width, 1.0 / scale.height);
return cg_context;
}
......@@ -317,10 +324,14 @@ gdk_quartz_ref_cairo_surface (GdkWindow *window)
if (!impl->cairo_surface)
{
gint scale = gdk_window_get_scale_factor (impl->wrapper);
impl->cairo_surface =
gdk_quartz_create_cairo_surface (impl,
gdk_window_get_width (impl->wrapper),
gdk_window_get_height (impl->wrapper));
gdk_window_get_width (impl->wrapper) * scale,
gdk_window_get_height (impl->wrapper) * scale);
cairo_surface_set_device_scale (impl->cairo_surface, scale, scale);
}
else
cairo_surface_reference (impl->cairo_surface);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment