# HG changeset patch # User Zoltan Ivanfi # Date 1514485942 -3600 # Node ID 79b668de97df4018d9e378d0e606efec73ed69a5 # Parent 8ba86a100c537cc9c9c1295f7bcf922eb25cdfc1 Partially fix #561: Hi-DPI-aware rendering of images. Displayed images are no longer blurry on Hi-DPI displays, nor they have a grid artifact any more. Image overlays and thumbnails are not addresset yet and are still blurry. diff -r 8ba86a100c53 -r 79b668de97df src/renderer-tiles.c --- a/src/renderer-tiles.c Mon Jan 01 13:40:30 2018 +0100 +++ b/src/renderer-tiles.c Thu Dec 28 19:32:22 2017 +0100 @@ -147,6 +147,7 @@ gint x_scroll; /* allow local adjustment and mirroring */ gint y_scroll; + gint hidpi_scale; }; @@ -499,6 +500,25 @@ return PR_TILE_SIZE * PR_TILE_SIZE * 4 / 8; } +static void rt_hidpi_aware_draw( + RendererTiles *rt, + cairo_t *cr, + GdkPixbuf *pixbuf, + double x, + double y) +{ +#if GTK_CHECK_VERSION(3, 10, 0) + cairo_surface_t *surface; + surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, rt->hidpi_scale, NULL); + cairo_set_source_surface(cr, surface, x, y); + cairo_fill(cr); + cairo_surface_destroy(surface); +#else + gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); + cairo_fill(cr); +#endif +} + static void rt_tile_prepare(RendererTiles *rt, ImageTile *it) { PixbufRenderer *pr = rt->pr; @@ -511,7 +531,7 @@ CAIRO_CONTENT_COLOR, rt->tile_width, rt->tile_height); - size = pixmap_calc_size(surface); + size = pixmap_calc_size(surface) * rt->hidpi_scale * rt->hidpi_scale; rt_tile_free_space(rt, size, it); it->surface = surface; @@ -523,9 +543,9 @@ { GdkPixbuf *pixbuf; guint size; - pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, rt->tile_width, rt->tile_height); + pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, rt->hidpi_scale * rt->tile_width, rt->hidpi_scale * rt->tile_height); - size = gdk_pixbuf_get_rowstride(pixbuf) * rt->tile_height; + size = gdk_pixbuf_get_rowstride(pixbuf) * rt->tile_height * rt->hidpi_scale; rt_tile_free_space(rt, size, it); it->pixbuf = pixbuf; @@ -623,7 +643,7 @@ cairo_fill_preserve(cr); gdk_cairo_set_source_pixbuf(cr, od->pixbuf, px - rx, py - ry); - cairo_fill (cr); + cairo_fill(cr); cairo_destroy (cr); cr = gdk_cairo_create(od->window); @@ -881,7 +901,7 @@ static GdkPixbuf *rt_get_spare_tile(RendererTiles *rt) { - if (!rt->spare_tile) rt->spare_tile = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, rt->tile_width, rt->tile_height); + if (!rt->spare_tile) rt->spare_tile = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, rt->tile_width * rt->hidpi_scale, rt->tile_height * rt->hidpi_scale); return rt->spare_tile; } @@ -896,7 +916,7 @@ guchar *sp, *dp; guchar *ip, *spi, *dpi; gint i, j; - gint tw = rt->tile_width; + gint tw = rt->tile_width * rt->hidpi_scale; srs = gdk_pixbuf_get_rowstride(src); s_pix = gdk_pixbuf_get_pixels(src); @@ -932,7 +952,7 @@ guchar *sp, *dp; guchar *ip, *spi, *dpi; gint i, j; - gint th = rt->tile_height; + gint th = rt->tile_height * rt->hidpi_scale; srs = gdk_pixbuf_get_rowstride(src); s_pix = gdk_pixbuf_get_pixels(src); @@ -969,7 +989,7 @@ guchar *spi, *dpi; gint i, j; - gint tw = rt->tile_width; + gint tw = rt->tile_width * rt->hidpi_scale; srs = gdk_pixbuf_get_rowstride(src); s_pix = gdk_pixbuf_get_pixels(src); @@ -1005,8 +1025,8 @@ guchar *sp, *dp; guchar *dpi; gint i, j; - gint tw = rt->tile_width; - gint th = rt->tile_height; + gint tw = rt->tile_width * rt->hidpi_scale; + gint th = rt->tile_height * rt->hidpi_scale; srs = gdk_pixbuf_get_rowstride(src); s_pix = gdk_pixbuf_get_pixels(src); @@ -1041,7 +1061,7 @@ guchar *sp, *dp; guchar *spi, *dpi; gint i; - gint th = rt->tile_height; + gint th = rt->tile_height * rt->hidpi_scale; srs = gdk_pixbuf_get_rowstride(src); s_pix = gdk_pixbuf_get_pixels(src); @@ -1150,12 +1170,12 @@ if (st->blank) { cairo_set_source_rgb(cr, 0, 0, 0); + cairo_fill (cr); } else /* (pr->zoom == 1.0 || pr->scale == 1.0) */ { - gdk_cairo_set_source_pixbuf(cr, st->pixbuf, -it->x + st->x, -it->y + st->y); + rt_hidpi_aware_draw(rt, cr, st->pixbuf, -it->x + st->x, -it->y + st->y); } - cairo_fill (cr); cairo_destroy (cr); } } @@ -1356,8 +1376,8 @@ if (pr->image_width == 0 || pr->image_height == 0) return; - scale_x = (gdouble)pr->width / pr->image_width; - scale_y = (gdouble)pr->height / pr->image_height; + scale_x = rt->hidpi_scale * (gdouble)pr->width / pr->image_width; + scale_y = rt->hidpi_scale * (gdouble)pr->height / pr->image_height; pr_tile_coords_map_orientation(orientation, it->x, it->y, pr->width, pr->height, @@ -1369,6 +1389,13 @@ &pb_x, &pb_y, &pb_w, &pb_h); + src_x *= rt->hidpi_scale; + src_y *= rt->hidpi_scale; + pb_x *= rt->hidpi_scale; + pb_y *= rt->hidpi_scale; + pb_w *= rt->hidpi_scale; + pb_h *= rt->hidpi_scale; + switch (orientation) { gdouble tmp; @@ -1424,8 +1451,7 @@ cr = cairo_create(it->surface); cairo_rectangle (cr, x, y, w, h); - gdk_cairo_set_source_pixbuf(cr, it->pixbuf, 0, 0); - cairo_fill (cr); + rt_hidpi_aware_draw(rt, cr, it->pixbuf, 0, 0); cairo_destroy (cr); } } @@ -2164,6 +2190,12 @@ rt->stereo_off_x = 0; rt->stereo_off_y = 0; +#if GTK_CHECK_VERSION(3, 10, 0) + rt->hidpi_scale = gtk_widget_get_scale_factor(GTK_WIDGET(rt->pr)); +#else + rt->hidpi_scale = 1; +#endif + g_signal_connect(G_OBJECT(pr), "hierarchy-changed", G_CALLBACK(rt_hierarchy_changed_cb), rt); @@ -2174,6 +2206,7 @@ g_signal_connect(G_OBJECT(pr), "expose_event", G_CALLBACK(rt_expose_cb), rt); #endif + return (RendererFuncs *) rt; }