unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#37770: [PATCH] Expose scale factor through the redisplay interface
@ 2019-10-15 22:29 Carlos Pita
  2019-10-16  0:32 ` Carlos Pita
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Pita @ 2019-10-15 22:29 UTC (permalink / raw)
  To: 37770

[-- Attachment #1: Type: text/plain, Size: 1332 bytes --]

I need this in order to move forward #37689.

Besides I did some related changes proposed in #37752, which I'm no
closing in favor of this one.

Here is the commit message:

    * src/dispextern.h: add get_scale_factor API.
    * src/xterm.c:
      - Unify usages of xg_get_scale and x_get_scale_factor into a
        consolidated x_get_scale_factor that is exported by the rif.
      - Simplify scale inferring logic (see note below).
    * src/w32term.c:
      - Simplify w32_get_scale_factor in a similar way (see note).
      - Add it to the rif.
    * src/nsterm.m:
      - Just add NULL to the rif since there are no uses of any scale
        factor here. Clients are expected to interpret a missing API
        as meaning scale factor = 1.

    Note: both x_get_scale_factor and w32_get_scale_factor computed
    distinct scales for x and y by taking the ratio between effective
    resolution in each direction and a standard 96 dpi resolution.  Since
    this ratio is then truncated to an integer (the floor) it seems to me
    that there is no sensible possibility that these two numbers
    diverge. Moreover, modern toolkits report one number as scale factor
    and we need a common interface here. For those reasons I'm arbitrarily
    picking the horizontal scale factor as THE scale factor.

Best regards
--
Carlos

[-- Attachment #2: 0001-Expose-scale-factor-through-the-redisplay-interface.patch --]
[-- Type: text/x-patch, Size: 7080 bytes --]

From 494b2864e97d8035365b32079e0949a7633c3338 Mon Sep 17 00:00:00 2001
From: memeplex <carlosjosepita@gmail.com>
Date: Tue, 15 Oct 2019 19:14:03 -0300
Subject: [PATCH] Expose scale factor through the redisplay interface

* src/dispextern.h: add get_scale_factor API.
* src/xterm.c:
  - Unify usages of xg_get_scale and x_get_scale_factor into a
    consolidated x_get_scale_factor that is exported by the rif.
  - Simplify scale inferring logic (see note below).
* src/w32term.c:
  - Simplify w32_get_scale_factor in a similar way (see note).
  - Add it to the rif.
* src/nsterm.m:
  - Just add NULL to the rif since there are no uses of any scale
    factor here. Clients are expected to interpret a missing API
    as meaning scale factor = 1.

Note: both x_get_scale_factor and w32_get_scale_factor computed
distinct scales for x and y by taking the ratio between effective
resolution in each direction and a standard 96 dpi resolution.  Since
this ratio is then truncated to an integer (the floor) it seems to me
that there is no sensible possibility that these two numbers
diverge. Moreover, modern toolkits report one number as scale factor
and we need a common interface here. For those reasons I'm arbitrarily
picking the horizontal scale factor as THE scale factor.
---
 src/dispextern.h |  3 +++
 src/nsterm.m     |  1 +
 src/w32term.c    | 29 +++++++++++------------------
 src/xterm.c      | 41 ++++++++++++++++++-----------------------
 4 files changed, 33 insertions(+), 41 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0615b16..ec3c555 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+  /* Return the scale factor for the screen containing frame F.  */
+  unsigned (*get_scale_factor) (struct frame *f);
+
   /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
   void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
                               struct draw_fringe_bitmap_params *p);
diff --git a/src/nsterm.m b/src/nsterm.m
index 5583c61..8dddf1e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5087,6 +5087,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  0, /* get_scale_factor */
   ns_draw_fringe_bitmap,
   0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
   0, /* destroy_fringe_bitmap */
diff --git a/src/w32term.c b/src/w32term.c
index 9da0845..c898f17 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -304,20 +304,16 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
     }
 }
 
-static void
-w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
+static unsigned
+w32_get_scale_factor(struct frame *f)
 {
+  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   const int base_res = 96;
 
-  *scale_x = *scale_y = 1;
-
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
 }
 
 /*
@@ -334,12 +330,8 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
 static void
 w32_draw_underwave (struct glyph_string *s, COLORREF color)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-
-  int scale_x, scale_y;
-  w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
+  int scale = w32_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale, thickness = scale;
   int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
   Emacs_Rectangle wave_clip, string_clip, final_clip;
   RECT w32_final_clip, w32_string_clip;
@@ -348,7 +340,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -7192,6 +7184,7 @@ w32_make_rdb (char *xrm_option)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  w32_get_scale_factor,
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
diff --git a/src/xterm.c b/src/xterm.c
index 5d8b148..6000860 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3611,21 +3611,21 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
-static void
-x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
+static unsigned
+x_get_scale_factor(struct frame *f)
 {
+#ifdef USE_GTK
+  return xg_get_scale (f);
+#else
+  Display *disp = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo = x_display_info_for_display (disp);
   const int base_res = 96;
-  struct x_display_info * dpyinfo = x_display_info_for_display (disp);
-
-  *scale_x = *scale_y = 1;
 
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
+#endif /* USE_GTK */
 }
 
 /*
@@ -3641,27 +3641,21 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
 static void
 x_draw_underwave (struct glyph_string *s)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-
   /* Adjust for scale/HiDPI.  */
-  int scale_x, scale_y;
-
-  x_get_scale_factor (display, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
-
+  int scale = x_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale;
 #ifdef USE_CAIRO
   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 			  s->width, wave_height, wave_length);
 #else  /* not USE_CAIRO */
-  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
 
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -10557,7 +10551,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 {
   int modified_top, modified_left;
 #ifdef USE_GTK
-  int scale = xg_get_scale (f);
+  int scale = x_get_scale_factor (f);
 #endif
 
   if (change_gravity > 0)
@@ -13356,6 +13350,7 @@ x_activate_timeout_atimer (void)
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
     gui_fix_overlapping_area,
+    x_get_scale_factor,
     x_draw_fringe_bitmap,
 #ifdef USE_CAIRO
     x_cr_define_fringe_bitmap,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-15 22:29 bug#37770: [PATCH] Expose scale factor through the redisplay interface Carlos Pita
@ 2019-10-16  0:32 ` Carlos Pita
  2019-10-16  8:51   ` Robert Pluim
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Pita @ 2019-10-16  0:32 UTC (permalink / raw)
  To: 37770

[-- Attachment #1: Type: text/plain, Size: 471 bytes --]

I have updated my patch a bit:

1. Instead of setting the new API to NULL when the scale factor is
ignored or unsupported by the backend, I'm setting it to a dummy
function returning 1. This keeps backwards compatibility and is more
convenient for the user of the interface.

2. get_scale_factor now returns a double. Even though current scale
factors are integers, this is an interface that will better have to
make it through the forthcoming era of fractional scaling.

[-- Attachment #2: 0001-Expose-scale-factor-through-the-redisplay-interface.patch --]
[-- Type: text/x-patch, Size: 7619 bytes --]

From 5b6e276e3dd9b4cb06bcf0e21e99227b2134a8bf Mon Sep 17 00:00:00 2001
From: memeplex <carlosjosepita@gmail.com>
Date: Tue, 15 Oct 2019 19:14:03 -0300
Subject: [PATCH] Expose scale factor through the redisplay interface

* src/dispextern.h: add get_scale_factor API.
* src/xterm.c:
  - Unify usages of xg_get_scale and x_get_scale_factor into a
    consolidated x_get_scale_factor that is exported by the rif.
  - Simplify scale inferring logic (see note below).
* src/w32term.c:
  - Simplify w32_get_scale_factor in a similar way (see note).
  - Add it to the rif.
* src/nsterm.m:
  - Just add a dummy implementation that always return 1 to the rif,
    since there are no uses of any scale factor here.

Note 1: both x_get_scale_factor and w32_get_scale_factor computed
distinct scales for x and y by taking the ratio between effective
resolution in each direction and a standard 96 dpi resolution.  Since
this ratio is then truncated to an integer (the floor) it seems to me
that there is no sensible possibility that these two numbers
diverge. Moreover, modern toolkits report one number as scale factor
and we need a common interface here. For those reasons I'm arbitrarily
picking the horizontal scale factor as THE scale factor.

Note 2: I decided to let get_scale_factor return a double, even tough
factors currently in use are all integers AFAIK. This is in
anticipation of fractional scaling. I believe it's prudent to keep
the interface general in this regard.
---
 src/dispextern.h |  3 +++
 src/nsterm.m     |  6 ++++++
 src/w32term.c    | 29 +++++++++++------------------
 src/xterm.c      | 41 ++++++++++++++++++-----------------------
 4 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0615b16..b93e25f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+  /* Return the scale factor for the screen containing frame F.  */
+  double (*get_scale_factor) (struct frame *f);
+
   /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
   void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
                               struct draw_fringe_bitmap_params *p);
diff --git a/src/nsterm.m b/src/nsterm.m
index 5583c61..6e1b751 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2957,6 +2957,11 @@ so some key presses (TAB) are swallowed by the system.  */
 
    ========================================================================== */
 
+static double
+ns_get_scale_factor (struct frame *f)
+{
+  return 1;  // TODO do we need to do something else here?
+}
 
 extern int max_used_fringe_bitmap;
 static void
@@ -5087,6 +5092,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  ns_get_scale_factor,
   ns_draw_fringe_bitmap,
   0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
   0, /* destroy_fringe_bitmap */
diff --git a/src/w32term.c b/src/w32term.c
index 9da0845..6d430c6 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -304,20 +304,16 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
     }
 }
 
-static void
-w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
+static double
+w32_get_scale_factor(struct frame *f)
 {
+  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   const int base_res = 96;
 
-  *scale_x = *scale_y = 1;
-
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
 }
 
 /*
@@ -334,12 +330,8 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
 static void
 w32_draw_underwave (struct glyph_string *s, COLORREF color)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-
-  int scale_x, scale_y;
-  w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
+  double scale = w32_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale, thickness = scale;
   int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
   Emacs_Rectangle wave_clip, string_clip, final_clip;
   RECT w32_final_clip, w32_string_clip;
@@ -348,7 +340,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -7192,6 +7184,7 @@ w32_make_rdb (char *xrm_option)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  w32_get_scale_factor,
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
diff --git a/src/xterm.c b/src/xterm.c
index 5d8b148..67253a6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3611,21 +3611,21 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
-static void
-x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
+static double
+x_get_scale_factor(struct frame *f)
 {
+#ifdef USE_GTK
+  return xg_get_scale (f);
+#else
+  Display *disp = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo = x_display_info_for_display (disp);
   const int base_res = 96;
-  struct x_display_info * dpyinfo = x_display_info_for_display (disp);
-
-  *scale_x = *scale_y = 1;
 
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
+#endif /* USE_GTK */
 }
 
 /*
@@ -3641,27 +3641,21 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
 static void
 x_draw_underwave (struct glyph_string *s)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-
   /* Adjust for scale/HiDPI.  */
-  int scale_x, scale_y;
-
-  x_get_scale_factor (display, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
-
+  double scale = x_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale;
 #ifdef USE_CAIRO
   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 			  s->width, wave_height, wave_length);
 #else  /* not USE_CAIRO */
-  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
 
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -10557,7 +10551,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 {
   int modified_top, modified_left;
 #ifdef USE_GTK
-  int scale = xg_get_scale (f);
+  double scale = x_get_scale_factor (f);
 #endif
 
   if (change_gravity > 0)
@@ -13356,6 +13350,7 @@ x_activate_timeout_atimer (void)
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
     gui_fix_overlapping_area,
+    x_get_scale_factor,
     x_draw_fringe_bitmap,
 #ifdef USE_CAIRO
     x_cr_define_fringe_bitmap,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-16  0:32 ` Carlos Pita
