emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 219bfea874b: Improve rules for enumerating user fonts


From: Po Lu
Subject: feature/android 219bfea874b: Improve rules for enumerating user fonts
Date: Wed, 29 Mar 2023 08:14:58 -0400 (EDT)

branch: feature/android
commit 219bfea874b237caa763a31f3e9261733fab8e68
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve rules for enumerating user fonts
    
    * doc/emacs/android.texi (Android Fonts): Document distortable
    font replacement rules.
    * src/sfntfont.c (sfnt_replace_fonts_p): New function.
    (sfnt_enum_font_1): Call it.
---
 doc/emacs/android.texi | 25 ++++++++++++++++----
 src/sfntfont.c         | 64 +++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi
index c92700980de..97f72e98cee 100644
--- a/doc/emacs/android.texi
+++ b/doc/emacs/android.texi
@@ -534,10 +534,11 @@ menu in the system settings, but this procedure may vary 
by device.
 named @code{sfnt-android} and @code{android}.
 
 Upon startup, Emacs enumerates all the TrueType format fonts in the
-directory @file{/system/fonts}, and the @file{fonts} directory inside
-the Emacs home directory.  Emacs assumes there will always be a font
-named ``Droid Sans Mono'', and then defaults to using this font.
-These fonts are then displayed by the @code{sfnt-android} font driver.
+directory @file{/system/fonts}, and the @file{fonts} directory
+(@dfn{user fonts directory}) inside the Emacs home directory.  Emacs
+assumes there will always be a font named ``Droid Sans Mono'', and
+then defaults to using this font.  These fonts are then displayed by
+the @code{sfnt-android} font driver.
 
 When running on Android, Emacs currently lacks support for OpenType
 fonts.  This means that only a subset of the fonts installed on the
@@ -551,6 +552,22 @@ metrics provided by the Android platform.  In that case, 
Emacs uses
 the ``Monospace'' typeface configured on your system; this should
 always be Droid Sans Mono.
 
+@cindex TrueType GX fonts, android
+@cindex distortable fonts, android
+
+  Like on X systems, Emacs supports distortable fonts under Android.
+These fonts (also termed ``TrueType GX fonts'', ``variable fonts'',
+and ``multiple master fonts'') provide multiple different styles
+(``Bold'', ``Italic'', etc) using a single font file.
+
+When a user-installed distortable font is found, each font that a
+previously discovered font provided will no longer be used.  In
+addition, any previously specified distortable fonts with the same
+family name are also removed.  When a conventional font is found, any
+previous conventional font with the same style and family will be
+removed; distortable fonts with the same family will no longer be
+used to provide that style.
+
 @node Android Troubleshooting
 @section What to do when something goes wrong on Android
 @cindex troubleshooting, android
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 99ba6bb1001..c9d48f640af 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -827,6 +827,63 @@ sfnt_grok_registry (int fd, struct sfnt_font_desc *desc,
   xfree (subtables);
 }
 
+/* Return whether or not the font description PREV conflicts with the
+   newer font description DESC, and should be removed from the list of
+   system fonts.
+
+   If PREV is a variable font, potentially adjust its list of
+   instances.  */
+
+static bool
+sfnt_replace_fonts_p (struct sfnt_font_desc *prev,
+                     struct sfnt_font_desc *desc)
+{
+  int i, width, weight, slant, count_instance;
+  Lisp_Object tem;
+  bool family_equal_p;
+
+  family_equal_p = !NILP (Fstring_equal (prev->family,
+                                        desc->family));
+
+  if ((!NILP (desc->instances)
+       || !NILP (Fstring_equal (prev->style, desc->style)))
+      && family_equal_p)
+    return true;
+
+  if (NILP (prev->instances) || !family_equal_p)
+    return false;
+
+  /* Look through instances in PREV to see if DESC provides the same
+     thing.  */
+
+  count_instance = 0;
+  for (i = 0; i < ASIZE (prev->instances); ++i)
+    {
+      tem = AREF (prev->instances, i);
+
+      if (NILP (tem))
+       continue;
+
+      width = XFIXNUM (AREF (tem, 2));
+      weight = XFIXNUM (AREF (tem, 3));
+      slant = XFIXNUM (AREF (tem, 4));
+
+      if (desc->width == width
+         && desc->weight == weight
+         && desc->slant == slant)
+       {
+         /* Remove this instance.  */
+         ASET (prev->instances, i, Qnil);
+         continue;
+       }
+
+      count_instance++;
+    }
+
+  /* Remove this desc if there are no more instances.  */
+  return count_instance < 1;
+}
+
 /* Enumerate the offset subtable SUBTABLES in the file FD, whose file
    name is FILE.  OFFSET should be the offset of the subtable within
    the font file, and is recorded for future use.  Value is 1 upon
@@ -959,14 +1016,15 @@ sfnt_enum_font_1 (int fd, const char *file,
   desc->next = system_fonts;
   system_fonts = desc;
 
-  /* Remove any fonts which have the same style as this one.  */
+  /* Remove any fonts which have the same style as this one.  For
+     distortable fonts, only remove overlapping styles, unless this is
+     also a distortable font.  */
 
   next = &system_fonts->next;
   prev = *next;
   for (; *next; prev = *next)
     {
-      if (!NILP (Fstring_equal (prev->style, desc->style))
-         && !NILP (Fstring_equal (prev->family, desc->family)))
+      if (sfnt_replace_fonts_p (prev, desc))
        {
          *next = prev->next;
          xfree (prev);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]