Support font driver supersession

* src/font.c (font_update_drivers): If argument NEW_DRIVERS is t, then don't
use superseded drivers.
(syms_of_font) <Qfont_driver_superseded_by>: New DEFSYM.

* src/ftfont.c (syms_of_ftfont) [HAVE_HARFBUZZ]:
* src/ftcrfont.c (syms_of_ftcrfont) [HAVE_HARFBUZZ]:
* src/w32font.c (syms_of_w32font) [HAVE_HARFBUZZ]:
* src/xftfont.c (syms_of_xftfont) [HAVE_HARFBUZZ]: Make Harfbuzz variants
supersede non-Harfbuzz ones.

* src/w32fns.c (Fx_create_frame, w32_create_tip_frame): Remove font backend
determination code.
This commit is contained in:
YAMAMOTO Mitsuharu 2019-06-18 10:19:40 +09:00
parent 56a90c4234
commit 64767008f7
6 changed files with 38 additions and 82 deletions

View file

@ -3518,7 +3518,10 @@ 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.
(A font driver SYMBOL is superseded by the driver specified by
SYMBOL's 'font-driver-superseded-by property if it is a non-nil
symbol.) 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 +3530,33 @@ 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 +3579,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 +3618,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 +5380,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);

View file

@ -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);
}

View file

@ -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. */

View file

@ -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,

View file

@ -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);
}

View file

@ -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",