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

From: Carlos Pita <[email-masked]>
Date: Wed, 16 Oct 2019 16:01:30 -0300

Improved the commit message to hopefully match CONTRIBUTING rules.
From eae482e5103b82642306e55c0c6fc985d46b36bb 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 (Bug#37689)

* src/fringe.c (draw_fringe_bitmap_1): Scale bitmap width and height.
* src/xterm.c (x_cr_draw_image): Set device scale.
* sec/window.h (WINDOW_FRAME_SCALE_FACTOR, WINDOW_LEFT_FRINGE_WIDTH)
(WINDOW_RIGHT_FRINGE_WIDTH): Add helper macro to scale result.
---
 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..ac66af8 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_FRAME_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_FRAME_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_FRAME_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