From 5b6e276e3dd9b4cb06bcf0e21e99227b2134a8bf Mon Sep 17 00:00:00 2001 From: memeplex 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