@ 2019-10-16  8:51   ` Robert Pluim
  2019-10-16 16:12     ` Carlos Pita
  0 siblings, 1 reply; 11+ messages in thread
From: Robert Pluim @ 2019-10-16  8:51 UTC (permalink / raw)
  To: Carlos Pita; +Cc: 37770

>>>>> On Tue, 15 Oct 2019 21:32:25 -0300, Carlos Pita <carlosjosepita@gmail.com> said:

    Carlos> I have updated my patch a bit:
    Carlos> 1. Instead of setting the new API to NULL when the scale factor is
    Carlos> ignored or unsupported by the backend, I'm setting it to a dummy
    Carlos> function returning 1. This keeps backwards compatibility and is more
    Carlos> convenient for the user of the interface.

    Carlos> 2. get_scale_factor now returns a double. Even though current scale
    Carlos> factors are integers, this is an interface that will better have to
    Carlos> make it through the forthcoming era of fractional scaling.

    Carlos> From 5b6e276e3dd9b4cb06bcf0e21e99227b2134a8bf Mon Sep 17 00:00:00 2001
    Carlos> From: memeplex <carlosjosepita@gmail.com>
    Carlos> Date: Tue, 15 Oct 2019 19:14:03 -0300
    Carlos> Subject: [PATCH] Expose scale factor through the redisplay interface

    Carlos> * src/dispextern.h: add get_scale_factor API.
    Carlos> * src/xterm.c:
    Carlos>   - Unify usages of xg_get_scale and x_get_scale_factor into a
    Carlos>     consolidated x_get_scale_factor that is exported by the rif.
    Carlos>   - Simplify scale inferring logic (see note below).
    Carlos> * src/w32term.c:
    Carlos>   - Simplify w32_get_scale_factor in a similar way (see note).
    Carlos>   - Add it to the rif.
    Carlos> * src/nsterm.m:
    Carlos>   - Just add a dummy implementation that always return 1 to the rif,
    Carlos>     since there are no uses of any scale factor here.

