all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: When and how to register various font backends
Date: Fri, 14 Jun 2019 19:52:07 +0900	[thread overview]
Message-ID: <wla7ek30dk.wl-mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <83tvd1p4jm.fsf@gnu.org>

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

On Sat, 08 Jun 2019 04:40:45 +0900,
Eli Zaretskii wrote:
> 
> The question is how to implement this preference.  In the code that is
> currently on master, you will see one way of implementing it in
> w32fns.c, where the Windows code creates GUI frames (look in
> x-create-frame).  Basically, after determining whether Uniscribe was
> explicitly requested, this implementation registers or doesn't
> register Uniscribe for each new frame.  This means the backends to be
> available to a frame must be specified at frame creation time, or be
> known by that time.
> 
> Yamamoto-san suggested a slightly different way of implementing the
> same idea; I will let him explain his proposal in more detail.

Attached is my proposal.  The idea is to register all the drivers in
x-create-frame as before, but tweak the function font_update_drivers
(in font.c) so it only chooses "unsuperseded" drivers if the user did
not explicitly specify font backends (i.e., if NEW_DRIVERS is t).
Unlike Eli's current code in w32fns.c, this leaves the room to change
the font backend from uniscribe to harfbuzz (and vice versa) for the
same frame.  (You can't change xft/frcr to xfthb/ftcrhb on X
regardless of this patch because Bug#23386).

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp

[-- Attachment #2: font-driver-supersede.diff --]
[-- Type: application/octet-stream, Size: 8005 bytes --]

diff --git a/src/font.c b/src/font.c
index 5705758b99f..b786d623a77 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3518,7 +3518,8 @@ free_font_driver_list (struct frame *f)
 
 /* Make the frame F use font backends listed in NEW_DRIVERS (list of
    symbols, e.g. xft, x).  If NEW_DRIVERS is t, make F use all
-   available font drivers.  If NEW_DRIVERS is nil, finalize all drivers.
+   available font drivers that are not superseded by another driver.
+   If NEW_DRIVERS is nil, finalize all drivers.
 
    A caller must free all realized faces if any in advance.  The
    return value is a list of font backends actually made used on
@@ -3527,16 +3528,32 @@ free_font_driver_list (struct frame *f)
 Lisp_Object
 font_update_drivers (struct frame *f, Lisp_Object new_drivers)
 {
-  Lisp_Object active_drivers = Qnil;
+  Lisp_Object active_drivers = Qnil, default_drivers = Qnil;
   struct font_driver_list *list;
 
+  /* Collect all unsuperseded driver symbols into
+     `default_drivers'.  */
+  Lisp_Object all_drivers = Qnil;
+  for (list = f->font_driver_list; list; list = list->next)
+    all_drivers = Fcons (list->driver->type, all_drivers);
+  for (Lisp_Object rest = all_drivers; CONSP (rest); rest = XCDR (rest))
+    {
+      Lisp_Object superseded_by = Fget (XCAR (rest), Qfont_driver_superseded_by);
+
+      if (NILP (superseded_by)
+	  || NILP (Fmemq (superseded_by, all_drivers)))
+	default_drivers = Fcons (XCAR (rest), default_drivers);
+    }
+
+  if (EQ (new_drivers, Qt))
+    new_drivers = default_drivers;
+
   /* At first, turn off non-requested drivers, and turn on requested
      drivers.  */
   for (list = f->font_driver_list; list; list = list->next)
     {
       struct font_driver const *driver = list->driver;
-      if ((EQ (new_drivers, Qt) || ! NILP (Fmemq (driver->type, new_drivers)))
-	  != list->on)
+      if ((! NILP (Fmemq (driver->type, new_drivers))) != list->on)
 	{
 	  if (list->on)
 	    {
@@ -3559,8 +3576,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
 
   if (NILP (new_drivers))
     return Qnil;
-
-  if (! EQ (new_drivers, Qt))
+  else
     {
       /* Re-order the driver list according to new_drivers.  */
       struct font_driver_list **list_table, **next;
@@ -3599,6 +3615,8 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
 	    {
 	      struct font_driver const *driver = list->driver;
 	      eassert (! list->on);
+	      if (NILP (Fmemq (driver->type, default_drivers)))
+		continue;
 	      if (! driver->start_for_frame
 		  || driver->start_for_frame (f) == 0)
 		{
@@ -5359,6 +5377,8 @@ syms_of_font (void)
   DEFSYM (QL2R, "L2R");
   DEFSYM (QR2L, "R2L");
 
+  DEFSYM (Qfont_driver_superseded_by, "font-driver-superseded-by");
+
   scratch_font_spec = Ffont_spec (0, NULL);
   staticpro (&scratch_font_spec);
   scratch_font_prefer = Ffont_spec (0, NULL);
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 1c28a7ceb67..a019fe8294a 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -599,6 +599,7 @@ syms_of_ftcrfont (void)
   DEFSYM (Qftcr, "ftcr");
 #ifdef HAVE_HARFBUZZ
   DEFSYM (Qftcrhb, "ftcrhb");
+  Fput (Qftcr, Qfont_driver_superseded_by, Qftcrhb);
 #endif	/* HAVE_HARFBUZZ */
   pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
 }
diff --git a/src/ftfont.c b/src/ftfont.c
index efd0fcbd8c0..4380a48d8dc 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -2970,6 +2970,7 @@ syms_of_ftfont (void)
   DEFSYM (Qfreetype, "freetype");
 #ifdef HAVE_HARFBUZZ
   DEFSYM (Qfreetypehb, "freetypehb");
+  Fput (Qfreetype, Qfont_driver_superseded_by, Qfreetypehb);
 #endif	/* HAVE_HARFBUZZ */
 
   /* Fontconfig's generic families and their aliases.  */
diff --git a/src/w32fns.c b/src/w32fns.c
index 8ebfc119521..83830c616e5 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5844,46 +5844,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
       specbind (Qx_resource_name, name);
     }
 
-  bool register_uniscribe = uniscribe_available;
 #ifdef HAVE_HARFBUZZ
-  /* Register Uniscribe only if HarfBuzz is not available or if
-     explicitly requested.  If Uniscribe is registered, register
-     HarfBuzz only if explicitly requested.  */
-  bool register_harfbuzz = harfbuzz_available;
-  if (register_harfbuzz)
-    register_uniscribe = false;
-  Lisp_Object dflt_backends
-    = gui_display_get_arg (dpyinfo, parameters, Qfont_backend,
-			   "fontBackend", "FontBackend", RES_TYPE_STRING);
-  if (!EQ (dflt_backends, Qunbound))
-    {
-      bool harfbuzz_requested = false, uniscribe_requested = false;
-      if (CONSP (dflt_backends))
-	{
-	  if (!NILP (Fmemq (Quniscribe, dflt_backends)))
-	    uniscribe_requested = true;
-	  if (!NILP (Fmemq (Qharfbuzz, dflt_backends)))
-	    harfbuzz_requested = true;
-	}
-      else if (STRINGP (dflt_backends))
-	{
-	  if (strcmp (SSDATA (dflt_backends), "uniscribe") == 0)
-	    uniscribe_requested = true;
-	  else if (strcmp (SSDATA (dflt_backends), "harfbuzz") == 0)
-	    harfbuzz_requested = true;
-	}
-      if (uniscribe_requested)
-	{
-	  register_uniscribe = uniscribe_available;
-	  if (!harfbuzz_requested)
-	    register_harfbuzz = false;
-	}
-    }
-  if (register_harfbuzz)
-    register_font_driver (&harfbuzz_font_driver, f);
+  register_font_driver (&harfbuzz_font_driver, f);
 #endif
-  if (register_uniscribe)
-    register_font_driver (&uniscribe_font_driver, f);
+  register_font_driver (&uniscribe_font_driver, f);
   register_font_driver (&w32font_driver, f);
 
   gui_default_parameter (f, parameters, Qfont_backend, Qnil,
@@ -6935,46 +6899,10 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
       specbind (Qx_resource_name, name);
     }
 
-  bool register_uniscribe = uniscribe_available;
 #ifdef HAVE_HARFBUZZ
-  /* Register Uniscribe only if HarfBuzz is not available or if
-     explicitly requested.  If Uniscribe is registered, register
-     HarfBuzz only if explicitly requested.  */
-  bool register_harfbuzz = harfbuzz_available;
-  if (register_harfbuzz)
-    register_uniscribe = false;
-  Lisp_Object dflt_backends
-    = gui_display_get_arg (dpyinfo, parms, Qfont_backend,
-			   "fontBackend", "FontBackend", RES_TYPE_STRING);
-  if (!EQ (dflt_backends, Qunbound))
-    {
-      bool harfbuzz_requested = false, uniscribe_requested = false;
-      if (CONSP (dflt_backends))
-	{
-	  if (!NILP (Fmemq (Quniscribe, dflt_backends)))
-	    uniscribe_requested = true;
-	  if (!NILP (Fmemq (Qharfbuzz, dflt_backends)))
-	    harfbuzz_requested = true;
-	}
-      else if (STRINGP (dflt_backends))
-	{
-	  if (strcmp (SSDATA (dflt_backends), "uniscribe") == 0)
-	    uniscribe_requested = true;
-	  else if (strcmp (SSDATA (dflt_backends), "harfbuzz") == 0)
-	    harfbuzz_requested = true;
-	}
-      if (uniscribe_requested)
-	{
-	  register_uniscribe = uniscribe_available;
-	  if (!harfbuzz_requested)
-	    register_harfbuzz = false;
-	}
-    }
-  if (register_harfbuzz)
-    register_font_driver (&harfbuzz_font_driver, f);
+  register_font_driver (&harfbuzz_font_driver, f);
 #endif
-  if (register_uniscribe)
-    register_font_driver (&uniscribe_font_driver, f);
+  register_font_driver (&uniscribe_font_driver, f);
   register_font_driver (&w32font_driver, f);
 
   gui_default_parameter (f, parms, Qfont_backend, Qnil,
diff --git a/src/w32font.c b/src/w32font.c
index 14d49b24d9b..5d54f048fb5 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -2821,6 +2821,8 @@ versions of Windows) characters.  */);
 
   defsubr (&Sx_select_font);
 
+  Fput (Quniscribe, Qfont_driver_superseded_by, Qharfbuzz);
+
   pdumper_do_now_and_after_load (syms_of_w32font_for_pdumper);
 }
 
diff --git a/src/xftfont.c b/src/xftfont.c
index 04cda12fb52..4d2a5f520e0 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -679,6 +679,7 @@ syms_of_xftfont (void)
   DEFSYM (Qxft, "xft");
 #ifdef HAVE_HARFBUZZ
   DEFSYM (Qxfthb, "xfthb");
+  Fput (Qxft, Qfont_driver_superseded_by, Qxfthb);
 #endif	/* HAVE_HARFBUZZ */
 
   DEFVAR_BOOL ("xft-font-ascent-descent-override",

  parent reply	other threads:[~2019-06-14 10:52 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-07 19:40 When and how to register various font backends Eli Zaretskii
2019-06-14  9:14 ` Robert Pluim
2019-06-14 12:19   ` Eli Zaretskii
2019-06-14 13:16     ` Robert Pluim
2019-06-14 14:47       ` Eli Zaretskii
2019-06-15  9:50         ` Eli Zaretskii
2019-06-17  3:03           ` Michael Welsh Duggan
2019-06-17  9:41           ` Robert Pluim
2019-06-17 16:01             ` Eli Zaretskii
2019-06-18  1:29               ` YAMAMOTO Mitsuharu
2019-06-18 17:26                 ` Eli Zaretskii
2019-06-18 23:21                   ` YAMAMOTO Mitsuharu
2019-06-19 16:42                     ` Eli Zaretskii
2019-06-14 16:54     ` Andy Moreton
2019-06-14 10:52 ` YAMAMOTO Mitsuharu [this message]
2019-06-14 11:52   ` Robert Pluim
2019-06-14 12:26     ` Eli Zaretskii
2019-06-14 13:24       ` Robert Pluim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wla7ek30dk.wl-mituharu@math.s.chiba-u.ac.jp \
    --to=mituharu@math.s.chiba-u.ac.jp \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.