Commit fba3687d authored by Eli Zaretskii's avatar Eli Zaretskii

Add HarfBuzz font backend for MS-Windows

* src/w32uniscribe.c [HAVE_HARFBUZZ]: Include math.h and
hb.h.
(bswap_32): Define for GCC 4.3.0 and later; else include
<byteswap.h> from Gnulib.
(struct uniscribe_font_info): Extend for HarfBuzz; 'cache' is
now a 'void *' (all users changed).
[HAVE_HARFBUZZ]: Define typedefs for HarfBuzz functions to be
loaded dynamically from the HarfBuzz DLL.  Define macros to
call those functions via function pointers.
(uniscribe_open) [HAVE_HARFBUZZ]: Use the HarfBuzz font driver
if the type of the font entity is 'harfbuzz'.
(uniscribe_close) [HAVE_HARFBUZZ]: For fonts using the
HarfBuzz backend, call hb_font_destroy to free memory used for
the cached hb_font data.
(uniscribe_shape): Fix assignment of character codepoints to
glyphs from a single cluster.
(w32hb_list, w32hb_match, free_cb, w32hb_get_font_table)
(w32hb_get_font, w32hb_encode_char, w32hb_begin_font)
(w32uni_combining, w32uni_general, w32uni_mirroring)
(get_hb_unicode_funcs, w32hb_shape)
(w32hb_combining_capability, load_harfbuzz_funcs)
[HAVE_HARFBUZZ]: New functions.
(syms_of_w32uniscribe_for_pdumper) [HAVE_HARFBUZZ]: Load the
HarfBuzz DLL and register the HarfBuzz backend with its
functions.
* src/w32font.c (syms_of_w32font) <Qharfbuzz>: New DEFSYM.
* src/w32fns.c (Fx_create_frame, w32_create_tip_frame)
[HAVE_HARFBUZZ]: Register the harfbuzz font backend.
* src/lisp.h (get_unicode_property): Declare prototype.
* src/font.h (harfbuzz_font_driver) [HAVE_NTGUI]: Declare.
* src/chartab.c (get_unicode_property): New function, body
taken from get-unicode-property-internal.
(Fget_unicode_property_internal): Call get_unicode_property
after validating input.

* doc/lispref/frames.texi (Font and Color Parameters):
* doc/emacs/msdos.texi (Windows Fonts): Document support for
HarfBuzz text shaping on MS-Windows.

