diff options
| author | K. Handa <handa@gnu.org> | 2017-10-08 11:48:01 +0900 |
|---|---|---|
| committer | K. Handa <handa@gnu.org> | 2017-10-08 11:48:01 +0900 |
| commit | 64baaff8c5f70b7d637ac37304c4377e955b3f09 (patch) | |
| tree | 54922ceb5d3b828685fb487656e495acac3b9518 /lisp/language | |
| parent | 7a1133f1ff002943ce32b5a05a7261bba520288c (diff) | |
| download | emacs-64baaff8c5f70b7d637ac37304c4377e955b3f09.tar.gz | |
New option for handling ZWNJ in Arabic text rendering
Provide a new option 'arabic-shaper-ZWNJ-handling' that controls how
to display ZWNJ in Arabic text rendering (Bug#28339).
* lisp/language/misc-lang.el: Register arabic-shape-gstring in
composition-function-table.
(arabic-shaper-ZWNJ-handling): New variable.
(arabic-shape-log): New variable.
(arabic-shape-gstring): New function.
* lisp/composite.el (lgstring-remove-glyph): New function.
Diffstat (limited to 'lisp/language')
| -rw-r--r-- | lisp/language/misc-lang.el | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/lisp/language/misc-lang.el b/lisp/language/misc-lang.el index 2843c7c9038..f6179dc1fbf 100644 --- a/lisp/language/misc-lang.el +++ b/lisp/language/misc-lang.el @@ -75,12 +75,70 @@ and Italian."))) (sample-text . "Persian فارسی") (documentation . "Bidirectional editing is supported."))) +(defcustom arabic-shaper-ZWNJ-handling nil + "How to handle ZWMJ in Arabic text renderling. +This variable controls the way to handle a glyph for ZWNJ +returned by the underling shaping engine. + +The default value is nil, which means that the ZWNJ glyph is +displayed as is. + +If the value is `absorb', ZWNJ is absorbed into the previous +grapheme cluster, and not displayed. + +If the value is `as-space', the glyph is displayed by a +thin (i.e. 1-dot width) space. + +Customizing the value takes effect when you start Emacs next time." + :group 'mule + :version "26.1" + :type '(choice + (const :tag "default" nil) + (const :tag "as space" as-space) + (const :tag "absorb" absorb))) + +;; Record error in arabic-change-gstring. +(defvar arabic-shape-log nil) + +(defun arabic-shape-gstring (gstring) + (setq gstring (font-shape-gstring gstring)) + (condition-case err + (when arabic-shaper-ZWNJ-handling + (let ((font (lgstring-font gstring)) + (i 1) + (len (lgstring-glyph-len gstring)) + (modified nil)) + (while (< i len) + (let ((glyph (lgstring-glyph gstring i))) + (when (eq (lglyph-char glyph) #x200c) + (cond + ((eq arabic-shaper-ZWNJ-handling 'as-space) + (if (> (- (lglyph-rbearing glyph) (lglyph-lbearing glyph)) 0) + (let ((space-glyph (aref (font-get-glyphs font 0 1 " ") 0))) + (when space-glyph + (lglyph-set-code glyph (aref space-glyph 3)) + (lglyph-set-width glyph (aref space-glyph 4))))) + (lglyph-set-adjustment glyph 0 0 1) + (setq modified t)) + ((eq arabic-shaper-ZWNJ-handling 'absorb) + (let ((prev (lgstring-glyph gstring (1- i)))) + (lglyph-set-from-to prev (lglyph-from prev) (lglyph-to glyph)) + (setq gstring (lgstring-remove-glyph gstring i)) + (setq len (1- len))) + (setq modified t))))) + (setq i (1+ i))) + (if modified + (lgstring-set-id gstring nil)))) + (error (push err arabic-shape-log))) + gstring) + (set-char-table-range composition-function-table '(#x600 . #x74F) - (list (vector "[\u0600-\u074F\u200C\u200D]+" 0 'font-shape-gstring) - (vector "[\u200C\u200D][\u0600-\u074F\u200C\u200D]+" - 1 'font-shape-gstring))) + (list (vector "[\u0600-\u074F\u200C\u200D]+" 0 + 'arabic-shape-gstring) + (vector "[\u200C\u200D][\u0600-\u074F\u200C\u200D]+" 1 + 'arabic-shape-gstring))) (provide 'misc-lang) |
