Skip to content

Commit 23a8e65

Browse files
authored
try our own tile snapping (#51)
* try our own tile snapping * oops, should be 1.0 / scale * snap backdrop as well * better backdrop snapping * scale tile size with desktop scale but the checkerboard PNG still fails to render correctly * always use NN * debug and NN * Revert "scale tile size with desktop scale" This reverts commit f9fa2c3. * note high-dpi issues
1 parent 887070f commit 23a8e65

File tree

4 files changed

+50
-7
lines changed

4 files changed

+50
-7
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,15 @@ Clone and run:
263263

264264
## TODO
265265

266+
- add high-DPI support
267+
268+
for 2900% desktop scale (for example) we probably need to render our
269+
256x256 tiles as 128x128 gtk pixels
270+
271+
however, this seems to cause filtering problems, mysteriously, see
272+
https://github.com/jcupitt/vipsdisp/tree/add-high-dpi for a quick test
273+
hack
274+
266275
- skip unknown files on next / prev?
267276

268277
- need to add the test to next-image, not glob, since we can't test the

src/imagedisplay.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,9 +666,17 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
666666
paint.size.width = imagedisplay->paint_rect.width;
667667
paint.size.height = imagedisplay->paint_rect.height;
668668

669+
/* If there's no gtk snapping, we do our own based on the hardware pixel
670+
* size for the surface this snapshot will be rendered to.
671+
*/
672+
GtkNative *native = gtk_widget_get_native(widget);
673+
GdkSurface *surface = gtk_native_get_surface(native);
674+
double pixel_size = 1.0 / gdk_surface_get_scale_factor(surface);
675+
669676
if (imagedisplay->tilecache &&
670677
imagedisplay->tilecache->n_levels > 0)
671678
tilecache_snapshot(imagedisplay->tilecache, snapshot,
679+
pixel_size,
672680
imagedisplay->scale, imagedisplay->x, imagedisplay->y,
673681
&paint, imagedisplay->debug);
674682

src/tilecache.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -835,15 +835,41 @@ tilecache_draw_bounds(GtkSnapshot *snapshot,
835835
}
836836
}
837837

838+
#ifndef HAVE_GTK_SNAPSHOT_SET_SNAP
839+
/* Snap a graphene rect to a hardware pixel boundary on the output surface. We
840+
* need to do this if the gtk snap mechachanism is missing or we'll get thin
841+
* white lines on tile edges.
842+
*/
843+
static void
844+
tilecache_snap_rect_to_boundary(graphene_rect_t *bounds, double pixel_size)
845+
{
846+
double left = rint(bounds->origin.x * pixel_size) / pixel_size;
847+
double top = rint(bounds->origin.y * pixel_size) / pixel_size;
848+
double right =
849+
rint((bounds->origin.x + bounds->size.width) * pixel_size) / pixel_size;
850+
double bottom =
851+
rint((bounds->origin.y + bounds->size.height) * pixel_size) / pixel_size;
852+
853+
bounds->origin.x = left;
854+
bounds->origin.y = top;
855+
bounds->size.width = right - left;
856+
bounds->size.height = bottom - top;
857+
}
858+
#endif /*!HAVE_GTK_SNAPSHOT_SET_SNAP*/
859+
838860
/* Scale is how much the level0 image has been scaled, x/y is the position of
839-
* the top-left corner of the paint_rect area in the scaled image.
861+
* the top-left corner of @paint in the scaled image.
862+
*
863+
* @pixel_scale is gdk_surface_get_scale() for the surface this snapshot will
864+
* be rendered to.
840865
*
841-
* paint_rect is the pixel area in gtk coordinates that we paint in the widget.
866+
* @paint is the pixel area in gtk coordinates that we paint in the widget.
842867
*
843868
* Set debug to draw tile boundaries for debugging.
844869
*/
845870
void
846871
tilecache_snapshot(Tilecache *tilecache, GtkSnapshot *snapshot,
872+
double pixel_size,
847873
double scale, double x, double y, graphene_rect_t *paint, gboolean debug)
848874
{
849875
/* In debug mode, scale and offset so we can see tile clipping.
@@ -914,6 +940,9 @@ tilecache_snapshot(Tilecache *tilecache, GtkSnapshot *snapshot,
914940
/* Paint the backdrop.
915941
*/
916942
graphene_rect_t backdrop = *paint;
943+
#ifndef HAVE_GTK_SNAPSHOT_SET_SNAP
944+
tilecache_snap_rect_to_boundary(&backdrop, pixel_size);
945+
#endif /*!HAVE_GTK_SNAPSHOT_SET_SNAP*/
917946
gtk_snapshot_push_repeat(snapshot, &backdrop, NULL);
918947

919948
backdrop.origin.x = 0;
@@ -947,11 +976,7 @@ tilecache_snapshot(Tilecache *tilecache, GtkSnapshot *snapshot,
947976
bounds.size.height = tile->bounds0.height * scale;
948977

949978
#ifndef HAVE_GTK_SNAPSHOT_SET_SNAP
950-
/* Without set snap, we have to hide tile edges by expanding the
951-
* tile.
952-
*/
953-
bounds.size.width += 1;
954-
bounds.size.height += 1;
979+
tilecache_snap_rect_to_boundary(&bounds, pixel_size);
955980
#endif /*!HAVE_GTK_SNAPSHOT_SET_SNAP*/
956981

957982
gtk_snapshot_append_scaled_texture(snapshot,

src/tilecache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ Tilecache *tilecache_new();
110110
/* Render the tiles to a snapshot.
111111
*/
112112
void tilecache_snapshot(Tilecache *tilecache, GtkSnapshot *snapshot,
113+
double pixel_size,
113114
double scale, double x, double y, graphene_rect_t *paint, gboolean debug);
114115

115116
#endif /*__TILECACHE_H*/

0 commit comments

Comments
 (0)