This commit message doesnʼt use the ChangeLog format. There are
various help functions in vc for creating that in the correct
format. Either select some files, run 'vc-diff', and then
'diff-add-change-log-entries-other-window' (bound to C-x 4 A) to
prepare it, or, when youʼre committing, you can run C-c C-w, which
does the same.

    Carlos> Note 1: both x_get_scale_factor and w32_get_scale_factor computed
    Carlos> distinct scales for x and y by taking the ratio between effective
    Carlos> resolution in each direction and a standard 96 dpi resolution.  Since
    Carlos> this ratio is then truncated to an integer (the floor) it seems to me
    Carlos> that there is no sensible possibility that these two numbers
    Carlos> diverge. Moreover, modern toolkits report one number as scale factor
    Carlos> and we need a common interface here. For those reasons I'm arbitrarily
    Carlos> picking the horizontal scale factor as THE scale factor.

Sure.

    Carlos> Note 2: I decided to let get_scale_factor return a double, even tough
    Carlos> factors currently in use are all integers AFAIK. This is in
    Carlos> anticipation of fractional scaling. I believe it's prudent to keep
    Carlos> the interface general in this regard.

Yes. I believe at least KDE already supports fractional scaling, Gnome
canʼt be far behind.

Carlos> diff --git a/src/dispextern.h b/src/dispextern.h
    Carlos> index 0615b16..b93e25f 100644
    Carlos> --- a/src/dispextern.h
    Carlos> +++ b/src/dispextern.h
    Carlos> @@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
    Carlos>  #ifdef HAVE_WINDOW_SYSTEM
 
    Carlos> +  /* Return the scale factor for the screen containing frame F.  */
    Carlos> +  double (*get_scale_factor) (struct frame *f);
    Carlos> +
    Carlos>    /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
    Carlos>    void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
    Carlos>                                struct draw_fringe_bitmap_params *p);
    Carlos> diff --git a/src/nsterm.m b/src/nsterm.m
    Carlos> index 5583c61..6e1b751 100644
    Carlos> --- a/src/nsterm.m
    Carlos> +++ b/src/nsterm.m
    Carlos> @@ -2957,6 +2957,11 @@ so some key presses (TAB) are swallowed by the system.  */
 
    Carlos>     ========================================================================== */
 
    Carlos> +static double
    Carlos> +ns_get_scale_factor (struct frame *f)
    Carlos> +{
    Carlos> +  return 1;  // TODO do we need to do something else here?
    Carlos> +}

As far as I know, macOS *can* scale displays, but generally doesnʼt. I
think using 1 here doesnʼt change anything from the status quo. There
is an API to get the scale factor if it turns out to be needed.

For the rest, it looks ok. Do you plan to make the changes to actually
use the rif interface as part of the same patch?

