From 75db4511704284a739c93895d7a31478b1a71181 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 6 Jul 2023 09:35:27 +0800 Subject: [PATCH] Update Android port * java/org/gnu/emacs/EmacsNative.java (scaledDensity): Announce new argument `scaledDensity'. * java/org/gnu/emacs/EmacsNoninteractive.java (main): Specify new argument. * java/org/gnu/emacs/EmacsService.java (onCreate): Compute an adjusted DPI for the font size based on the ratio between density and scaledDensity. (run): Specify that adjusted density. * src/android.c (setEmacsParams): Set `android_scaled_pixel_density'. * src/android.h: (android_scaled_pixel_density: New variable. * src/androidterm.c (android_term_init): Set `font_resolution'. * src/androidterm.h (struct android_display_info): New field. * src/font.c (font_pixel_size, font_find_for_lface) (font_open_for_lface, Ffont_face_attributes, Fopen_font): Use FRAME_RES instead of FRAME_RES_Y. * src/frame.h (FRAME_RES): New macro. Use this to convert between font point and pixel sizes as opposed to FRAME_RES_Y. * src/w32font.c (fill_in_logfont): * src/xfaces.c (Fx_family_fonts, set_lface_from_font): Use FRAME_RES instead of FRAME_RES_Y. (bug#64444) --- java/org/gnu/emacs/EmacsNative.java | 4 ++++ java/org/gnu/emacs/EmacsNoninteractive.java | 2 +- java/org/gnu/emacs/EmacsService.java | 5 +++++ src/android.c | 6 ++++++ src/android.h | 1 + src/androidterm.c | 5 ++--- src/androidterm.h | 5 +++++ src/font.c | 12 ++++++------ src/frame.h | 18 ++++++++++++++++-- src/w32font.c | 2 +- src/xfaces.c | 4 ++-- 11 files changed, 49 insertions(+), 15 deletions(-) diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index 9e87c419f95..5b8b0f1eae5 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java @@ -60,6 +60,9 @@ public final class EmacsNative pixelDensityX and pixelDensityY are the DPI values that will be used by Emacs. + scaledDensity is the DPI value used to translate point sizes to + pixel sizes when loading fonts. + classPath must be the classpath of this app_process process, or NULL. @@ -70,6 +73,7 @@ public final class EmacsNative String cacheDir, float pixelDensityX, float pixelDensityY, + float scaledDensity, String classPath, EmacsService emacsService); diff --git a/java/org/gnu/emacs/EmacsNoninteractive.java b/java/org/gnu/emacs/EmacsNoninteractive.java index aaba74d877c..aa6fa41ba97 100644 --- a/java/org/gnu/emacs/EmacsNoninteractive.java +++ b/java/org/gnu/emacs/EmacsNoninteractive.java @@ -190,7 +190,7 @@ public final class EmacsNoninteractive EmacsNative.setEmacsParams (assets, filesDir, libDir, cacheDir, 0.0f, - 0.0f, null, null); + 0.0f, 0.0f, null, null); /* Now find the dump file that Emacs should use, if it has already been dumped. */ diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index e1fd2dbffda..37048960f25 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -211,6 +211,7 @@ public final class EmacsService extends Service final String filesDir, libDir, cacheDir, classPath; final double pixelDensityX; final double pixelDensityY; + final double scaledDensity; SERVICE = this; handler = new Handler (Looper.getMainLooper ()); @@ -219,6 +220,9 @@ public final class EmacsService extends Service metrics = getResources ().getDisplayMetrics (); pixelDensityX = metrics.xdpi; pixelDensityY = metrics.ydpi; + scaledDensity = ((metrics.scaledDensity + / metrics.density) + * pixelDensityX); resolver = getContentResolver (); try @@ -247,6 +251,7 @@ public final class EmacsService extends Service EmacsNative.setEmacsParams (manager, filesDir, libDir, cacheDir, (float) pixelDensityX, (float) pixelDensityY, + (float) scaledDensity, classPath, EmacsService.this); } }, extraStartupArgument, diff --git a/src/android.c b/src/android.c index 2a2d134c3c8..a6bc8217820 100644 --- a/src/android.c +++ b/src/android.c @@ -198,6 +198,10 @@ char *android_class_path; /* The display's pixel densities. */ double android_pixel_density_x, android_pixel_density_y; +/* The display pixel density used to convert between point and pixel + font sizes. */ +double android_scaled_pixel_density; + /* The Android application data directory. */ static char *android_files_dir; @@ -2000,6 +2004,7 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object, jobject cache_dir, jfloat pixel_density_x, jfloat pixel_density_y, + jfloat scaled_density, jobject class_path, jobject emacs_service_object) { @@ -2021,6 +2026,7 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object, android_pixel_density_x = pixel_density_x; android_pixel_density_y = pixel_density_y; + android_scaled_pixel_density = scaled_density; __android_log_print (ANDROID_LOG_INFO, __func__, "Initializing "PACKAGE_STRING"...\nPlease report bugs to " diff --git a/src/android.h b/src/android.h index 8634ba01a3d..33ca379e6ba 100644 --- a/src/android.h +++ b/src/android.h @@ -58,6 +58,7 @@ extern int android_fclose (FILE *); extern const char *android_get_home_directory (void); extern double android_pixel_density_x, android_pixel_density_y; +extern double android_scaled_pixel_density; enum android_handle_type { diff --git a/src/androidterm.c b/src/androidterm.c index aed8e24b9fa..20a8860a913 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -6295,11 +6295,10 @@ android_term_init (void) dpyinfo->color_map = color_map; #ifndef ANDROID_STUBIFY - dpyinfo->resx = android_pixel_density_x; dpyinfo->resy = android_pixel_density_y; - -#endif + dpyinfo->font_resolution = android_scaled_pixel_density; +#endif /* ANDROID_STUBIFY */ /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html */ dpyinfo->smallest_font_height = 1; diff --git a/src/androidterm.h b/src/androidterm.h index e3738fb2192..e75d46b1dfb 100644 --- a/src/androidterm.h +++ b/src/androidterm.h @@ -65,6 +65,11 @@ struct android_display_info /* DPI of the display. */ double resx, resy; + /* DPI used to convert font point sizes into pixel dimensions. + This is resy adjusted by a fixed scaling factor specified by + the user. */ + double font_resolution; + /* Scratch GC for drawing a cursor in a non-default face. */ struct android_gc *scratch_cursor_gc; diff --git a/src/font.c b/src/font.c index 9dcafb3bb33..7f8ddc4dc34 100644 --- a/src/font.c +++ b/src/font.c @@ -348,7 +348,7 @@ font_pixel_size (struct frame *f, Lisp_Object spec) if (FIXNUMP (val)) dpi = XFIXNUM (val); else - dpi = FRAME_RES_Y (f); + dpi = FRAME_RES (f); pixel_size = POINT_TO_PIXEL (point_size, dpi); return pixel_size; } @@ -3023,7 +3023,7 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int { double pt = XFIXNUM (attrs[LFACE_HEIGHT_INDEX]); - pixel_size = POINT_TO_PIXEL (pt / 10, FRAME_RES_Y (f)); + pixel_size = POINT_TO_PIXEL (pt / 10, FRAME_RES (f)); if (pixel_size < 1) pixel_size = 1; } @@ -3175,13 +3175,13 @@ font_open_for_lface (struct frame *f, Lisp_Object entity, Lisp_Object *attrs, Li } pt /= 10; - size = POINT_TO_PIXEL (pt, FRAME_RES_Y (f)); + size = POINT_TO_PIXEL (pt, FRAME_RES (f)); #ifdef HAVE_NS if (size == 0) { Lisp_Object ffsize = get_frame_param (f, Qfontsize); size = (NUMBERP (ffsize) - ? POINT_TO_PIXEL (XFLOATINT (ffsize), FRAME_RES_Y (f)) + ? POINT_TO_PIXEL (XFLOATINT (ffsize), FRAME_RES (f)) : 0); } #endif @@ -4082,7 +4082,7 @@ are to be displayed on. If omitted, the selected frame is used. */) if (FIXNUMP (val)) { Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); - int dpi = FIXNUMP (font_dpi) ? XFIXNUM (font_dpi) : FRAME_RES_Y (f); + int dpi = FIXNUMP (font_dpi) ? XFIXNUM (font_dpi) : FRAME_RES (f); plist[n++] = QCheight; plist[n++] = make_fixnum (PIXEL_TO_POINT (XFIXNUM (val) * 10, dpi)); } @@ -4986,7 +4986,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, { CHECK_NUMBER (size); if (FLOATP (size)) - isize = POINT_TO_PIXEL (XFLOAT_DATA (size), FRAME_RES_Y (f)); + isize = POINT_TO_PIXEL (XFLOAT_DATA (size), FRAME_RES (f)); else if (! integer_to_intmax (size, &isize)) args_out_of_range (font_entity, size); if (! (INT_MIN <= isize && isize <= INT_MAX)) diff --git a/src/frame.h b/src/frame.h index 8ed9c0f37d8..62fc63c7c1f 100644 --- a/src/frame.h +++ b/src/frame.h @@ -981,12 +981,26 @@ default_pixels_per_inch_y (void) #define FRAME_RES_Y(f) \ (eassert (FRAME_WINDOW_P (f)), FRAME_DISPLAY_INFO (f)->resy) +#ifdef HAVE_ANDROID + +/* Android systems use a font scaling factor independent from the + display DPI. */ + +#define FRAME_RES(f) \ + (eassert (FRAME_WINDOW_P (f)), \ + FRAME_DISPLAY_INFO (f)->font_resolution) + +#else /* !HAVE_ANDROID */ +#define FRAME_RES(f) (FRAME_RES_Y (f)) +#endif /* HAVE_ANDROID */ + #else /* !HAVE_WINDOW_SYSTEM */ /* Defaults when no window system available. */ -#define FRAME_RES_X(f) default_pixels_per_inch_x () -#define FRAME_RES_Y(f) default_pixels_per_inch_y () +#define FRAME_RES_X(f) default_pixels_per_inch_x () +#define FRAME_RES_Y(f) default_pixels_per_inch_y () +#define FRAME_RES(f) default_pixels_per_inch_y () #endif /* HAVE_WINDOW_SYSTEM */ diff --git a/src/w32font.c b/src/w32font.c index 2917fa55f9f..0371b24e1d1 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -2031,7 +2031,7 @@ static void fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec) { Lisp_Object tmp, extra; - int dpi = FRAME_RES_Y (f); + int dpi = FRAME_RES (f); tmp = AREF (font_spec, FONT_DPI_INDEX); if (FIXNUMP (tmp)) diff --git a/src/xfaces.c b/src/xfaces.c index af3428ad995..30487c0e8fb 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -1612,7 +1612,7 @@ the face font sort order, see `face-font-selection-order'. */) { Lisp_Object font = AREF (vec, i); int point = PIXEL_TO_POINT (XFIXNUM (AREF (font, FONT_SIZE_INDEX)) * 10, - FRAME_RES_Y (f)); + FRAME_RES (f)); Lisp_Object spacing = Ffont_get (font, QCspacing); Lisp_Object v = CALLN (Fvector, AREF (font, FONT_FAMILY_INDEX), @@ -2173,7 +2173,7 @@ set_lface_from_font (struct frame *f, Lisp_Object lface, if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) { - int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES_Y (f)); + int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES (f)); eassert (pt > 0); ASET (lface, LFACE_HEIGHT_INDEX, make_fixnum (pt)); -- 2.39.2