Commit 63701479 authored by Michael Natterer's avatar Michael Natterer

app: make all pixbuf rendering in GimpViewRenderer HiDPI-aware

Request pixbufs in double size and cache the created surface instead
of the pixbuf. This affects rendering icons and image thumbnails.

All other rendering (which is most previews) is not ported yet, but
just lacks HiDPI quality, there are no actual bugs.
parent aaf8b8b5
......@@ -65,7 +65,7 @@ enum
struct _GimpViewRendererPrivate
{
cairo_pattern_t *pattern;
GdkPixbuf *pixbuf;
cairo_surface_t *icon_surface;
gchar *bg_icon_name;
GimpColorConfig *color_config;
......@@ -206,7 +206,7 @@ gimp_view_renderer_finalize (GObject *object)
g_clear_pointer (&renderer->priv->pattern, cairo_pattern_destroy);
g_clear_pointer (&renderer->surface, cairo_surface_destroy);
g_clear_object (&renderer->priv->pixbuf);
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
g_clear_pointer (&renderer->priv->bg_icon_name, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
......@@ -328,7 +328,7 @@ gimp_view_renderer_set_viewable (GimpViewRenderer *renderer,
return;
g_clear_pointer (&renderer->surface, cairo_surface_destroy);
g_clear_object (&renderer->priv->pixbuf);
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
gimp_view_renderer_free_color_transform (renderer);
......@@ -728,12 +728,19 @@ gimp_view_renderer_real_draw (GimpViewRenderer *renderer,
renderer->priv->needs_render = FALSE;
}
if (renderer->priv->pixbuf)
if (renderer->priv->icon_surface)
{
gint width = gdk_pixbuf_get_width (renderer->priv->pixbuf);
gint height = gdk_pixbuf_get_height (renderer->priv->pixbuf);
gint scale_factor = gtk_widget_get_scale_factor (widget);
gint width;
gint height;
gint x, y;
width = cairo_image_surface_get_width (renderer->priv->icon_surface);
height = cairo_image_surface_get_height (renderer->priv->icon_surface);
width /= scale_factor;
height /= scale_factor;
if (renderer->priv->bg_icon_name)
{
if (! renderer->priv->pattern)
......@@ -749,7 +756,7 @@ gimp_view_renderer_real_draw (GimpViewRenderer *renderer,
x = (available_width - width) / 2;
y = (available_height - height) / 2;
gdk_cairo_set_source_pixbuf (cr, renderer->priv->pixbuf, x, y);
cairo_set_source_surface (cr, renderer->priv->icon_surface, x, y);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);
}
......@@ -791,11 +798,12 @@ gimp_view_renderer_real_render (GimpViewRenderer *renderer,
GdkPixbuf *pixbuf;
GimpTempBuf *temp_buf;
const gchar *icon_name;
gint scale_factor = gtk_widget_get_scale_factor (widget);
pixbuf = gimp_viewable_get_pixbuf (renderer->viewable,
renderer->context,
renderer->width,
renderer->height);
renderer->width * scale_factor,
renderer->height * scale_factor);
if (pixbuf)
{
gimp_view_renderer_render_pixbuf (renderer, widget, pixbuf);
......@@ -884,7 +892,7 @@ gimp_view_renderer_render_temp_buf (GimpViewRenderer *renderer,
GimpViewBG inside_bg,
GimpViewBG outside_bg)
{
g_clear_object (&renderer->priv->pixbuf);
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
if (! renderer->surface)
renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
......@@ -912,6 +920,7 @@ gimp_view_renderer_render_pixbuf (GimpViewRenderer *renderer,
{
GimpColorTransform *transform;
const Babl *format;
gint scale_factor;
g_clear_pointer (&renderer->surface, cairo_surface_destroy);
......@@ -949,13 +958,19 @@ gimp_view_renderer_render_pixbuf (GimpViewRenderer *renderer,
dest += dest_stride;
}
g_clear_object (&renderer->priv->pixbuf);
renderer->priv->pixbuf = new;
pixbuf = new;
}
else
{
g_set_object (&renderer->priv->pixbuf, pixbuf);
g_object_ref (pixbuf);
}
scale_factor = gtk_widget_get_scale_factor (widget);
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
renderer->priv->icon_surface =
gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
g_object_unref (pixbuf);
}
void
......@@ -964,41 +979,49 @@ gimp_view_renderer_render_icon (GimpViewRenderer *renderer,
const gchar *icon_name)
{
GdkPixbuf *pixbuf;
gint scale_factor;
gint width;
gint height;
g_return_if_fail (GIMP_IS_VIEW_RENDERER (renderer));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (icon_name != NULL);
g_clear_object (&renderer->priv->pixbuf);
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
g_clear_pointer (&renderer->surface, cairo_surface_destroy);
scale_factor = gtk_widget_get_scale_factor (widget);
pixbuf = gimp_widget_load_icon (widget, icon_name,
MIN (renderer->width, renderer->height));
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
if (width > renderer->width || height > renderer->height)
if (width > renderer->width * scale_factor ||
height > renderer->height * scale_factor)
{
GdkPixbuf *scaled_pixbuf;
gimp_viewable_calc_preview_size (width, height,
renderer->width, renderer->height,
renderer->width * scale_factor,
renderer->height * scale_factor,
TRUE, 1.0, 1.0,
&width, &height,
NULL);
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
width, height,
width * scale_factor,
height * scale_factor,
GDK_INTERP_BILINEAR);
g_object_unref (pixbuf);
pixbuf = scaled_pixbuf;
}
renderer->priv->pixbuf = pixbuf;
g_clear_pointer (&renderer->priv->icon_surface, cairo_surface_destroy);
renderer->priv->icon_surface =
gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
g_object_unref (pixbuf);
}
GimpColorTransform *
......
......@@ -68,9 +68,13 @@ static void
gimp_view_renderer_imagefile_render (GimpViewRenderer *renderer,
GtkWidget *widget)
{
GdkPixbuf *pixbuf = gimp_view_renderer_get_frame_pixbuf (renderer, widget,
renderer->width,
renderer->height);
GdkPixbuf *pixbuf;
gint scale_factor = gtk_widget_get_scale_factor (widget);
gint width = renderer->width * scale_factor;
gint height = renderer->height * scale_factor;
pixbuf = gimp_view_renderer_get_frame_pixbuf (renderer, widget,
width, height);
if (! pixbuf)
{
......@@ -78,8 +82,7 @@ gimp_view_renderer_imagefile_render (GimpViewRenderer *renderer,
pixbuf = gimp_view_renderer_imagefile_get_icon (imagefile,
widget,
MIN (renderer->width,
renderer->height));
MAX (width, height));
}
if (pixbuf)
......@@ -179,9 +182,16 @@ gimp_view_renderer_imagefile_get_icon (GimpImagefile *imagefile,
}
}
if (! pixbuf && thumbnail->image_mimetype)
if (! pixbuf)
{
pixbuf = get_icon_for_mime_type (thumbnail->image_mimetype, size);
if (thumbnail->image_mimetype)
{
pixbuf = get_icon_for_mime_type (thumbnail->image_mimetype, size);
}
else if (thumbnail->image_state == GIMP_THUMB_STATE_FOLDER)
{
pixbuf = get_icon_for_mime_type ("inode/directory", size);
}
}
if (! pixbuf)
......
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