Robert





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-16  8:51   ` Robert Pluim
@ 2019-10-16 16:12     ` Carlos Pita
  2019-10-16 19:08       ` Carlos Pita
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Pita @ 2019-10-16 16:12 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 37770

[-- Attachment #1: Type: text/plain, Size: 716 bytes --]

> This commit message doesnʼt use the ChangeLog format.

Ahh, I was just informally pattern matching other commit messages I
had seen in your repo. Now I've read [1] (I really like those rules,
will adopt them for other projects too). Nevertheless I'm still unsure
about how to format the notes that go below the actual changes.

Please, tell me what do you think about the new commit message.

> For the rest, it looks ok. Do you plan to make the changes to actually
> use the rif interface as part of the same patch?

No, those are part of bug#37689 [2].

---

[1] https://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs
[2] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37689

[-- Attachment #2: 0001-Expose-scale-factor-through-the-redisplay-interface.patch --]
[-- Type: text/x-patch, Size: 7599 bytes --]

From 6da098e0ebfbe8e17ad0fa860245222d12497889 Mon Sep 17 00:00:00 2001
From: memeplex <carlosjosepita@gmail.com>
Date: Tue, 15 Oct 2019 19:14:03 -0300
Subject: [PATCH] Expose scale factor through the redisplay interface

* src/dispextern.h (redisplay_interface): add get_scale_factor API.

* src/xterm.c (x_get_scale_factor): consolidate with xg_get_scale (see
bug#37752) and export through the rif. Simplify scale inferring
logic (see note 1 below).

* src/w32term.c (w32_get_scale_factor): likewise simplify logic and
add to the rif.

* src/nsterm.m (ns_get_scale_factor): add a dummy implementation that
always return 1 to the rif, since there are no uses of any scale
factor here.

Note 1: both x_get_scale_factor and w32_get_scale_factor computed
distinct scales for x and y by taking the ratio between effective
resolution in each direction and a standard 96 dpi resolution.  Since
this ratio is then truncated to an integer (the floor) it seems to me
that there is no sensible possibility that these two numbers
diverge. Moreover, modern toolkits report one number as scale factor
and we need a common interface here. For those reasons I'm arbitrarily
picking the horizontal scale factor as THE scale factor.

Note 2: I decided to let get_scale_factor return a double, even tough
factors currently in use are all integers AFAIK. This is in
anticipation of fractional scaling. I believe it's prudent to keep
the interface general in this regard.
---
 src/dispextern.h |  3 +++
 src/nsterm.m     |  6 ++++++
 src/w32term.c    | 29 +++++++++++------------------
 src/xterm.c      | 41 ++++++++++++++++++-----------------------
 4 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0615b16..b93e25f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+  /* Return the scale factor for the screen containing frame F.  */
+  double (*get_scale_factor) (struct frame *f);
+
   /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
   void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
                               struct draw_fringe_bitmap_params *p);
diff --git a/src/nsterm.m b/src/nsterm.m
index 5583c61..6e1b751 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2957,6 +2957,11 @@ so some key presses (TAB) are swallowed by the system.  */
 
    ========================================================================== */
 
+static double
+ns_get_scale_factor (struct frame *f)
+{
+  return 1;  // TODO do we need to do something else here?
+}
 
 extern int max_used_fringe_bitmap;
 static void
@@ -5087,6 +5092,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  ns_get_scale_factor,
   ns_draw_fringe_bitmap,
   0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
   0, /* destroy_fringe_bitmap */
diff --git a/src/w32term.c b/src/w32term.c
index 9da0845..6d430c6 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -304,20 +304,16 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
     }
 }
 
-static void
-w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
+static double
+w32_get_scale_factor(struct frame *f)
 {
+  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   const int base_res = 96;
 
-  *scale_x = *scale_y = 1;
-
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
 }
 
 /*
@@ -334,12 +330,8 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
 static void
 w32_draw_underwave (struct glyph_string *s, COLORREF color)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-
-  int scale_x, scale_y;
-  w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
+  double scale = w32_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale, thickness = scale;
   int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
   Emacs_Rectangle wave_clip, string_clip, final_clip;
   RECT w32_final_clip, w32_string_clip;
@@ -348,7 +340,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -7192,6 +7184,7 @@ w32_make_rdb (char *xrm_option)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  w32_get_scale_factor,
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
diff --git a/src/xterm.c b/src/xterm.c
index 5d8b148..67253a6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3611,21 +3611,21 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
-static void
-x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
+static double
+x_get_scale_factor(struct frame *f)
 {
+#ifdef USE_GTK
+  return xg_get_scale (f);
+#else
+  Display *disp = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo = x_display_info_for_display (disp);
   const int base_res = 96;
-  struct x_display_info * dpyinfo = x_display_info_for_display (disp);
-
-  *scale_x = *scale_y = 1;
 
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
+#endif /* USE_GTK */
 }
 
 /*
@@ -3641,27 +3641,21 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
 static void
 x_draw_underwave (struct glyph_string *s)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-
   /* Adjust for scale/HiDPI.  */
-  int scale_x, scale_y;
-
-  x_get_scale_factor (display, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
-
+  double scale = x_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale;
 #ifdef USE_CAIRO
   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 			  s->width, wave_height, wave_length);
 #else  /* not USE_CAIRO */
-  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
 
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -10557,7 +10551,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 {
   int modified_top, modified_left;
 #ifdef USE_GTK
-  int scale = xg_get_scale (f);
+  double scale = x_get_scale_factor (f);
 #endif
 
   if (change_gravity > 0)
@@ -13356,6 +13350,7 @@ x_activate_timeout_atimer (void)
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
     gui_fix_overlapping_area,
+    x_get_scale_factor,
     x_draw_fringe_bitmap,
 #ifdef USE_CAIRO
     x_cr_define_fringe_bitmap,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-16 16:12     ` Carlos Pita
