Subject: Re: bug#37689: Fringe pixmaps, widgets, etc. look ridiculously tiny in hidpi screen

From: Carlos Pita <[email-masked]>
Date: Wed, 16 Oct 2019 13:31:06 -0300

> Please just call it WINDOW_FRAME_SCALE_FACTOR or FRAME_SCALE_FACTOR.
> WINDOW_SCALE_FACTOR implies that it could be different for different
> windows on the same frame.

Good point, I've changed the name to WINDOW_FRAME_SCALE_FACTOR.

I've a bad feeling towards the conditional hidden behind that macro,
though. It's necessary because WINDOW_LEFT/RIGHT_FRINGE_WIDTH are
being called in contexts where the rif is still unavailable; so
knowing of no other sensible default, I just defaulted to 1. Now,
there is a bad smell in these requests for geometry parameters in
places where the exact geometry may still be unknown (although I
believe geometry is indeed known because, even if there isn't a rif,
cursory debugging shows that there already is a frame in all
problematic cases). So either these usages asume geometry is not
dependent on the current screen or, less problematically and more
probably, the rif is being initialized too late. A careful inspection
of every use place is a lot of work (I might be doing some of it next
weekend, though) so for now I'm just returning a sane default so that
we can safely move forward.
From 6ce862360bc9369916a25c933bf4a84b989849b6 Mon Sep 17 00:00:00 2001
From: memeplex <[email-masked]>
Date: Wed, 16 Oct 2019 01:18:49 -0300
Subject: [PATCH] Make fringe honour scale factor in Cairo backend

* src/fringe.c: scale bitmap with and height
* src/xterm.c: set device scale.
* sec/window.h: scale WINDOW_LEFT/RIGHT_FRINGE_WIDTH macros
---
 src/fringe.c |  5 +++--
 src/window.h | 14 ++++++++++----
 src/xterm.c  |  2 ++
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/fringe.c b/src/fringe.c
index 22f3bdc..5242e84 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -563,6 +563,7 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
   int period;
   int face_id = DEFAULT_FACE_ID;
   int offset, header_line_height;
+  double scale = FRAME_RIF (f)->get_scale_factor (f);
 
   p.overlay_p = (overlay & 1) == 1;
   p.cursor_p = (overlay & 2) == 2;
@@ -602,9 +603,9 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
 
   p.which = which;
   p.bits = fb->bits;
-  p.wd = fb->width;
+  p.wd = fb->width * scale;
 
-  p.h = fb->height;
+  p.h = fb->height * scale;
   p.dh = (period > 0 ? (p.y % period) : 0);
   p.h -= p.dh;
 
diff --git a/src/window.h b/src/window.h
index 71946a5..7937d1e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -827,16 +827,22 @@ #define WINDOW_MARGINS_WIDTH(W)			\
   (WINDOW_LEFT_MARGIN_WIDTH (W)			\
    + WINDOW_RIGHT_MARGIN_WIDTH (W))
 
+#define WINDOW_SCALE_FACTOR(W)							\
+  (FRAME_RIF (WINDOW_XFRAME (W)) == 0 ? 1					\
+   : FRAME_RIF (WINDOW_XFRAME (W))->get_scale_factor (WINDOW_XFRAME (W)))
+
 /* Pixel-widths of fringes.  */
 #define WINDOW_LEFT_FRINGE_WIDTH(W)			\
-  (W->left_fringe_width >= 0				\
+  ((W->left_fringe_width >= 0				\
    ? W->left_fringe_width				\
-   : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
+   : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))	\
+   * WINDOW_SCALE_FACTOR (W))
 
 #define WINDOW_RIGHT_FRINGE_WIDTH(W)			\
-  (W->right_fringe_width >= 0				\
+  ((W->right_fringe_width >= 0				\
    ? W->right_fringe_width				\
-   : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
+   : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))	\
+   * WINDOW_SCALE_FACTOR (W))
 
 #define WINDOW_FRINGES_WIDTH(W)		\
   (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
diff --git a/src/xterm.c b/src/xterm.c
index 67253a6..bf1aba2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -608,6 +608,7 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
 		 int dest_x, int dest_y, bool overlay_p)
 {
   cairo_t *cr = x_begin_cr_clip (f, gc);
+  double scale = FRAME_RIF (f)->get_scale_factor (f);
 
   if (overlay_p)
     cairo_rectangle (cr, dest_x, dest_y, width, height);
@@ -622,6 +623,7 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
 
   cairo_surface_t *surface;
   cairo_pattern_get_surface (image, &surface);
+  cairo_surface_set_device_scale (surface, 1. / scale, 1. / scale);
   cairo_format_t format = cairo_image_surface_get_format (surface);
   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
     {
-- 
2.20.1