Commit 64767008 authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu

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.
parent 56a90c42
Pipeline #2139 failed with stage
in 50 minutes and 42 seconds
...@@ -3518,7 +3518,10 @@ free_font_driver_list (struct frame *f) ...@@ -3518,7 +3518,10 @@ free_font_driver_list (struct frame *f)
/* Make the frame F use font backends listed in NEW_DRIVERS (list of /* 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 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 A caller must free all realized faces if any in advance. The
return value is a list of font backends actually made used on return value is a list of font backends actually made used on
...@@ -3527,16 +3530,33 @@ free_font_driver_list (struct frame *f) ...@@ -3527,16 +3530,33 @@ free_font_driver_list (struct frame *f)
Lisp_Object Lisp_Object
font_update_drivers (struct frame *f, Lisp_Object new_drivers) 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; 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 /* At first, turn off non-requested drivers, and turn on requested
drivers. */ drivers. */
for (list = f->font_driver_list; list; list = list->next) for (list = f->font_driver_list; list; list = list->next)
{ {
struct font_driver const *driver = list->driver; struct font_driver const *driver = list->driver;
if ((EQ (new_drivers, Qt) || ! NILP (Fmemq (driver->type, new_drivers))) if ((! NILP (Fmemq (driver->type, new_drivers))) != list->on)
!= list->on)
{ {
if (list->on) if (list->on)
{ {
...@@ -3559,8 +3579,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers) ...@@ -3559,8 +3579,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
if (NILP (new_drivers)) if (NILP (new_drivers))
return Qnil; return Qnil;
else
if (! EQ (new_drivers, Qt))
{ {
/* Re-order the driver list according to new_drivers. */ /* Re-order the driver list according to new_drivers. */
struct font_driver_list **list_table, **next; struct font_driver_list **list_table, **next;
...@@ -3599,6 +3618,8 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers) ...@@ -3599,6 +3618,8 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
{ {
struct font_driver const *driver = list->driver; struct font_driver const *driver = list->driver;
eassert (! list->on); eassert (! list->on);
if (NILP (Fmemq (driver->type, default_drivers)))
continue;
if (! driver->start_for_frame if (! driver->start_for_frame
|| driver->start_for_frame (f) == 0) || driver->start_for_frame (f) == 0)
{ {
...@@ -5359,6 +5380,8 @@ syms_of_font (void) ...@@ -5359,6 +5380,8 @@ syms_of_font (void)
DEFSYM (QL2R, "L2R"); DEFSYM (QL2R, "L2R");
DEFSYM (QR2L, "R2L"); DEFSYM (QR2L, "R2L");
DEFSYM (Qfont_driver_superseded_by, "font-driver-superseded-by");
scratch_font_spec = Ffont_spec (0, NULL); scratch_font_spec = Ffont_spec (0, NULL);
staticpro (&scratch_font_spec); staticpro (&scratch_font_spec);
scratch_font_prefer = Ffont_spec (0, NULL); scratch_font_prefer = Ffont_spec (0, NULL);
......
...@@ -599,6 +599,7 @@ syms_of_ftcrfont (void) ...@@ -599,6 +599,7 @@ syms_of_ftcrfont (void)
DEFSYM (Qftcr, "ftcr"); DEFSYM (Qftcr, "ftcr");
#ifdef HAVE_HARFBUZZ #ifdef HAVE_HARFBUZZ
DEFSYM (Qftcrhb, "ftcrhb"); DEFSYM (Qftcrhb, "ftcrhb");
Fput (Qftcr, Qfont_driver_superseded_by, Qftcrhb);
#endif /* HAVE_HARFBUZZ */ #endif /* HAVE_HARFBUZZ */
pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper); pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
} }
......
...@@ -2970,6 +2970,7 @@ syms_of_ftfont (void) ...@@ -2970,6 +2970,7 @@ syms_of_ftfont (void)
DEFSYM (Qfreetype, "freetype"); DEFSYM (Qfreetype, "freetype");
#ifdef HAVE_HARFBUZZ #ifdef HAVE_HARFBUZZ
DEFSYM (Qfreetypehb, "freetypehb"); DEFSYM (Qfreetypehb, "freetypehb");
Fput (Qfreetype, Qfont_driver_superseded_by, Qfreetypehb);
#endif /* HAVE_HARFBUZZ */ #endif /* HAVE_HARFBUZZ */
/* Fontconfig's generic families and their aliases. */ /* Fontconfig's generic families and their aliases. */
......
...@@ -5844,46 +5844,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, ...@@ -5844,46 +5844,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
specbind (Qx_resource_name, name); specbind (Qx_resource_name, name);
} }
bool register_uniscribe = uniscribe_available;
#ifdef HAVE_HARFBUZZ #ifdef HAVE_HARFBUZZ
/* Register Uniscribe only if HarfBuzz is not available or if register_font_driver (&harfbuzz_font_driver, f);
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);
#endif #endif
if (register_uniscribe) register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f); register_font_driver (&w32font_driver, f);
gui_default_parameter (f, parameters, Qfont_backend, Qnil, gui_default_parameter (f, parameters, Qfont_backend, Qnil,
...@@ -6935,46 +6899,10 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) ...@@ -6935,46 +6899,10 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
specbind (Qx_resource_name, name); specbind (Qx_resource_name, name);
} }
bool register_uniscribe = uniscribe_available;
#ifdef HAVE_HARFBUZZ #ifdef HAVE_HARFBUZZ
/* Register Uniscribe only if HarfBuzz is not available or if register_font_driver (&harfbuzz_font_driver, f);
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);
#endif #endif
if (register_uniscribe) register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f); register_font_driver (&w32font_driver, f);
gui_default_parameter (f, parms, Qfont_backend, Qnil, gui_default_parameter (f, parms, Qfont_backend, Qnil,
......
...@@ -2821,6 +2821,8 @@ versions of Windows) characters. */); ...@@ -2821,6 +2821,8 @@ versions of Windows) characters. */);
defsubr (&Sx_select_font); defsubr (&Sx_select_font);
Fput (Quniscribe, Qfont_driver_superseded_by, Qharfbuzz);
pdumper_do_now_and_after_load (syms_of_w32font_for_pdumper); pdumper_do_now_and_after_load (syms_of_w32font_for_pdumper);
} }
......
...@@ -679,6 +679,7 @@ syms_of_xftfont (void) ...@@ -679,6 +679,7 @@ syms_of_xftfont (void)
DEFSYM (Qxft, "xft"); DEFSYM (Qxft, "xft");
#ifdef HAVE_HARFBUZZ #ifdef HAVE_HARFBUZZ
DEFSYM (Qxfthb, "xfthb"); DEFSYM (Qxfthb, "xfthb");
Fput (Qxft, Qfont_driver_superseded_by, Qxfthb);
#endif /* HAVE_HARFBUZZ */ #endif /* HAVE_HARFBUZZ */
DEFVAR_BOOL ("xft-font-ascent-descent-override", DEFVAR_BOOL ("xft-font-ascent-descent-override",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment