@@ -79,6 +79,11 @@ struct _Imagedisplay {
7979 double scale ;
8080 double x , y ;
8181
82+ /* The size of physical display pixels in gtk coordinates, eg. for a 200%
83+ * desktop this would be 0.5.
84+ */
85+ double pixel_size ;
86+
8287 /* Draw the screen in debug mode.
8388 */
8489 gboolean debug ;
@@ -126,6 +131,9 @@ enum {
126131 */
127132 PROP_DEBUG ,
128133
134+ /* Read out display density with this.
135+ */
136+ PROP_PIXEL_SIZE ,
129137};
130138
131139enum {
@@ -476,6 +484,8 @@ imagedisplay_set_property(GObject *object,
476484{
477485 Imagedisplay * imagedisplay = (Imagedisplay * ) object ;
478486
487+ double d ;
488+
479489#ifdef DEBUG
480490 {
481491 g_autofree char * str = g_strdup_value_contents (value );
@@ -573,6 +583,15 @@ imagedisplay_set_property(GObject *object,
573583 gtk_widget_queue_draw (GTK_WIDGET (imagedisplay ));
574584 break ;
575585
586+ case PROP_PIXEL_SIZE :
587+ d = g_value_get_double (value );
588+ if (imagedisplay -> pixel_size != d ) {
589+ imagedisplay -> pixel_size = d ;
590+ imagedisplay_layout (imagedisplay );
591+ gtk_widget_queue_draw (GTK_WIDGET (imagedisplay ));
592+ }
593+ break ;
594+
576595 default :
577596 G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
578597 break ;
@@ -632,6 +651,10 @@ imagedisplay_get_property(GObject *object,
632651 g_value_set_boolean (value , imagedisplay -> debug );
633652 break ;
634653
654+ case PROP_PIXEL_SIZE :
655+ g_value_set_double (value , imagedisplay -> pixel_size );
656+ break ;
657+
635658 default :
636659 G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
637660 break ;
@@ -649,40 +672,49 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
649672
650673 GTK_WIDGET_CLASS (imagedisplay_parent_class )-> snapshot (widget , snapshot );
651674
652- #ifdef HAVE_GTK_SNAPSHOT_SET_SNAP
653- gtk_snapshot_set_snap (snapshot , GSK_RECT_SNAP_ROUND );
654- #endif /*HAVE_GTK_SNAPSHOT_SET_SNAP*/
655-
656675 /* Clip to the widget area, or we may paint over the display control
657676 * bar.
658677 */
659678 gtk_snapshot_push_clip (snapshot ,
660679 & GRAPHENE_RECT_INIT (0 , 0 ,
661680 gtk_widget_get_width (widget ), gtk_widget_get_height (widget )));
662681
663- graphene_rect_t paint ;
664- paint .origin .x = imagedisplay -> paint_rect .left ;
665- paint .origin .y = imagedisplay -> paint_rect .top ;
666- paint .size .width = imagedisplay -> paint_rect .width ;
667- paint .size .height = imagedisplay -> paint_rect .height ;
682+ gtk_snapshot_save (snapshot );
668683
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.
684+ /* This can change on each repaint as windows are dragged.
671685 */
672686 GtkNative * native = gtk_widget_get_native (widget );
673687 GdkSurface * surface = gtk_native_get_surface (native );
674- double pixel_size = 1.0 / gdk_surface_get_scale_factor (surface );
688+ double pixel_size = 1.0 / gdk_surface_get_scale (surface );
689+ g_object_set (imagedisplay , "pixel-size" , pixel_size , NULL );
690+
691+ #ifdef HAVE_GTK_SNAPSHOT_SET_SNAP
692+ gtk_snapshot_set_snap (snapshot , GSK_RECT_SNAP_ROUND );
693+ #endif /*HAVE_GTK_SNAPSHOT_SET_SNAP*/
694+
695+ gtk_snapshot_scale (snapshot , pixel_size , pixel_size );
696+
697+ graphene_rect_t paint ;
698+ paint .origin .x = imagedisplay -> paint_rect .left / pixel_size ;
699+ paint .origin .y = imagedisplay -> paint_rect .top / pixel_size ;
700+ paint .size .width = imagedisplay -> paint_rect .width / pixel_size ;
701+ paint .size .height = imagedisplay -> paint_rect .height / pixel_size ;
675702
676703 if (imagedisplay -> tilecache &&
677704 imagedisplay -> tilecache -> n_levels > 0 )
678705 tilecache_snapshot (imagedisplay -> tilecache , snapshot ,
679- pixel_size ,
680- imagedisplay -> scale , imagedisplay -> x , imagedisplay -> y ,
706+ imagedisplay -> scale / pixel_size ,
707+ imagedisplay -> x / pixel_size ,
708+ imagedisplay -> y / pixel_size ,
681709 & paint , imagedisplay -> debug );
682710
683- // draw any overlays
711+ // undo snap and scale
712+ gtk_snapshot_restore (snapshot );
713+
714+ // draw any overlays back in the regular coordinate space
684715 imagedisplay_overlay_snapshot (imagedisplay , snapshot );
685716
717+ // end of clip
686718 gtk_snapshot_pop (snapshot );
687719}
688720
@@ -828,6 +860,13 @@ imagedisplay_class_init(ImagedisplayClass *class)
828860 FALSE,
829861 G_PARAM_READWRITE ));
830862
863+ g_object_class_install_property (gobject_class , PROP_PIXEL_SIZE ,
864+ g_param_spec_double ("pixel-size" ,
865+ _ ("Pixel size" ),
866+ _ ("Size of hardware display pixels in gtk coordinates" ),
867+ 0.0 , 10.0 , 0.0 ,
868+ G_PARAM_READWRITE ));
869+
831870 g_object_class_override_property (gobject_class ,
832871 PROP_HADJUSTMENT , "hadjustment" );
833872 g_object_class_override_property (gobject_class ,
0 commit comments