@ 2019-10-16 19:08       ` Carlos Pita
  2019-10-17  8:01         ` Robert Pluim
  2019-10-20 12:34         ` Eli Zaretskii
  0 siblings, 2 replies; 11+ messages in thread
From: Carlos Pita @ 2019-10-16 19:08 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 37770

[-- Attachment #1: Type: text/plain, Size: 563 bytes --]

I've capitalized changelog entries in the message and also added a
reference to the bug number.

Eli told me that you prefer code comments to long commit messages but
in this case I think the rationale would be lost in fragmentary
comments here and there. It's true that there is still the reference
to this discussion in the commit message, but I believe it's
convenient to quickly get a description of the change using git blame
when browsing the code. If you disagree I will remove the notes from
the commit message and copy them here.

Best regards
--
Carlos

[-- Attachment #2: 0001-Expose-scale-factor-through-the-redisplay-interface-.patch --]
[-- Type: text/x-patch, Size: 7612 bytes --]

From 01e52de9ce49bc0b3490492891f066d2f9306cf4 Mon Sep 17 00:00:00 2001
From: memeplex <carlosjosepita@gmail.com>
Date: Tue, 15 Oct 2019 19:14:03 -0300
Subject: [PATCH] Expose scale factor through the redisplay interface
 (Bug#37770)

* src/dispextern.h (redisplay_interface): Add get_scale_factor API.

* src/xterm.c (x_get_scale_factor): Consolidate with xg_get_scale (see
bug#37752) and export through the rif. Simplify scale inferring
logic (see note 1 below).

* src/w32term.c (w32_get_scale_factor): Likewise simplify logic and
add to the rif.

* src/nsterm.m (ns_get_scale_factor): Add a dummy implementation that
always return 1 to the rif, since there are no uses of any scale
factor here.

Note 1: both x_get_scale_factor and w32_get_scale_factor computed
distinct scales for x and y by taking the ratio between effective
resolution in each direction and a standard 96 dpi resolution.  Since
this ratio is then truncated to an integer (the floor) it seems to me
that there is no sensible possibility that these two numbers
diverge. Moreover, modern toolkits report one number as scale factor
and we need a common interface here. For those reasons I'm arbitrarily
picking the horizontal scale factor as THE scale factor.

Note 2: I decided to let get_scale_factor return a double, even tough
factors currently in use are all integers AFAIK. This is in
anticipation of fractional scaling. I believe it's prudent to keep
the interface general in this regard.
---
 src/dispextern.h |  3 +++
 src/nsterm.m     |  6 ++++++
 src/w32term.c    | 29 +++++++++++------------------
 src/xterm.c      | 41 ++++++++++++++++++-----------------------
 4 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0615b16..b93e25f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+  /* Return the scale factor for the screen containing frame F.  */
+  double (*get_scale_factor) (struct frame *f);
+
   /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
   void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
                               struct draw_fringe_bitmap_params *p);
diff --git a/src/nsterm.m b/src/nsterm.m
index 5583c61..6e1b751 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2957,6 +2957,11 @@ so some key presses (TAB) are swallowed by the system.  */
 
    ========================================================================== */
 
+static double
+ns_get_scale_factor (struct frame *f)
+{
+  return 1;  // TODO do we need to do something else here?
+}
 
 extern int max_used_fringe_bitmap;
 static void
@@ -5087,6 +5092,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  ns_get_scale_factor,
   ns_draw_fringe_bitmap,
   0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
   0, /* destroy_fringe_bitmap */
diff --git a/src/w32term.c b/src/w32term.c
index 9da0845..6d430c6 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -304,20 +304,16 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
     }
 }
 
-static void
-w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
+static double
+w32_get_scale_factor(struct frame *f)
 {
+  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   const int base_res = 96;
 
-  *scale_x = *scale_y = 1;
-
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
 }
 
 /*
@@ -334,12 +330,8 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
 static void
 w32_draw_underwave (struct glyph_string *s, COLORREF color)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-
-  int scale_x, scale_y;
-  w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
+  double scale = w32_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale, thickness = scale;
   int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
   Emacs_Rectangle wave_clip, string_clip, final_clip;
   RECT w32_final_clip, w32_string_clip;
@@ -348,7 +340,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -7192,6 +7184,7 @@ w32_make_rdb (char *xrm_option)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  w32_get_scale_factor,
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
diff --git a/src/xterm.c b/src/xterm.c
index 5d8b148..67253a6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3611,21 +3611,21 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
-static void
-x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
+static double
+x_get_scale_factor(struct frame *f)
 {
+#ifdef USE_GTK
+  return xg_get_scale (f);
+#else
+  Display *disp = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo = x_display_info_for_display (disp);
   const int base_res = 96;
-  struct x_display_info * dpyinfo = x_display_info_for_display (disp);
-
-  *scale_x = *scale_y = 1;
 
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return floor (dpyinfo->resx / base_res);
+  else
+    return 1;
+#endif /* USE_GTK */
 }
 
 /*
@@ -3641,27 +3641,21 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
 static void
 x_draw_underwave (struct glyph_string *s)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-
   /* Adjust for scale/HiDPI.  */
-  int scale_x, scale_y;
-
-  x_get_scale_factor (display, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
-
+  double scale = x_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale;
 #ifdef USE_CAIRO
   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 			  s->width, wave_height, wave_length);
 #else  /* not USE_CAIRO */
-  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
 
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -10557,7 +10551,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 {
   int modified_top, modified_left;
 #ifdef USE_GTK
-  int scale = xg_get_scale (f);
+  double scale = x_get_scale_factor (f);
 #endif
 
   if (change_gravity > 0)
@@ -13356,6 +13350,7 @@ x_activate_timeout_atimer (void)
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
     gui_fix_overlapping_area,
+    x_get_scale_factor,
     x_draw_fringe_bitmap,
 #ifdef USE_CAIRO
     x_cr_define_fringe_bitmap,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-16 19:08       ` Carlos Pita
@ 2019-10-17  8:01         ` Robert Pluim
  2019-10-20 12:34         ` Eli Zaretskii
  1 sibling, 0 replies; 11+ messages in thread
From: Robert Pluim @ 2019-10-17  8:01 UTC (permalink / raw)
  To: Carlos Pita; +Cc: 37770

>>>>> On Wed, 16 Oct 2019 16:08:47 -0300, Carlos Pita <carlosjosepita@gmail.com> said:

    Carlos> I've capitalized changelog entries in the message and also added a
    Carlos> reference to the bug number.

    Carlos> Eli told me that you prefer code comments to long commit messages but
    Carlos> in this case I think the rationale would be lost in fragmentary
    Carlos> comments here and there. It's true that there is still the reference
    Carlos> to this discussion in the commit message, but I believe it's
    Carlos> convenient to quickly get a description of the change using git blame
    Carlos> when browsing the code. If you disagree I will remove the notes from
    Carlos> the commit message and copy them here.

If by 'you' you mean 'Emacs', then yes, putting stuff in the code
is preferred, I think. Of course nothing stops us from doing both.

