emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 536f48e 1/2: support rendering of wider range of co


From: Kenichi Handa
Subject: [Emacs-diffs] master 536f48e 1/2: support rendering of wider range of combinging characters by ftfont backend
Date: Sun, 03 Jan 2016 08:54:29 +0000

branch: master
commit 536f48e9a2251b9e654ea974bd90ff2f40218753
Author: K. Handa <address@hidden>
Commit: K. Handa <address@hidden>

    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.
---
 lisp/language/hebrew.el |   38 ++++++++++++++++++++------------------
 src/font.c              |   27 +++++++++++++++++++++------
 src/font.h              |    6 ++++++
 src/ftfont.c            |   30 +++++++++++++++++++++++++-----
 4 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/lisp/language/hebrew.el b/lisp/language/hebrew.el
index a3f4b3d..05f2f25 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 016b7e0..6fa5995 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 1d13e1c..f6f862a 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 17e41a9..575bf53 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)
 {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]