* configure.ac (HAVE_HARFBUZZ): Move out of the X-specific
part, and consider HarfBuzz also for HAVE_W32 systems.
Require HarfBuzz v1.2.3 for w32.
parent b40dde70
Pipeline #1841 failed with stage
in 67 minutes and 37 seconds
......@@ -3409,56 +3409,70 @@ if test "${HAVE_X11}" = "yes"; then
fi
fi # $HAVE_CAIRO != yes
HAVE_HARFBUZZ=no
HAVE_LIBOTF=no
if test "${HAVE_FREETYPE}" = "yes"; then
AC_DEFINE(HAVE_FREETYPE, 1,
[Define to 1 if using the freetype and fontconfig libraries.])
if test "${with_harfbuzz}" != "no"; then
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= 0.9.42])
if test "$HAVE_HARFBUZZ" = "yes"; then
AC_DEFINE(HAVE_HARFBUZZ, 1, [Define to 1 if using HarfBuzz.])
HAVE_LIBOTF=no
if test "${HAVE_FREETYPE}" = "yes"; then
AC_DEFINE(HAVE_FREETYPE, 1,
[Define to 1 if using the freetype and fontconfig libraries.])
if test "${with_libotf}" != "no"; then
EMACS_CHECK_MODULES([LIBOTF], [libotf])
if test "$HAVE_LIBOTF" = "yes"; then
AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
HAVE_OTF_GET_VARIATION_GLYPHS=yes,
HAVE_OTF_GET_VARIATION_GLYPHS=no)
if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
[Define to 1 if libotf has OTF_get_variation_glyphs.])
fi
fi
if test "${with_libotf}" != "no"; then
EMACS_CHECK_MODULES([LIBOTF], [libotf])
if test "$HAVE_LIBOTF" = "yes"; then
AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
HAVE_OTF_GET_VARIATION_GLYPHS=yes,
HAVE_OTF_GET_VARIATION_GLYPHS=no)
if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
[Define to 1 if libotf has OTF_get_variation_glyphs.])
fi
if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
AC_DEFINE(HAVE_OTF_KANNADA_BUG, 1,
if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
AC_DEFINE(HAVE_OTF_KANNADA_BUG, 1,
[Define to 1 if libotf is affected by https://debbugs.gnu.org/28110.])
fi
fi
fi
dnl FIXME should there be an error if HAVE_FREETYPE != yes?
dnl Does the new font backend require it, or can it work without it?
fi
dnl FIXME should there be an error if HAVE_FREETYPE != yes?
dnl Does the new font backend require it, or can it work without it?
fi
HAVE_M17N_FLT=no
if test "${HAVE_LIBOTF}" = yes; then
if test "${with_m17n_flt}" != "no"; then
EMACS_CHECK_MODULES([M17N_FLT], [m17n-flt])
if test "$HAVE_M17N_FLT" = "yes"; then
AC_DEFINE(HAVE_M17N_FLT, 1, [Define to 1 if using libm17n-flt.])
fi
HAVE_M17N_FLT=no
if test "${HAVE_LIBOTF}" = yes; then
if test "${with_m17n_flt}" != "no"; then
EMACS_CHECK_MODULES([M17N_FLT], [m17n-flt])
if test "$HAVE_M17N_FLT" = "yes"; then
AC_DEFINE(HAVE_M17N_FLT, 1, [Define to 1 if using libm17n-flt.])
fi
fi
else
HAVE_XFT=no
HAVE_FREETYPE=no
HAVE_HARFBUZZ=no
HAVE_LIBOTF=no
HAVE_M17N_FLT=no
fi
else # "${HAVE_X11}" != "yes"
HAVE_XFT=no
HAVE_FREETYPE=no
HAVE_LIBOTF=no
HAVE_M17N_FLT=no
fi # "${HAVE_X11}" != "yes"
HAVE_HARFBUZZ=no
if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
|| test "${HAVE_W32}" = "yes"; then
if test "${with_harfbuzz}" != "no"; then
### On MS-Windows we use hb_font_get_nominal_glyph, which appeared
### in HarfBuzz version 1.2.3
if test "${HAVE_W32}" = "yes"; then
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= 1.2.3])
else
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= 0.9.42])
fi
if test "$HAVE_HARFBUZZ" = "yes"; then
AC_DEFINE(HAVE_HARFBUZZ, 1, [Define to 1 if using HarfBuzz.])
### mingw32 and Cygwin-w32 don't use -lharfbuzz, since they load
### the library dynamically.
if test "${HAVE_W32}" = "yes"; then
HARFBUZZ_LIBS=
fi
fi
fi
fi
### End of font-backend (under X11) section.
### End of font-backend section.
AC_SUBST(FREETYPE_CFLAGS)
AC_SUBST(FREETYPE_LIBS)
......
......@@ -985,21 +985,28 @@ fontconfig library used in modern Free desktops:
The old XLFD based format is also supported for backwards compatibility.
@cindex font backend selection (MS-Windows)
Emacs 23 and later supports a number of font backends. Currently,
the @code{gdi} and @code{uniscribe} backends are supported on Windows.
The @code{gdi} font backend is available on all versions of Windows,
and supports all fonts that are natively supported by Windows. The
@code{uniscribe} font backend is available on Windows 2000 and later,
and supports TrueType and OpenType fonts. Some languages requiring
complex layout can only be properly supported by the Uniscribe
backend. By default, both backends are enabled if supported, with
@code{uniscribe} taking priority over @code{gdi}. To override that
and use the GDI backend even if Uniscribe is available, invoke Emacs
with the @kbd{-xrm Emacs.fontBackend:gdi} command-line argument, or
add a @code{Emacs.fontBackend} resource with the value @code{gdi} in
the Registry under either the
@samp{HKEY_CURRENT_USER\SOFTWARE\GNU\Emacs} or the
@samp{HKEY_LOCAL_MACHINE\SOFTWARE\GNU\Emacs} key (@pxref{Resources}).
Emacs on MS-Windows supports a number of font backends. Currently,
the @code{gdi}, @code{uniscribe}, and @code{harfbuzz} backends are
available. The @code{gdi} font backend is available on all versions
of Windows, and supports all fonts that are natively supported by
Windows. The @code{uniscribe} font backend is available on Windows
2000 and later, and supports TrueType and OpenType fonts. The
@code{harfbuzz} font backend is available if Emacs was built with
HarfBuzz support, and if the HarfBuzz DLL is installed on your system;
like @code{uniscribe}, this backend supports only TrueType and
OpenType fonts. Some languages requiring complex layout can only be
properly supported by the Uniscribe or HarfBuzz backends. By default,
all backends are enabled if supported, with @code{harfbuzz} taking
priority over @code{uniscribe}, and @code{uniscribe} taking priority
over @code{gdi}. To override that and use the GDI backend even if
Uniscribe is available, invoke Emacs with the @kbd{-xrm
Emacs.fontBackend:gdi} command-line argument, or add a
@code{Emacs.fontBackend} resource with the value @code{gdi} in the
Registry under either the @samp{HKEY_CURRENT_USER\SOFTWARE\GNU\Emacs}
or the @samp{HKEY_LOCAL_MACHINE\SOFTWARE\GNU\Emacs} key
(@pxref{Resources}). Similarly, to use the Uniscribe backend even if
HarfBuzz is available, use @kbd{-xrm Emacs.fontBackend:uniscribe} on
the command line that invokes Emacs.
@cindex font properties (MS Windows)
@noindent
......
......@@ -2278,18 +2278,21 @@ variable do not take effect immediately, only when you specify the
@vindex font-backend@r{, a frame parameter}
@item font-backend
A list of symbols, specifying the @dfn{font backends} to use for
drawing fonts in the frame, in order of priority. On X, there are
currently three available font backends if Emacs was built without the
Cairo drawing: @code{x} (the X core font driver), @code{xft} (the Xft
font driver), and @code{xfthb} (the Xft font driver with HarfBuzz text
shaping). If built with the Cairo drawing, then there are two
available font backends: @code{ftcr} (the FreeType font driver on
Cairo) and @code{ftcrhb} (the FreeType font driver on Cairo with
HarfBuzz text shaping). On MS-Windows, there are currently two
available font backends: @code{gdi} and @code{uniscribe}
(@pxref{Windows Fonts,,, emacs, The GNU Emacs Manual}). On other
systems, there is only one available font backend, so it does not make
sense to modify this frame parameter.
drawing characters on the frame, in order of priority. In Emacs built
without Cairo drawing on X, there are currently three available font
backends: @code{x} (the X core font driver), @code{xft} (the Xft font
driver), and @code{xfthb} (the Xft font driver with HarfBuzz text
shaping). If built with the Cairo drawing, there are two available
font backends on X: @code{ftcr} (the FreeType font driver on Cairo)
and @code{ftcrhb} (the FreeType font driver on Cairo with HarfBuzz
text shaping). On MS-Windows, there are currently three available
font backends: @code{gdi} (the core MS-Windows font driver),
@code{uniscribe} (font driver for OTF and TTF fonts with text shaping
by the Uniscribe engine), and @code{harfbuzz} (font driver for OTF and
TTF fonts with HarfBuzz text shaping) (@pxref{Windows Fonts,,, emacs,
The GNU Emacs Manual}). On other systems, there is only one available
font backend, so it does not make sense to modify this frame
parameter.
@vindex background-mode@r{, a frame parameter}
@item background-mode
......
......@@ -1321,22 +1321,25 @@ and put an element value. */)
return Fcdr (Fassq (prop, Vchar_code_property_alist));
}
Lisp_Object
get_unicode_property (Lisp_Object char_table, int ch)
{
Lisp_Object val = CHAR_TABLE_REF (char_table, ch);
uniprop_decoder_t decoder = uniprop_get_decoder (char_table);
return (decoder ? decoder (char_table, val) : val);
}
DEFUN ("get-unicode-property-internal", Fget_unicode_property_internal,
Sget_unicode_property_internal, 2, 2, 0,
doc: /* Return an element of CHAR-TABLE for character CH.
CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
(Lisp_Object char_table, Lisp_Object ch)
{
Lisp_Object val;
uniprop_decoder_t decoder;
CHECK_CHAR_TABLE (char_table);
CHECK_CHARACTER (ch);
if (! UNIPROP_TABLE_P (char_table))
error ("Invalid Unicode property table");
val = CHAR_TABLE_REF (char_table, XFIXNUM (ch));
decoder = uniprop_get_decoder (char_table);
return (decoder ? decoder (char_table, val) : val);
return get_unicode_property (char_table, XFIXNUM (ch));
}
DEFUN ("put-unicode-property-internal", Fput_unicode_property_internal,
......
......@@ -951,6 +951,9 @@ extern void syms_of_bdffont (void);
#ifdef HAVE_NTGUI
extern struct font_driver w32font_driver;
extern struct font_driver uniscribe_font_driver;
#ifdef HAVE_HARFBUZZ
extern struct font_driver harfbuzz_font_driver;
#endif
extern void syms_of_w32font (void);
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
......
......@@ -3994,6 +3994,7 @@ extern void map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Ob
Lisp_Object, struct charset *,
unsigned, unsigned);
extern Lisp_Object uniprop_table (Lisp_Object);
extern Lisp_Object get_unicode_property (Lisp_Object, int);
extern void syms_of_chartab (void);
/* Defined in print.c. */
......
......@@ -221,6 +221,7 @@ int menubar_in_use = 0;
/* From w32uniscribe.c */
extern void syms_of_w32uniscribe (void);
extern int uniscribe_available;
extern int harfbuzz_available;
#ifdef WINDOWSNT
/* From w32inevt.c */
......@@ -5843,6 +5844,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
specbind (Qx_resource_name, name);
}
#ifdef HAVE_HARFBUZZ
if (harfbuzz_available)
register_font_driver (&harfbuzz_font_driver, f);
#endif
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
......@@ -6896,6 +6901,10 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
specbind (Qx_resource_name, name);
}
#ifdef HAVE_HARFBUZZ
if (harfbuzz_available)
register_font_driver (&harfbuzz_font_driver, f);
#endif
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
......
......@@ -2634,6 +2634,7 @@ syms_of_w32font (void)
{
DEFSYM (Qgdi, "gdi");
DEFSYM (Quniscribe, "uniscribe");
DEFSYM (Qharfbuzz, "harfbuzz");
DEFSYM (QCformat, ":format");
/* Generic font families. */
......
This diff is collapsed.
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