diff options
author | K. Handa <handa@gnu.org> | 2016-01-02 16:36:21 +0900 |
---|---|---|
committer | K. Handa <handa@gnu.org> | 2016-01-02 16:36:21 +0900 |
commit | 536f48e9a2251b9e654ea974bd90ff2f40218753 (patch) | |
tree | fa48333ec65910b24ffab90f2dda3d200fb56215 | |
parent | d259328fb87db8cc67d52771efcfa653e52c5b71 (diff) |
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.
-rw-r--r-- | lisp/language/hebrew.el | 38 | ||||
-rw-r--r-- | src/font.c | 27 | ||||
-rw-r--r-- | src/font.h | 6 | ||||
-rw-r--r-- | src/ftfont.c | 30 |
4 files changed, 72 insertions, 29 deletions
diff --git a/lisp/language/hebrew.el b/lisp/language/hebrew.el index a3f4b3dd99..05f2f2521f 100644 --- a/lisp/language/hebrew.el +++ b/lisp/language/hebrew.el @@ -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]") diff --git a/src/font.c b/src/font.c index 016b7e0a88..6fa599524c 100644 --- a/src/font.c +++ b/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"); diff --git a/src/font.h b/src/font.h index 1d13e1cb6b..f6f862ac7d 100644 --- a/src/font.h +++ b/src/font.h @@ -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); }; diff --git a/src/ftfont.c b/src/ftfont.c index 17e41a9339..575bf53701 100644 --- a/src/ftfont.c +++ b/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) { |