Carlos> From 01e52de9ce49bc0b3490492891f066d2f9306cf4 Mon Sep 17 00:00:00 2001
    Carlos> From: memeplex <carlosjosepita@gmail.com>
    Carlos> Date: Tue, 15 Oct 2019 19:14:03 -0300
    Carlos> Subject: [PATCH] Expose scale factor through the redisplay interface
    Carlos>  (Bug#37770)

    Carlos> * src/dispextern.h (redisplay_interface): Add get_scale_factor API.

    Carlos> * src/xterm.c (x_get_scale_factor): Consolidate with xg_get_scale (see
    Carlos> bug#37752) and export through the rif. Simplify scale inferring
    Carlos> logic (see note 1 below).

2 spaces after '.'

    Carlos> Note 1: both x_get_scale_factor and w32_get_scale_factor computed
    Carlos> distinct scales for x and y by taking the ratio between effective
    Carlos> resolution in each direction and a standard 96 dpi resolution.  Since
    Carlos> this ratio is then truncated to an integer (the floor) it seems to me
    Carlos> that there is no sensible possibility that these two numbers
    Carlos> diverge. Moreover, modern toolkits report one number as scale factor
    Carlos> and we need a common interface here. For those reasons I'm arbitrarily
    Carlos> picking the horizontal scale factor as THE scale factor.

    Carlos> Note 2: I decided to let get_scale_factor return a double, even tough
    Carlos> factors currently in use are all integers AFAIK. This is in
    Carlos> anticipation of fractional scaling. I believe it's prudent to keep
    Carlos> the interface general in this regard.

I tend to lean towards putting this sort of rationale at the beginning
of the commit message, and let the ChangeLog message explain the
mechanics of the change.

Robert





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-16 19:08       ` Carlos Pita
  2019-10-17  8:01         ` Robert Pluim
@ 2019-10-20 12:34         ` Eli Zaretskii
  2019-10-20 17:22           ` Carlos Pita
  1 sibling, 1 reply; 11+ messages in thread
From: Eli Zaretskii @ 2019-10-20 12:34 UTC (permalink / raw)
  To: Carlos Pita; +Cc: rpluim, 37770

> From: Carlos Pita <carlosjosepita@gmail.com>
> Date: Wed, 16 Oct 2019 16:08:47 -0300
> Cc: 37770@debbugs.gnu.org
> 
> Eli told me that you prefer code comments to long commit messages but
> in this case I think the rationale would be lost in fragmentary
> comments here and there. It's true that there is still the reference
> to this discussion in the commit message, but I believe it's
> convenient to quickly get a description of the change using git blame
> when browsing the code. If you disagree I will remove the notes from
> the commit message and copy them here.

The explanations should precede the file/function entries part.

> Note 1: both x_get_scale_factor and w32_get_scale_factor computed
> distinct scales for x and y by taking the ratio between effective
> resolution in each direction and a standard 96 dpi resolution.  Since
> this ratio is then truncated to an integer (the floor) it seems to me
> that there is no sensible possibility that these two numbers
> diverge. Moreover, modern toolkits report one number as scale factor
> and we need a common interface here. For those reasons I'm arbitrarily
> picking the horizontal scale factor as THE scale factor.

I'm not sure about this.  Admittedly, I'm not an expert on screen
scales on GUI systems, but why do we need to drop the two scale
factors as part of this change, which is basically just refactoring?
I'd suggest to keep the 2 scale factors for now.  We can always
replace 2 with one later.

> +static double
> +ns_get_scale_factor (struct frame *f)
> +{
> +  return 1;  // TODO do we need to do something else here?

Please use C-style comments, /* Like this.  */, not C++ style.

Thanks.





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-20 12:34         ` Eli Zaretskii
@ 2019-10-20 17:22           ` Carlos Pita
  2019-10-22 18:06             ` Carlos Pita
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Pita @ 2019-10-20 17:22 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Robert Pluim, 37770

[-- Attachment #1: Type: text/plain, Size: 1703 bytes --]

> I'm not sure about this.  Admittedly, I'm not an expert on screen
> scales on GUI systems, but why do we need to drop the two scale
> factors as part of this change, which is basically just refactoring?
> I'd suggest to keep the 2 scale factors for now.  We can always
> replace 2 with one later.

I might do that, I might rename x/w32_get_scale_factor to
x/w32_get_scale_factor_xy and then define the rif exposed
x/w32_get_scale_factor to call these ones and simply drop the y scale
factor. But I would prefer not to do that because:

1. It adds complexity (more code, two different apis).

2. The only users of the (static) _xy variants would be x/w32_draw_underwave.

3. For me, it's hard to figure out why a screen would offer, say, x
resolution = 2 * 96dpi and y resolution = 3 * 96dpi (and surely we
could accommodate a humble underwave drawing routing if such a screen
happens to exist).

4. The nsterm backend also draws underwaves and doesn't use two
different scale factors (indeed, it doesn't use any scale factor at
all, nor the rest of this backend does).

5. AFAIK, the "toolkit industry" has long been using one number as THE
scale factor. Moreover, most of the time this number is just 1 or 2.

Regarding point 3, it's easier to imagine a screen with 1.99 and 2.01
x and y ratios that get respectively truncated down 1 and 2 x and y
scale factors. Now, the problem is not the different scale factors but
the way they were computed, and this is not solved at all by using 2
scale factors. Maybe we should use round instead of floor there.

I've modified the code comment and the message comment according to
your comments, Eli. I've also changed floor to round.

Best regards
--
Carlos

[-- Attachment #2: 0001-Expose-scale-factor-through-the-redisplay-interface-.patch --]
[-- Type: text/x-patch, Size: 7640 bytes --]

From 837006c732b7792f20d27a7c8825fa542f6c7607 Mon Sep 17 00:00:00 2001
From: memeplex <carlosjosepita@gmail.com>
Date: Tue, 15 Oct 2019 19:14:03 -0300
Subject: [PATCH] Expose scale factor through the redisplay interface
 (Bug#37770)

Note 1: both x_get_scale_factor and w32_get_scale_factor computed
distinct scales for x and y by taking the ratio between effective
resolution in each direction and a standard 96 dpi resolution.  Since
this ratio is then truncated to an integer (the floor) it seems to me
that there is no sensible possibility that these two numbers
diverge. Moreover, modern toolkits report one number as scale factor
and we need a common interface here. For those reasons I'm arbitrarily
picking the horizontal scale factor as THE scale factor.

Note 2: I decided to let get_scale_factor return a double, even tough
factors currently in use are all integers AFAIK. This is in
anticipation of fractional scaling. I believe it's prudent to keep
the interface general in this regard.

* src/dispextern.h (redisplay_interface): Add get_scale_factor API.

* src/xterm.c (x_get_scale_factor): Consolidate with xg_get_scale (see
bug#37752) and export through the rif. Simplify scale inferring
logic (see note 1 above).

* src/w32term.c (w32_get_scale_factor): Likewise simplify logic and
add to the rif.

* src/nsterm.m (ns_get_scale_factor): Add a dummy implementation that
always return 1 to the rif, since there are no uses of any scale
factor here.
---
 src/dispextern.h |  3 +++
 src/nsterm.m     |  6 ++++++
 src/w32term.c    | 29 +++++++++++------------------
 src/xterm.c      | 41 ++++++++++++++++++-----------------------
 4 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0615b16d71..b93e25f216 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2942,6 +2942,9 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+  /* Return the scale factor for the screen containing frame F.  */
+  double (*get_scale_factor) (struct frame *f);
+
   /* Draw a fringe bitmap in window W of row ROW using parameters P.  */
   void (*draw_fringe_bitmap) (struct window *w, struct glyph_row *row,
                               struct draw_fringe_bitmap_params *p);
diff --git a/src/nsterm.m b/src/nsterm.m
index 5583c6105c..7b95b9e20b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2957,6 +2957,11 @@ so some key presses (TAB) are swallowed by the system.  */
 
    ========================================================================== */
 
+static double
+ns_get_scale_factor (struct frame *f)
+{
+  return 1;  /* TODO do we need to do something else here?  */
+}
 
 extern int max_used_fringe_bitmap;
 static void
@@ -5087,6 +5092,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  ns_get_scale_factor,
   ns_draw_fringe_bitmap,
   0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */
   0, /* destroy_fringe_bitmap */
diff --git a/src/w32term.c b/src/w32term.c
index 9da0845836..fc2893f254 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -304,20 +304,16 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
     }
 }
 
-static void
-w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
+static double
+w32_get_scale_factor(struct frame *f)
 {
+  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   const int base_res = 96;
 
-  *scale_x = *scale_y = 1;
-
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return round (dpyinfo->resx / base_res);
+  else
+    return 1;
 }
 
 /*
@@ -334,12 +330,8 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
 static void
 w32_draw_underwave (struct glyph_string *s, COLORREF color)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-
-  int scale_x, scale_y;
-  w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
+  double scale = w32_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale, thickness = scale;
   int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
   Emacs_Rectangle wave_clip, string_clip, final_clip;
   RECT w32_final_clip, w32_string_clip;
@@ -348,7 +340,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -7192,6 +7184,7 @@ w32_make_rdb (char *xrm_option)
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
   gui_fix_overlapping_area,
+  w32_get_scale_factor,
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
diff --git a/src/xterm.c b/src/xterm.c
index 045589534f..1a5c339fa7 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3611,21 +3611,21 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
-static void
-x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
+static double
+x_get_scale_factor(struct frame *f)
 {
+#ifdef USE_GTK
+  return xg_get_scale (f);
+#else
+  Display *disp = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo = x_display_info_for_display (disp);
   const int base_res = 96;
-  struct x_display_info * dpyinfo = x_display_info_for_display (disp);
-
-  *scale_x = *scale_y = 1;
 
-  if (dpyinfo)
-    {
-      if (dpyinfo->resx > base_res)
-	*scale_x = floor (dpyinfo->resx / base_res);
-      if (dpyinfo->resy > base_res)
-	*scale_y = floor (dpyinfo->resy / base_res);
-    }
+  if (dpyinfo && dpyinfo->resx > base_res)
+    return round (dpyinfo->resx / base_res);
+  else
+    return 1;
+#endif /* USE_GTK */
 }
 
 /*
@@ -3641,27 +3641,21 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
 static void
 x_draw_underwave (struct glyph_string *s)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-
   /* Adjust for scale/HiDPI.  */
-  int scale_x, scale_y;
-
-  x_get_scale_factor (display, &scale_x, &scale_y);
-
-  int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
-
+  double scale = x_get_scale_factor (s->f);
+  int wave_height = 3 * scale, wave_length = 2 * scale;
 #ifdef USE_CAIRO
   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 			  s->width, wave_height, wave_length);
 #else  /* not USE_CAIRO */
-  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
 
   dx = wave_length;
   dy = wave_height - 1;
   x0 = s->x;
-  y0 = s->ybase + wave_height / 2 - scale_y;
+  y0 = s->ybase + wave_height / 2 - scale;
   width = s->width;
   xmax = x0 + width;
 
@@ -10557,7 +10551,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
 {
   int modified_top, modified_left;
 #ifdef USE_GTK
-  int scale = xg_get_scale (f);
+  double scale = x_get_scale_factor (f);
 #endif
 
   if (change_gravity > 0)
@@ -13357,6 +13351,7 @@ x_activate_timeout_atimer (void)
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
     gui_fix_overlapping_area,
+    x_get_scale_factor,
     x_draw_fringe_bitmap,
 #ifdef USE_CAIRO
     x_cr_define_fringe_bitmap,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-20 17:22           ` Carlos Pita
@ 2019-10-22 18:06             ` Carlos Pita
  2019-10-24  9:19               ` Robert Pluim
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Pita @ 2019-10-22 18:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Robert Pluim, 37770

I've improved the code comment for the redisplay interface entry in:

https://github.com/memeplex/emacs/commit/d3c66e6eea8a3b6f1a269bd968597a3bd8a3e811

(to generate the patch, add a .patch suffix to that url)

The new comment states:

/* Return the scale factor for the screen containing frame F. All
geometries are reported by the backend using a scale that is
approximately 96dpi x scale_factor. This scale may match
physical resolution or not. */

Some thoughts:

One possibility for the (maybe distant) future, is that this scale
factor api won't be needed any more. Like nsterm does (I believe), all
backends might expose a 1 x 96dpi interface so that the upper layers
can work mostly or fully unaware of the device complexities. But at
this moment the xterm backend goes to lengths in order to revert gtk
auto-scaling and provide a "physical dpi" (well, not necessarily
physical, since there is still randr in the middle)  interface to the
upper layers, thus losing the benefits of gtk auto-scaling, although
with good reason since nowadays gtk is more of a hack to the x11
backend, sniffing the underlying x event loop as it is, than a proper
backend on its own.

Anyway, even if that's not the trend, exposing a higher scale factor
to the upper layers still has the potential benefit of letting those
layers decide how to better use the extra available resolution,
instead of pretending they are drawing to a vintage screen. Whether
this is worthwhile or not I don't know, given that font and image
rendering are the parts most profited from this extra resolution, and
that fact every modern toolkit already exploits. In any case, at this
moment we still need the api because of the differences between
backends.





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-22 18:06             ` Carlos Pita
@ 2019-10-24  9:19               ` Robert Pluim
  2019-10-24 14:34                 ` Carlos Pita
  0 siblings, 1 reply; 11+ messages in thread
From: Robert Pluim @ 2019-10-24  9:19 UTC (permalink / raw)
  To: Carlos Pita; +Cc: 37770

>>>>> On Tue, 22 Oct 2019 15:06:49 -0300, Carlos Pita <carlosjosepita@gmail.com> said:

    Carlos> I've improved the code comment for the redisplay interface entry in:
    Carlos> https://github.com/memeplex/emacs/commit/d3c66e6eea8a3b6f1a269bd968597a3bd8a3e811

    Carlos> (to generate the patch, add a .patch suffix to that url)

    Carlos> The new comment states:

    Carlos> /* Return the scale factor for the screen containing frame F. All
    Carlos> geometries are reported by the backend using a scale that is
    Carlos> approximately 96dpi x scale_factor. This scale may match
    Carlos> physical resolution or not. */

Two spaces after '.'. Also: "This scale may not match the physical resolution."

    Carlos> Some thoughts:

    Carlos> One possibility for the (maybe distant) future, is that this scale
    Carlos> factor api won't be needed any more. Like nsterm does (I believe), all
    Carlos> backends might expose a 1 x 96dpi interface so that the upper layers
    Carlos> can work mostly or fully unaware of the device complexities. But at
    Carlos> this moment the xterm backend goes to lengths in order to revert gtk
    Carlos> auto-scaling and provide a "physical dpi" (well, not necessarily
    Carlos> physical, since there is still randr in the middle)  interface to the
    Carlos> upper layers, thus losing the benefits of gtk auto-scaling, although
    Carlos> with good reason since nowadays gtk is more of a hack to the x11
    Carlos> backend, sniffing the underlying x event loop as it is, than a proper
    Carlos> backend on its own.

If emacs used only GTK to draw things to the screen, then indeed there
would be no need for those conversions, as GTK would handle them.

<https://github.com/masm11/emacs> is attempting to implement a 'pure'
GTK backend. I have no idea how close it is to being ready to merge.

    Carlos> Anyway, even if that's not the trend, exposing a higher scale factor
    Carlos> to the upper layers still has the potential benefit of letting those
    Carlos> layers decide how to better use the extra available resolution,
    Carlos> instead of pretending they are drawing to a vintage screen. Whether
    Carlos> this is worthwhile or not I don't know, given that font and image
    Carlos> rendering are the parts most profited from this extra resolution, and
    Carlos> that fact every modern toolkit already exploits. In any case, at this
    Carlos> moment we still need the api because of the differences between
    Carlos> backends.

Youʼre right about that (although on macOS we seem to get by OK
without it).

Robert





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#37770: [PATCH] Expose scale factor through the redisplay interface
  2019-10-24  9:19               ` Robert Pluim
@ 2019-10-24 14:34                 ` Carlos Pita
  0 siblings, 0 replies; 11+ messages in thread
From: Carlos Pita @ 2019-10-24 14:34 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 37770-close

[-- Attachment #1: Type: text/plain, Size: 1636 bytes --]

>
>
> If emacs used only GTK to draw things to the screen, then indeed there
> would be no need for those conversions, as GTK would handle them.
>

Exactly.

>
> <https://github.com/masm11/emacs> is attempting to implement a 'pure'
> GTK backend. I have no idea how close it is to being ready to merge.
>

That's great. The way towards Wayland also. Sounds like a LOT of work,
though.

I've been working in an alternative to this patch and the one that fixes
the cairo fringe. My goal is to provide a gtk+cairo solution that listen to
gtk scale changes and scales everything (including fonts) accordingly. This
would enable an adaptive multi-monitor multi-dpi emacs using the old
scale-up-gtk then scale-down-xrandr trick, a nice implementation of which,
including GUI and everything,  is going to be part of the next Ubuntu LTS
with high probability.

I'm having a really hard time making the font engine abandon it's idea of
pixel-sized fonts that is very entrenched in its caching mechanism once
everything was first rendered at some initial dpi. The only way I found to
circumvent this is to report a fixed 96dpi resolution and then scale all
cairo rendering (fonts, images, bitmaps) using the platform scaling factor.
This mostly works but I'm still unable to get rid of all previously opened
fonts, even after clearing all ftcrfont caches, so I get a mix of different
sized fonts. It will probably take me some time to figure out what's
happening.

So I'm closing this issue and will open a new one once I have an integral
cairo+gtk solution working in a way that mostly resembles the nsterm
backend.

Best regards
--
Carlos



>

[-- Attachment #2: Type: text/html, Size: 2680 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-10-24 14:34 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-15 22:29 bug#37770: [PATCH] Expose scale factor through the redisplay interface Carlos Pita
2019-10-16  0:32 ` Carlos Pita
2019-10-16  8:51   ` Robert Pluim
2019-10-16 16:12     ` Carlos Pita
2019-10-16 19:08       ` Carlos Pita
2019-10-17  8:01         ` Robert Pluim
2019-10-20 12:34         ` Eli Zaretskii
2019-10-20 17:22           ` Carlos Pita
2019-10-22 18:06             ` Carlos Pita
2019-10-24  9:19               ` Robert Pluim
2019-10-24 14:34                 ` Carlos Pita

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).