support rendering of wider range of combinging characters by ftfont backend
* lisp/language/hebrew.el (hebrew-shape-gstring): If the font backend supports rendering of combining characters, call font-shape-gstring. * src/font.c (Ffont_get): Handle `combining-capability' property. (syms_of_font): New symbol ":combining-capability'. * src/font.h (struct font_driver): New member combining_capability. * src/ftfont.c: Include "category.h". (ftfont_driver): Initialize combining_capability to ftfont_combining_capability. (ftfont_shape_by_flt): If OTF is null, try to find a suitable FLT in advance. (ftfont_combining_capability): New function.
This commit is contained in:
parent
d259328fb8
commit
536f48e9a2
4 changed files with 72 additions and 29 deletions
|
@ -216,24 +216,26 @@ Bidirectional editing is supported.")))
|
|||
(setq idx 1 nglyphs nchars))
|
||||
;; Now IDX is an index to the first non-precomposed glyph.
|
||||
;; Adjust positions of the remaining glyphs artificially.
|
||||
(setq base-width (lglyph-width (lgstring-glyph gstring 0)))
|
||||
(while (< idx nglyphs)
|
||||
(setq glyph (lgstring-glyph gstring idx))
|
||||
(lglyph-set-from-to glyph 0 (1- nchars))
|
||||
(if (>= (lglyph-lbearing glyph) (lglyph-width glyph))
|
||||
;; It seems that this glyph is designed to be rendered
|
||||
;; before the base glyph.
|
||||
(lglyph-set-adjustment glyph (- base-width) 0 0)
|
||||
(if (>= (lglyph-lbearing glyph) 0)
|
||||
;; Align the horizontal center of this glyph to the
|
||||
;; horizontal center of the base glyph.
|
||||
(let ((width (- (lglyph-rbearing glyph)
|
||||
(lglyph-lbearing glyph))))
|
||||
(lglyph-set-adjustment glyph
|
||||
(- (/ (- base-width width) 2)
|
||||
(lglyph-lbearing glyph)
|
||||
base-width) 0 0))))
|
||||
(setq idx (1+ idx))))))
|
||||
(if (font-get font :combining-capability)
|
||||
(font-shape-gstring gstring)
|
||||
(setq base-width (lglyph-width (lgstring-glyph gstring 0)))
|
||||
(while (< idx nglyphs)
|
||||
(setq glyph (lgstring-glyph gstring idx))
|
||||
(lglyph-set-from-to glyph 0 (1- nchars))
|
||||
(if (>= (lglyph-lbearing glyph) (lglyph-width glyph))
|
||||
;; It seems that this glyph is designed to be rendered
|
||||
;; before the base glyph.
|
||||
(lglyph-set-adjustment glyph (- base-width) 0 0)
|
||||
(if (>= (lglyph-lbearing glyph) 0)
|
||||
;; Align the horizontal center of this glyph to the
|
||||
;; horizontal center of the base glyph.
|
||||
(let ((width (- (lglyph-rbearing glyph)
|
||||
(lglyph-lbearing glyph))))
|
||||
(lglyph-set-adjustment glyph
|
||||
(- (/ (- base-width width) 2)
|
||||
(lglyph-lbearing glyph)
|
||||
base-width) 0 0))))
|
||||
(setq idx (1+ idx)))))))
|
||||
gstring))
|
||||
|
||||
(let* ((base "[\u05D0-\u05F2]")
|
||||
|
|
27
src/font.c
27
src/font.c
|
@ -4036,7 +4036,13 @@ The value of :otf is a cons (GSUB . GPOS) where GSUB and GPOS are lists
|
|||
representing the OpenType features supported by the font by this form:
|
||||
((SCRIPT (LANGSYS FEATURE ...) ...) ...)
|
||||
SCRIPT, LANGSYS, and FEATURE are all symbols representing OpenType
|
||||
Layout tags. */)
|
||||
Layout tags.
|
||||
|
||||
In addition to the keys listed abobe, the following keys are reserved
|
||||
for the specific meanings as below:
|
||||
|
||||
The value of :combining-capability is non-nil if the font-backend of
|
||||
FONT supports rendering of combining characters for non-OTF fonts. */)
|
||||
(Lisp_Object font, Lisp_Object key)
|
||||
{
|
||||
int idx;
|
||||
|
@ -4051,14 +4057,22 @@ Layout tags. */)
|
|||
if (idx >= 0 && idx < FONT_EXTRA_INDEX)
|
||||
return AREF (font, idx);
|
||||
val = Fassq (key, AREF (font, FONT_EXTRA_INDEX));
|
||||
if (NILP (val) && EQ (key, QCotf) && FONT_OBJECT_P (font))
|
||||
if (NILP (val) && FONT_OBJECT_P (font))
|
||||
{
|
||||
struct font *fontp = XFONT_OBJECT (font);
|
||||
|
||||
if (fontp->driver->otf_capability)
|
||||
val = fontp->driver->otf_capability (fontp);
|
||||
else
|
||||
val = Fcons (Qnil, Qnil);
|
||||
if (EQ (key, QCotf))
|
||||
{
|
||||
if (fontp->driver->otf_capability)
|
||||
val = fontp->driver->otf_capability (fontp);
|
||||
else
|
||||
val = Fcons (Qnil, Qnil);
|
||||
}
|
||||
else if (EQ (key, QCcombining_capability))
|
||||
{
|
||||
if (fontp->driver->combining_capability)
|
||||
val = fontp->driver->combining_capability (fontp);
|
||||
}
|
||||
}
|
||||
else
|
||||
val = Fcdr (val);
|
||||
|
@ -5290,6 +5304,7 @@ syms_of_font (void)
|
|||
DEFSYM (QCscalable, ":scalable");
|
||||
DEFSYM (QCavgwidth, ":avgwidth");
|
||||
DEFSYM (QCfont_entity, ":font-entity");
|
||||
DEFSYM (QCcombining_capability, ":combining-capability");
|
||||
|
||||
/* Symbols representing values of font spacing property. */
|
||||
DEFSYM (Qc, "c");
|
||||
|
|
|
@ -715,6 +715,12 @@ struct font_driver
|
|||
bool (*cached_font_ok) (struct frame *f,
|
||||
Lisp_Object font_object,
|
||||
Lisp_Object entity);
|
||||
|
||||
/* Optional
|
||||
|
||||
Return non-nil if the driver support rendering of combining
|
||||
characters for FONT according to Unicode combining class. */
|
||||
Lisp_Object (*combining_capability) (struct font *font);
|
||||
};
|
||||
|
||||
|
||||
|
|
30
src/ftfont.c
30
src/ftfont.c
|
@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "dispextern.h"
|
||||
#include "character.h"
|
||||
#include "charset.h"
|
||||
#include "category.h"
|
||||
#include "composite.h"
|
||||
#include "font.h"
|
||||
#include "ftfont.h"
|
||||
|
@ -81,6 +82,8 @@ static Lisp_Object ftfont_lookup_cache (Lisp_Object,
|
|||
|
||||
static void ftfont_filter_properties (Lisp_Object font, Lisp_Object alist);
|
||||
|
||||
static Lisp_Object ftfont_combining_capability (struct font *);
|
||||
|
||||
#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
|
||||
|
||||
static struct
|
||||
|
@ -547,6 +550,10 @@ struct font_driver ftfont_driver =
|
|||
#endif
|
||||
|
||||
ftfont_filter_properties, /* filter_properties */
|
||||
|
||||
NULL, /* cached_font_ok */
|
||||
|
||||
ftfont_combining_capability,
|
||||
};
|
||||
|
||||
static Lisp_Object
|
||||
|
@ -2533,7 +2540,7 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
|
|||
|
||||
len = i;
|
||||
|
||||
if (with_variation_selector)
|
||||
if (otf && with_variation_selector)
|
||||
{
|
||||
setup_otf_gstring (len);
|
||||
for (i = 0; i < len; i++)
|
||||
|
@ -2583,14 +2590,19 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
|
|||
flt_font_ft.otf = otf;
|
||||
flt_font_ft.matrix = matrix->xx != 0 ? matrix : 0;
|
||||
|
||||
if (1 < len)
|
||||
if (1 < len || ! otf)
|
||||
{
|
||||
/* A little bit ad hoc. Perhaps, shaper must get script and
|
||||
language information, and select a proper flt for them
|
||||
here. */
|
||||
int c1 = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 1));
|
||||
if (0x300 <= c1 && c1 <= 0x36F)
|
||||
if (CHAR_HAS_CATEGORY (c1, '^'))
|
||||
flt = mflt_get (msymbol ("combining"));
|
||||
else if (! otf)
|
||||
flt = mflt_find (LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 0)),
|
||||
&flt_font_ft.flt_font);
|
||||
if (! flt)
|
||||
return make_number (0);
|
||||
}
|
||||
|
||||
MFLTGlyphFT *glyphs = (MFLTGlyphFT *) gstring.glyphs;
|
||||
|
@ -2675,8 +2687,6 @@ ftfont_shape (Lisp_Object lgstring)
|
|||
struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
|
||||
OTF *otf = ftfont_get_otf (ftfont_info);
|
||||
|
||||
if (! otf)
|
||||
return make_number (0);
|
||||
return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, otf,
|
||||
&ftfont_info->matrix);
|
||||
}
|
||||
|
@ -2750,6 +2760,16 @@ ftfont_filter_properties (Lisp_Object font, Lisp_Object alist)
|
|||
}
|
||||
|
||||
|
||||
static Lisp_Object
|
||||
ftfont_combining_capability (struct font *font)
|
||||
{
|
||||
#ifdef HAVE_M17N_FLT
|
||||
return Qt;
|
||||
#else
|
||||
return Qnil;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_ftfont (void)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue