Add new font backend drivers for text shaping by HarfBuzz
* etc/NEWS: Mention new font backend drivers xfthb and ftcrhb. * src/font.h [HAVE_HARFBUZZ]: Include hb.h. (struct font_driver) [HAVE_HARFBUZZ]: New members begin_hb_font and end_hb_font. (ftfont_match, ftfont_list): Remove externs. (ftfont_match2, ftfont_list2): (fthbfont_combining_capability, fthbfont_begin_hb_font) (fthbfont_shape) [HAVE_HARFBUZZ]: (xfthbfont_driver) [HAVE_XFT && HAVE_HARFBUZZ]: (ftcrhbfont_driver) [USE_CAIRO && HAVE_HARFBUZZ]: Add externs. * src/ftcrfont.c (ftcrfont_list): Use ftfont_list2. (ftcrfont_match): Use ftfont_match2. (ftcrfont_open): Get font type from entity. (ftcrfont_open) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified. (ftcrfont_shape) [HAVE_HARFBUZZ]: Make shaping fail. (ftcrhbfont_list, ftcrhbfont_match) (ftcrhbfont_begin_hb_font) [HAVE_HARFBUZZ]: New functions. (ftcrhbfont_driver) [HAVE_HARFBUZZ]: New variable. (syms_of_ftcrfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register it. (syms_of_ftcrfont) [HAVE_HARFBUZZ]: New symbol Qftcrhb. * src/ftfont.c: Include math.h for lround. (fthbfont_driver) [HAVE_HARFBUZZ]: New variable. (ftfont_get_hb_font) [HAVE_HARFBUZZ]: Remove function. (ftfont_list, ftfont_match): Make static. (ftfont_list2, ftfont_match2): New functions. (ftfont_open2) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified. (ftfont_open): Get font type from entity. (ftfont_shape, ftfont_combining_capability, ftfont_driver) [HAVE_HARFBUZZ]: Move HarfBuzz specific part from here ... (fthbfont_shape, fthbfont_combining_capability) (fthbfont_driver) [HAVE_HARFBUZZ]: ... to here. New functions and variable. (fthbfont_begin_hb_font) [HAVE_HARFBUZZ]: New function. (fthbfont_shape_by_hb) [HAVE_HARFBUZZ]: Rename from ftfont_shape_by_hb. Don't take FreeType specific arguments ft_face and matrix. Use begin_hb_font and end_hb_font font driver functions. Use text_extents font driver functions instead of ftfont_glyph_metrics. (syms_of_ftfont) [HAVE_HARFBUZZ]: New symbol Qfreetypehb. (syms_of_ftfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register fthbfont_drivert. * src/ftxfont.c (ftxfont_list): Use ftfont_list2. (ftxfont_match): Use ftfont_match2. (ftxfont_driver) [HAVE_HARFBUZZ]: Don't initialize shape member explicitly. * src/xfns.c (Fx_create_frame) [USE_CAIRO && HAVE_HARFBUZZ]: (Fx_create_frame) [HAVE_XFT && HAVE_HARFBUZZ]: Register HarfBuzz versions of font drivers. * src/xftfont.c (xftfont_list): Use ftfont_list2. (xftfont_match): Use ftfont_match2. (xftfont_open): Get font type from entity. (xftfont_open) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified. (xftfont_shape) [HAVE_HARFBUZZ]: Make shaping fail. (xfthbfont_list, xfthbfont_match, xfthbfont_begin_hb_font) (xfthbfont_end_hb_font) [HAVE_HARFBUZZ]: New functions. (xftfont_driver) [HAVE_HARFBUZZ]: Don't initialize shape member explicitly. (xfthbfont_driver) [HAVE_HARFBUZZ]: New variable. (syms_of_xftfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register it. (syms_of_xftfont) [HAVE_HARFBUZZ]: New symbol Qxfthb.
This commit is contained in:
parent
27511b9821
commit
f208d5ae77
7 changed files with 276 additions and 101 deletions
4
etc/NEWS
4
etc/NEWS
|
@ -32,7 +32,9 @@ suitable libgmp is available.
|
|||
|
||||
** The new configure option '--with-harfbuzz' adds support for the
|
||||
HarfBuzz text shaping engine. It is on by default; use './configure
|
||||
--without-harfbuzz' to build without it.
|
||||
--without-harfbuzz' to build without it. The HarfBuzz text shaping is
|
||||
available via new font backend drivers 'xfthb' and 'ftcrhb' for Xft
|
||||
and Cairo drawings, respectively.
|
||||
|
||||
** The new configure option '--with-json' adds support for JSON using
|
||||
the Jansson library. It is on by default; use './configure
|
||||
|
|
34
src/font.h
34
src/font.h
|
@ -22,6 +22,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#ifndef EMACS_FONT_H
|
||||
#define EMACS_FONT_H
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
#include <hb.h>
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
struct composition_it;
|
||||
struct face;
|
||||
struct glyph_string;
|
||||
|
@ -780,6 +784,21 @@ struct font_driver
|
|||
relies on this hook to throw away its old XftDraw (which won't
|
||||
work after the size change) and get a new one. */
|
||||
void (*drop_xrender_surfaces) (struct frame *f);
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
/* Optional.
|
||||
Return a HarfBuzz font object for FONT and store to
|
||||
*POSITION_UNIT the scale factor to convert a hb_position_t value
|
||||
to the number of pixels. Return NULL if HarfBuzz font object is
|
||||
not available for FONT. */
|
||||
hb_font_t *(*begin_hb_font) (struct font *font, double *position_unit);
|
||||
|
||||
/* Optional.
|
||||
Called when the return value (passed as HB_FONT) of begin_hb_font
|
||||
above is no longer used. Not called if the return value of
|
||||
begin_hb_font was NULL. */
|
||||
void (*end_hb_font) (struct font *font, hb_font_t *hb_font);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
};
|
||||
|
||||
|
||||
|
@ -892,9 +911,9 @@ extern int ftfont_has_char (Lisp_Object, int);
|
|||
extern int ftfont_variation_glyphs (struct font *, int, unsigned[256]);
|
||||
extern Lisp_Object ftfont_combining_capability (struct font *);
|
||||
extern Lisp_Object ftfont_get_cache (struct frame *);
|
||||
extern Lisp_Object ftfont_list (struct frame *, Lisp_Object);
|
||||
extern Lisp_Object ftfont_list2 (struct frame *, Lisp_Object, Lisp_Object);
|
||||
extern Lisp_Object ftfont_list_family (struct frame *);
|
||||
extern Lisp_Object ftfont_match (struct frame *, Lisp_Object);
|
||||
extern Lisp_Object ftfont_match2 (struct frame *, Lisp_Object, Lisp_Object);
|
||||
extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
|
||||
extern Lisp_Object ftfont_otf_capability (struct font *);
|
||||
extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object);
|
||||
|
@ -903,6 +922,11 @@ extern void ftfont_close (struct font *);
|
|||
extern void ftfont_filter_properties (Lisp_Object, Lisp_Object);
|
||||
extern void ftfont_text_extents (struct font *, unsigned *, int,
|
||||
struct font_metrics *);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
extern Lisp_Object fthbfont_combining_capability (struct font *);
|
||||
extern hb_font_t *fthbfont_begin_hb_font (struct font *, double *);
|
||||
extern Lisp_Object fthbfont_shape (Lisp_Object, Lisp_Object);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
extern void syms_of_ftfont (void);
|
||||
#endif /* HAVE_FREETYPE */
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
|
@ -912,6 +936,9 @@ extern void syms_of_xfont (void);
|
|||
extern void syms_of_ftxfont (void);
|
||||
#ifdef HAVE_XFT
|
||||
extern struct font_driver const xftfont_driver;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
extern struct font_driver xfthbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
#endif
|
||||
#if defined HAVE_FREETYPE || defined HAVE_XFT
|
||||
extern struct font_driver const ftxfont_driver;
|
||||
|
@ -933,6 +960,9 @@ extern void syms_of_macfont (void);
|
|||
#endif /* HAVE_NS */
|
||||
#ifdef USE_CAIRO
|
||||
extern struct font_driver const ftcrfont_driver;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
extern struct font_driver ftcrhbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
extern void syms_of_ftcrfont (void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -98,21 +98,13 @@ ftcrfont_glyph_extents (struct font *font,
|
|||
static Lisp_Object
|
||||
ftcrfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object list = ftfont_list (f, spec), tail;
|
||||
|
||||
for (tail = list; CONSP (tail); tail = XCDR (tail))
|
||||
ASET (XCAR (tail), FONT_TYPE_INDEX, Qftcr);
|
||||
return list;
|
||||
return ftfont_list2 (f, spec, Qftcr);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftcrfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object entity = ftfont_match (f, spec);
|
||||
|
||||
if (VECTORP (entity))
|
||||
ASET (entity, FONT_TYPE_INDEX, Qftcr);
|
||||
return entity;
|
||||
return ftfont_match2 (f, spec, Qftcr);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
|
@ -124,7 +116,8 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
if (size == 0)
|
||||
size = pixel_size;
|
||||
font_object = font_build_object (VECSIZE (struct font_info),
|
||||
Qftcr, entity, size);
|
||||
AREF (entity, FONT_TYPE_INDEX),
|
||||
entity, size);
|
||||
block_input ();
|
||||
font_object = ftfont_open2 (f, entity, pixel_size, font_object);
|
||||
if (FONT_OBJECT_P (font_object))
|
||||
|
@ -133,6 +126,11 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
struct font_info *ftcrfont_info = (struct font_info *) font;
|
||||
FT_Face ft_face = ftcrfont_info->ft_size->face;
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qftcrhb))
|
||||
font->driver = &ftcrhbfont_driver;
|
||||
else
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
font->driver = &ftcrfont_driver;
|
||||
FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw);
|
||||
FT_Activate_Size (ftcrfont_info->ft_size_draw);
|
||||
|
@ -291,7 +289,7 @@ ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
|
|||
static Lisp_Object
|
||||
ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction)
|
||||
{
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
|
||||
struct font_info *ftcrfont_info = (struct font_info *) font;
|
||||
|
||||
|
@ -361,6 +359,39 @@ ftcrfont_draw (struct glyph_string *s,
|
|||
return len;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
|
||||
static Lisp_Object
|
||||
ftcrhbfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
return ftfont_list2 (f, spec, Qftcrhb);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftcrhbfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
return ftfont_match2 (f, spec, Qftcrhb);
|
||||
}
|
||||
|
||||
static hb_font_t *
|
||||
ftcrhbfont_begin_hb_font (struct font *font, double *position_unit)
|
||||
{
|
||||
struct font_info *ftcrfont_info = (struct font_info *) font;
|
||||
|
||||
FT_Activate_Size (ftcrfont_info->ft_size_draw);
|
||||
hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit);
|
||||
int i = ftcrfont_info->bitmap_strike_index;
|
||||
if (i >= 0)
|
||||
{
|
||||
FT_Face ft_face = ftcrfont_info->ft_size_draw->face;
|
||||
*position_unit = ((double) font->height
|
||||
/ ft_face->available_sizes[i].height) / (1 << 6);
|
||||
}
|
||||
|
||||
return hb_font;
|
||||
}
|
||||
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
|
||||
static void syms_of_ftcrfont_for_pdumper (void);
|
||||
|
@ -390,11 +421,17 @@ struct font_driver const ftcrfont_driver =
|
|||
.filter_properties = ftfont_filter_properties,
|
||||
.combining_capability = ftfont_combining_capability,
|
||||
};
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
struct font_driver ftcrhbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
void
|
||||
syms_of_ftcrfont (void)
|
||||
{
|
||||
DEFSYM (Qftcr, "ftcr");
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
DEFSYM (Qftcrhb, "ftcrhb");
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
|
||||
}
|
||||
|
||||
|
@ -402,4 +439,14 @@ static void
|
|||
syms_of_ftcrfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&ftcrfont_driver, NULL);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
ftcrhbfont_driver = ftcrfont_driver;
|
||||
ftcrhbfont_driver.type = Qftcrhb;
|
||||
ftcrhbfont_driver.list = ftcrhbfont_list;
|
||||
ftcrhbfont_driver.match = ftcrhbfont_match;
|
||||
ftcrhbfont_driver.shape = fthbfont_shape;
|
||||
ftcrhbfont_driver.combining_capability = fthbfont_combining_capability;
|
||||
ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font;
|
||||
register_font_driver (&ftcrhbfont_driver, NULL);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
}
|
||||
|
|
172
src/ftfont.c
172
src/ftfont.c
|
@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
|
||||
|
@ -48,6 +49,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "pdumper.h"
|
||||
|
||||
static struct font_driver const ftfont_driver;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
static struct font_driver fthbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
/* Flag to tell if FcInit is already called or not. */
|
||||
static bool fc_initialized;
|
||||
|
@ -466,19 +470,6 @@ ftfont_get_otf (struct font_info *ftfont_info)
|
|||
}
|
||||
#endif /* HAVE_LIBOTF */
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
|
||||
static hb_font_t *
|
||||
ftfont_get_hb_font (struct font_info *ftfont_info)
|
||||
{
|
||||
if (! ftfont_info->hb_font)
|
||||
ftfont_info->hb_font
|
||||
= hb_ft_font_create_referenced (ftfont_info->ft_size->face);
|
||||
return ftfont_info->hb_font;
|
||||
}
|
||||
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
Lisp_Object
|
||||
ftfont_get_cache (struct frame *f)
|
||||
{
|
||||
|
@ -801,7 +792,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
|
|||
return pattern;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
static Lisp_Object
|
||||
ftfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object val = Qnil, family, adstyle;
|
||||
|
@ -1001,6 +992,16 @@ ftfont_list (struct frame *f, Lisp_Object spec)
|
|||
}
|
||||
|
||||
Lisp_Object
|
||||
ftfont_list2 (struct frame *f, Lisp_Object spec, Lisp_Object type)
|
||||
{
|
||||
Lisp_Object list = ftfont_list (f, spec);
|
||||
|
||||
for (Lisp_Object tail = list; CONSP (tail); tail = XCDR (tail))
|
||||
ASET (XCAR (tail), FONT_TYPE_INDEX, type);
|
||||
return list;
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object entity = Qnil;
|
||||
|
@ -1050,6 +1051,16 @@ ftfont_match (struct frame *f, Lisp_Object spec)
|
|||
return entity;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
ftfont_match2 (struct frame *f, Lisp_Object spec, Lisp_Object type)
|
||||
{
|
||||
Lisp_Object entity = ftfont_match (f, spec);
|
||||
|
||||
if (! NILP (entity))
|
||||
ASET (entity, FONT_TYPE_INDEX, type);
|
||||
return entity;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
ftfont_list_family (struct frame *f)
|
||||
{
|
||||
|
@ -1185,6 +1196,11 @@ ftfont_open2 (struct frame *f,
|
|||
/* This means that there's no need of transformation. */
|
||||
ftfont_info->matrix.xx = 0;
|
||||
font->pixel_size = size;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qfreetypehb))
|
||||
font->driver = &fthbfont_driver;
|
||||
else
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
font->driver = &ftfont_driver;
|
||||
font->encoding_charset = font->repertory_charset = -1;
|
||||
|
||||
|
@ -1266,7 +1282,8 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
if (size == 0)
|
||||
size = pixel_size;
|
||||
font_object = font_build_object (VECSIZE (struct font_info),
|
||||
Qfreetype, entity, size);
|
||||
AREF (entity, FONT_TYPE_INDEX),
|
||||
entity, size);
|
||||
font_object = ftfont_open2 (f, entity, pixel_size, font_object);
|
||||
if (FONT_OBJECT_P (font_object))
|
||||
{
|
||||
|
@ -2673,6 +2690,17 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
|
|||
return make_fixnum (i);
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
ftfont_shape (Lisp_Object lgstring)
|
||||
{
|
||||
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
|
||||
struct font_info *ftfont_info = (struct font_info *) font;
|
||||
OTF *otf = ftfont_get_otf (ftfont_info);
|
||||
|
||||
return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, otf,
|
||||
&ftfont_info->matrix);
|
||||
}
|
||||
|
||||
#endif /* HAVE_M17N_FLT */
|
||||
|
||||
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
|
||||
|
@ -2693,6 +2721,18 @@ ftfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
|
|||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
|
||||
hb_font_t *
|
||||
fthbfont_begin_hb_font (struct font *font, double *position_unit)
|
||||
{
|
||||
struct font_info *ftfont_info = (struct font_info *) font;
|
||||
|
||||
*position_unit = 1.0 / (1 << 6);
|
||||
if (! ftfont_info->hb_font)
|
||||
ftfont_info->hb_font
|
||||
= hb_ft_font_create_referenced (ftfont_info->ft_size->face);
|
||||
return ftfont_info->hb_font;
|
||||
}
|
||||
|
||||
static hb_unicode_combining_class_t
|
||||
uni_combining (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data)
|
||||
{
|
||||
|
@ -2818,8 +2858,8 @@ get_hb_unicode_funcs (void)
|
|||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
|
||||
FT_Matrix *matrix, Lisp_Object direction)
|
||||
fthbfont_shape_by_hb (Lisp_Object lgstring, struct font *font,
|
||||
Lisp_Object direction)
|
||||
{
|
||||
ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring);
|
||||
ptrdiff_t i;
|
||||
|
@ -2892,7 +2932,15 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
|
|||
above. FIXME: drop once script handling is fixed above. */
|
||||
hb_buffer_guess_segment_properties (hb_buffer);
|
||||
|
||||
if (!hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL))
|
||||
double position_unit;
|
||||
hb_font_t *hb_font = font->driver->begin_hb_font (font, &position_unit);
|
||||
if (!hb_font)
|
||||
return make_fixnum (0);
|
||||
|
||||
hb_bool_t success = hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL);
|
||||
if (font->driver->end_hb_font)
|
||||
font->driver->end_hb_font (font, hb_font);
|
||||
if (!success)
|
||||
return Qnil;
|
||||
|
||||
glyph_len = hb_buffer_get_length (hb_buffer);
|
||||
|
@ -2913,7 +2961,8 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
|
|||
{
|
||||
Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
|
||||
EMACS_INT from, to;
|
||||
int advance = 0, lbearing, rbearing, ascent, descent;
|
||||
struct font_metrics metrics = {.width = 0};
|
||||
int xoff, yoff, wadjust;
|
||||
ptrdiff_t j = i;
|
||||
|
||||
if (NILP (lglyph))
|
||||
|
@ -2936,61 +2985,46 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
|
|||
LGLYPH_SET_CHAR (lglyph, LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, from)));
|
||||
LGLYPH_SET_CODE (lglyph, info[i].codepoint);
|
||||
|
||||
if (ftfont_glyph_metrics (ft_face, info[i].codepoint, &advance, &lbearing,
|
||||
&rbearing, &ascent, &descent))
|
||||
{
|
||||
LGLYPH_SET_WIDTH (lglyph, advance);
|
||||
LGLYPH_SET_LBEARING (lglyph, lbearing);
|
||||
LGLYPH_SET_RBEARING (lglyph, rbearing);
|
||||
LGLYPH_SET_ASCENT (lglyph, ascent);
|
||||
LGLYPH_SET_DESCENT (lglyph, descent);
|
||||
}
|
||||
unsigned code = info[i].codepoint;
|
||||
font->driver->text_extents (font, &code, 1, &metrics);
|
||||
LGLYPH_SET_WIDTH (lglyph, metrics.width);
|
||||
LGLYPH_SET_LBEARING (lglyph, metrics.lbearing);
|
||||
LGLYPH_SET_RBEARING (lglyph, metrics.rbearing);
|
||||
LGLYPH_SET_ASCENT (lglyph, metrics.ascent);
|
||||
LGLYPH_SET_DESCENT (lglyph, metrics.descent);
|
||||
|
||||
if (pos[i].x_offset || pos[i].y_offset ||
|
||||
(pos[i].x_advance >> 6) != advance)
|
||||
{
|
||||
Lisp_Object vec = make_uninit_vector (3);
|
||||
ASET (vec, 0, make_fixnum (pos[i].x_offset >> 6));
|
||||
ASET (vec, 1, make_fixnum (-(pos[i].y_offset >> 6)));
|
||||
ASET (vec, 2, make_fixnum (pos[i].x_advance >> 6));
|
||||
LGLYPH_SET_ADJUSTMENT (lglyph, vec);
|
||||
}
|
||||
xoff = lround (pos[i].x_offset * position_unit);
|
||||
yoff = - lround (pos[i].y_offset * position_unit);
|
||||
wadjust = lround (pos[i].x_advance * position_unit);
|
||||
if (xoff || yoff || wadjust != metrics.width)
|
||||
{
|
||||
Lisp_Object vec = make_uninit_vector (3);
|
||||
ASET (vec, 0, make_fixnum (xoff));
|
||||
ASET (vec, 1, make_fixnum (yoff));
|
||||
ASET (vec, 2, make_fixnum (wadjust));
|
||||
LGLYPH_SET_ADJUSTMENT (lglyph, vec);
|
||||
}
|
||||
}
|
||||
|
||||
return make_fixnum (glyph_len);
|
||||
}
|
||||
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
Lisp_Object
|
||||
fthbfont_combining_capability (struct font *font)
|
||||
{
|
||||
return Qt;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
ftfont_shape (Lisp_Object lgstring, Lisp_Object direction)
|
||||
fthbfont_shape (Lisp_Object lgstring, Lisp_Object direction)
|
||||
{
|
||||
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
|
||||
struct font_info *ftfont_info = (struct font_info *) font;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
if (getenv ("EMACS_NO_HARFBUZZ") == NULL)
|
||||
{
|
||||
hb_font_t *hb_font = ftfont_get_hb_font (ftfont_info);
|
||||
|
||||
return ftfont_shape_by_hb (lgstring, ftfont_info->ft_size->face,
|
||||
hb_font, &ftfont_info->matrix, direction);
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
{
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
OTF *otf = ftfont_get_otf (ftfont_info);
|
||||
|
||||
return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face,
|
||||
otf, &ftfont_info->matrix);
|
||||
#endif /* defined HAVE_M17N_FLT && defined HAVE_LIBOTF */
|
||||
}
|
||||
return make_fixnum (0);
|
||||
return fthbfont_shape_by_hb (lgstring, font, direction);
|
||||
}
|
||||
|
||||
#endif /* (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ */
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
static const char *const ftfont_booleans [] = {
|
||||
":antialias",
|
||||
|
@ -3046,7 +3080,7 @@ ftfont_filter_properties (Lisp_Object font, Lisp_Object alist)
|
|||
Lisp_Object
|
||||
ftfont_combining_capability (struct font *font)
|
||||
{
|
||||
#if defined HAVE_M17N_FLT || defined HAVE_HARFBUZZ
|
||||
#ifdef HAVE_M17N_FLT
|
||||
return Qt;
|
||||
#else
|
||||
return Qnil;
|
||||
|
@ -3073,7 +3107,7 @@ static struct font_driver const ftfont_driver =
|
|||
#ifdef HAVE_LIBOTF
|
||||
.otf_capability = ftfont_otf_capability,
|
||||
#endif
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
.shape = ftfont_shape,
|
||||
#endif
|
||||
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
|
||||
|
@ -3082,12 +3116,18 @@ static struct font_driver const ftfont_driver =
|
|||
.filter_properties = ftfont_filter_properties,
|
||||
.combining_capability = ftfont_combining_capability,
|
||||
};
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
static struct font_driver fthbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
void
|
||||
syms_of_ftfont (void)
|
||||
{
|
||||
/* Symbolic type of this font-driver. */
|
||||
DEFSYM (Qfreetype, "freetype");
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
DEFSYM (Qfreetypehb, "freetypehb");
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
/* Fontconfig's generic families and their aliases. */
|
||||
DEFSYM (Qmonospace, "monospace");
|
||||
|
@ -3114,4 +3154,12 @@ syms_of_ftfont_for_pdumper (void)
|
|||
{
|
||||
PDUMPER_RESET_LV (ft_face_cache, Qnil);
|
||||
register_font_driver (&ftfont_driver, NULL);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
fthbfont_driver = ftfont_driver;
|
||||
fthbfont_driver.type = Qfreetypehb;
|
||||
fthbfont_driver.shape = fthbfont_shape;
|
||||
fthbfont_driver.combining_capability = fthbfont_combining_capability;
|
||||
fthbfont_driver.begin_hb_font = fthbfont_begin_hb_font;
|
||||
register_font_driver (&fthbfont_driver, NULL);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
}
|
||||
|
|
|
@ -209,21 +209,13 @@ ftxfont_draw_background (struct frame *f, struct font *font, GC gc, int x, int y
|
|||
static Lisp_Object
|
||||
ftxfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object list = ftfont_list (f, spec), tail;
|
||||
|
||||
for (tail = list; CONSP (tail); tail = XCDR (tail))
|
||||
ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx);
|
||||
return list;
|
||||
return ftfont_list2 (f, spec, Qftx);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
ftxfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object entity = ftfont_match (f, spec);
|
||||
|
||||
if (VECTORP (entity))
|
||||
ASET (entity, FONT_TYPE_INDEX, Qftx);
|
||||
return entity;
|
||||
return ftfont_match2 (f, spec, Qftx);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
|
@ -362,7 +354,7 @@ struct font_driver const ftxfont_driver =
|
|||
.otf_capability = ftfont_otf_capability,
|
||||
#endif
|
||||
.end_for_frame = ftxfont_end_for_frame,
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
.shape = ftfont_shape,
|
||||
#endif
|
||||
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
|
||||
|
|
|
@ -3774,10 +3774,16 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
|
||||
#ifdef USE_CAIRO
|
||||
register_font_driver (&ftcrfont_driver, f);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
register_font_driver (&ftcrhbfont_driver, f);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
#else
|
||||
#ifdef HAVE_FREETYPE
|
||||
#ifdef HAVE_XFT
|
||||
register_font_driver (&xftfont_driver, f);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
register_font_driver (&xfthbfont_driver, f);
|
||||
#endif
|
||||
#else /* not HAVE_XFT */
|
||||
register_font_driver (&ftxfont_driver, f);
|
||||
#endif /* not HAVE_XFT */
|
||||
|
|
|
@ -108,21 +108,13 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc,
|
|||
static Lisp_Object
|
||||
xftfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object list = ftfont_list (f, spec);
|
||||
|
||||
for (Lisp_Object tail = list; CONSP (tail); tail = XCDR (tail))
|
||||
ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft);
|
||||
return list;
|
||||
return ftfont_list2 (f, spec, Qxft);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
xftfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
Lisp_Object entity = ftfont_match (f, spec);
|
||||
|
||||
if (! NILP (entity))
|
||||
ASET (entity, FONT_TYPE_INDEX, Qxft);
|
||||
return entity;
|
||||
return ftfont_match2 (f, spec, Qxft);
|
||||
}
|
||||
|
||||
static FcChar8 ascii_printable[95];
|
||||
|
@ -311,10 +303,16 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
/* We should not destroy PAT here because it is kept in XFTFONT and
|
||||
destroyed automatically when XFTFONT is closed. */
|
||||
font_object = font_build_object (VECSIZE (struct font_info),
|
||||
Qxft, entity, size);
|
||||
AREF (entity, FONT_TYPE_INDEX),
|
||||
entity, size);
|
||||
ASET (font_object, FONT_FILE_INDEX, filename);
|
||||
font = XFONT_OBJECT (font_object);
|
||||
font->pixel_size = size;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qxfthb))
|
||||
font->driver = &xfthbfont_driver;
|
||||
else
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
font->driver = &xftfont_driver;
|
||||
font->encoding_charset = font->repertory_charset = -1;
|
||||
|
||||
|
@ -649,7 +647,7 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
|
|||
return len;
|
||||
}
|
||||
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
static Lisp_Object
|
||||
xftfont_shape (Lisp_Object lgstring, Lisp_Object direction)
|
||||
{
|
||||
|
@ -739,6 +737,41 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
|
|||
return ok;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
|
||||
static Lisp_Object
|
||||
xfthbfont_list (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
return ftfont_list2 (f, spec, Qxfthb);
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
xfthbfont_match (struct frame *f, Lisp_Object spec)
|
||||
{
|
||||
return ftfont_match2 (f, spec, Qxfthb);
|
||||
}
|
||||
|
||||
static hb_font_t *
|
||||
xfthbfont_begin_hb_font (struct font *font, double *position_unit)
|
||||
{
|
||||
struct font_info *xftfont_info = (struct font_info *) font;
|
||||
FT_Face ft_face = XftLockFace (xftfont_info->xftfont);
|
||||
|
||||
xftfont_info->ft_size = ft_face->size;
|
||||
|
||||
return fthbfont_begin_hb_font (font, position_unit);
|
||||
}
|
||||
|
||||
static void
|
||||
xfthbfont_end_hb_font (struct font *font, hb_font_t *hb_font)
|
||||
{
|
||||
struct font_info *xftfont_info = (struct font_info *) font;
|
||||
|
||||
XftUnlockFace (xftfont_info->xftfont);
|
||||
}
|
||||
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
static void syms_of_xftfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const xftfont_driver =
|
||||
|
@ -763,7 +796,7 @@ struct font_driver const xftfont_driver =
|
|||
.otf_capability = ftfont_otf_capability,
|
||||
#endif
|
||||
.end_for_frame = xftfont_end_for_frame,
|
||||
#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
|
||||
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
|
||||
.shape = xftfont_shape,
|
||||
#endif
|
||||
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
|
||||
|
@ -774,11 +807,17 @@ struct font_driver const xftfont_driver =
|
|||
.combining_capability = ftfont_combining_capability,
|
||||
.drop_xrender_surfaces = xftfont_drop_xrender_surfaces,
|
||||
};
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
struct font_driver xfthbfont_driver;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
void
|
||||
syms_of_xftfont (void)
|
||||
{
|
||||
DEFSYM (Qxft, "xft");
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
DEFSYM (Qxfthb, "xfthb");
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
DEFSYM (QChinting, ":hinting");
|
||||
DEFSYM (QCautohint, ":autohint");
|
||||
DEFSYM (QChintstyle, ":hintstyle");
|
||||
|
@ -799,4 +838,15 @@ static void
|
|||
syms_of_xftfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&xftfont_driver, NULL);
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
xfthbfont_driver = xftfont_driver;
|
||||
xfthbfont_driver.type = Qxfthb;
|
||||
xfthbfont_driver.list = xfthbfont_list;
|
||||
xfthbfont_driver.match = xfthbfont_match;
|
||||
xfthbfont_driver.shape = fthbfont_shape;
|
||||
xfthbfont_driver.combining_capability = fthbfont_combining_capability;
|
||||
xfthbfont_driver.begin_hb_font = xfthbfont_begin_hb_font;
|
||||
xfthbfont_driver.end_hb_font = xfthbfont_end_hb_font;
|
||||
register_font_driver (&xfthbfont_driver, NULL);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue