]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve rules for enumerating user fonts
authorPo Lu <luangruo@yahoo.com>
Wed, 29 Mar 2023 12:14:43 +0000 (20:14 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 29 Mar 2023 12:14:43 +0000 (20:14 +0800)
* 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
src/sfntfont.c

index c92700980defb2f9a0dddc935465e36ca4e992d3..97f72e98ceee2b774155cc823c442151428cf17f 100644 (file)
@@ -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
index 99ba6bb10016abf8392446e744ef29a53ca0556e..c9d48f640af4f9671c8d06503ef402a73798df45 100644 (file)
@@ -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);