aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2018-12-29 16:35:09 +0200
committerEli Zaretskii2018-12-29 16:35:09 +0200
commit48776b70115edf3775df19d80f734048dadff198 (patch)
tree10a7e72a45bbbdf8dbfed4afce59fc9a5b975110 /src
parent1a80b5d9b8cfa0e523b596db5d1e7e6074dbee46 (diff)
downloademacs-48776b70115edf3775df19d80f734048dadff198.tar.gz
emacs-48776b70115edf3775df19d80f734048dadff198.zip
Provide text directionality and language to HarfBuzz shaper
* lisp/language/tv-util.el (tai-viet-composition-function): * lisp/language/ethio-util.el (ethio-composition-function): * lisp/language/japanese.el (compose-gstring-for-variation-glyph): * lisp/language/thai-util.el (thai-composition-function): * lisp/language/misc-lang.el (arabic-shape-gstring): * lisp/language/lao-util.el (lao-composition-function): * lisp/language/hebrew.el (hebrew-shape-gstring): * lisp/composite.el (compose-gstring-for-graphic) (compose-gstring-for-dotted-circle, auto-compose-chars) (compose-gstring-for-terminal): Accept 2nd argument DIRECTION; all callers changed. * src/composite.c (composition_reseat_it): Call auto-composition-function with one more argument DIRECTION. (syms_of_composite) <auto-composition-function>: Update the doc string. * src/ftfont.c (ftfont_shape_by_hb): Compute language and direction, and set buffer properties accordingly. * src/composite.c (autocmp_chars): * src/w32uniscribe.c (uniscribe_shape): * src/xftfont.c (xftfont_shape): * src/ftfont.c (ftfont_shape, ftfont_shape_by_hb): * src/font.c (Ffont_shape_gstring): Accept an additional argument DIRECTION. * src/macfont.m (lgstring_direction): New enum. (mac_font_shape_1, mac_screen_font_shape, mac_font_shape): Accept an additional argument specifying text direction. All callers changed. * src/font.c (syms_of_font): New symbols QL2R and QR2L. * src/font.h (shape): Accept new argument DIRECTION. All implementations changed. (Bug#33729) (ftfont_shape): Update prototype.
Diffstat (limited to 'src')
-rw-r--r--src/composite.c28
-rw-r--r--src/font.c16
-rw-r--r--src/font.h13
-rw-r--r--src/ftfont.c41
-rw-r--r--src/macfont.m31
-rw-r--r--src/w32uniscribe.c7
-rw-r--r--src/xftfont.c4
7 files changed, 104 insertions, 36 deletions
diff --git a/src/composite.c b/src/composite.c
index 9819805c399..48824946e64 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -873,7 +873,7 @@ fill_gstring_body (Lisp_Object gstring)
873static Lisp_Object 873static Lisp_Object
874autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, 874autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos,
875 ptrdiff_t limit, struct window *win, struct face *face, 875 ptrdiff_t limit, struct window *win, struct face *face,
876 Lisp_Object string) 876 Lisp_Object string, Lisp_Object direction)
877{ 877{
878 ptrdiff_t count = SPECPDL_INDEX (); 878 ptrdiff_t count = SPECPDL_INDEX ();
879 Lisp_Object pos = make_fixnum (charpos); 879 Lisp_Object pos = make_fixnum (charpos);
@@ -920,8 +920,9 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos,
920 if (NILP (string)) 920 if (NILP (string))
921 record_unwind_protect (restore_point_unwind, 921 record_unwind_protect (restore_point_unwind,
922 build_marker (current_buffer, pt, pt_byte)); 922 build_marker (current_buffer, pt, pt_byte));
923 lgstring = safe_call (6, Vauto_composition_function, AREF (rule, 2), 923 lgstring = safe_call (7, Vauto_composition_function, AREF (rule, 2),
924 pos, make_fixnum (to), font_object, string); 924 pos, make_fixnum (to), font_object, string,
925 direction);
925 } 926 }
926 return unbind_to (count, lgstring); 927 return unbind_to (count, lgstring);
927} 928}
@@ -1221,7 +1222,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
1221 if (XFIXNAT (AREF (elt, 1)) != cmp_it->lookback) 1222 if (XFIXNAT (AREF (elt, 1)) != cmp_it->lookback)
1222 goto no_composition; 1223 goto no_composition;
1223 lgstring = autocmp_chars (elt, charpos, bytepos, endpos, 1224 lgstring = autocmp_chars (elt, charpos, bytepos, endpos,
1224 w, face, string); 1225 w, face, string, QL2R);
1225 if (composition_gstring_p (lgstring)) 1226 if (composition_gstring_p (lgstring))
1226 break; 1227 break;
1227 lgstring = Qnil; 1228 lgstring = Qnil;
@@ -1246,7 +1247,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
1246 bpos = CHAR_TO_BYTE (cpos); 1247 bpos = CHAR_TO_BYTE (cpos);
1247 } 1248 }
1248 lgstring = autocmp_chars (elt, cpos, bpos, charpos + 1, w, face, 1249 lgstring = autocmp_chars (elt, cpos, bpos, charpos + 1, w, face,
1249 string); 1250 string, QR2L);
1250 if (! composition_gstring_p (lgstring) 1251 if (! composition_gstring_p (lgstring)
1251 || cpos + LGSTRING_CHAR_LEN (lgstring) - 1 != charpos) 1252 || cpos + LGSTRING_CHAR_LEN (lgstring) - 1 != charpos)
1252 /* Composition failed or didn't cover the current 1253 /* Composition failed or didn't cover the current
@@ -1566,7 +1567,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit,
1566 for (check = cur; check_pos < check.pos; ) 1567 for (check = cur; check_pos < check.pos; )
1567 BACKWARD_CHAR (check, stop); 1568 BACKWARD_CHAR (check, stop);
1568 *gstring = autocmp_chars (elt, check.pos, check.pos_byte, 1569 *gstring = autocmp_chars (elt, check.pos, check.pos_byte,
1569 tail, w, NULL, string); 1570 tail, w, NULL, string, Qnil);
1570 need_adjustment = 1; 1571 need_adjustment = 1;
1571 if (NILP (*gstring)) 1572 if (NILP (*gstring))
1572 { 1573 {
@@ -1943,15 +1944,24 @@ Use the command `auto-composition-mode' to change this variable. */);
1943 1944
1944 DEFVAR_LISP ("auto-composition-function", Vauto_composition_function, 1945 DEFVAR_LISP ("auto-composition-function", Vauto_composition_function,
1945 doc: /* Function to call to compose characters automatically. 1946 doc: /* Function to call to compose characters automatically.
1946This function is called from the display routine with four arguments: 1947This function is called from the display engine with 6 arguments:
1947FROM, TO, WINDOW, and STRING. 1948FUNC, FROM, TO, FONT-OBJECT, STRING, and DIRECTION.
1949
1950FUNC is the function to compose characters. On text-mode display,
1951FUNC is ignored and `compose-gstring-for-terminal' is used instead.
1948 1952
1949If STRING is nil, the function must compose characters in the region 1953If STRING is nil, the function must compose characters in the region
1950between FROM and TO in the current buffer. 1954between FROM and TO in the current buffer.
1951 1955
1952Otherwise, STRING is a string, and FROM and TO are indices into the 1956Otherwise, STRING is a string, and FROM and TO are indices into the
1953string. In this case, the function must compose characters in the 1957string. In this case, the function must compose characters in the
1954string. */); 1958string.
1959
1960FONT-OBJECT is the font to use, or nil if characters are to be
1961composed on a text-mode display.
1962
1963DIRECTION is the bidi directionality of the text to shape. It could
1964be L2R or R2L, or nil if unknown. */);
1955 Vauto_composition_function = Qnil; 1965 Vauto_composition_function = Qnil;
1956 1966
1957 DEFVAR_LISP ("composition-function-table", Vcomposition_function_table, 1967 DEFVAR_LISP ("composition-function-table", Vcomposition_function_table,
diff --git a/src/font.c b/src/font.c
index e81c267de41..fc8efa7f235 100644
--- a/src/font.c
+++ b/src/font.c
@@ -4397,18 +4397,22 @@ font_fill_lglyph_metrics (Lisp_Object glyph, Lisp_Object font_object)
4397} 4397}
4398 4398
4399 4399
4400DEFUN ("font-shape-gstring", Ffont_shape_gstring, Sfont_shape_gstring, 1, 1, 0, 4400DEFUN ("font-shape-gstring", Ffont_shape_gstring, Sfont_shape_gstring, 2, 2, 0,
4401 doc: /* Shape the glyph-string GSTRING. 4401 doc: /* Shape the glyph-string GSTRING subject to bidi DIRECTION.
4402Shaping means substituting glyphs and/or adjusting positions of glyphs 4402Shaping means substituting glyphs and/or adjusting positions of glyphs
4403to get the correct visual image of character sequences set in the 4403to get the correct visual image of character sequences set in the
4404header of the glyph-string. 4404header of the glyph-string.
4405 4405
4406DIRECTION should be produced by the UBA, the Unicode Bidirectional
4407Algorithm, and should be a symbol, either L2R or R2L. It can also
4408be nil if the bidi context is unknown.
4409
4406If the shaping was successful, the value is GSTRING itself or a newly 4410If the shaping was successful, the value is GSTRING itself or a newly
4407created glyph-string. Otherwise, the value is nil. 4411created glyph-string. Otherwise, the value is nil.
4408 4412
4409See the documentation of `composition-get-gstring' for the format of 4413See the documentation of `composition-get-gstring' for the format of
4410GSTRING. */) 4414GSTRING. */)
4411 (Lisp_Object gstring) 4415 (Lisp_Object gstring, Lisp_Object direction)
4412{ 4416{
4413 struct font *font; 4417 struct font *font;
4414 Lisp_Object font_object, n, glyph; 4418 Lisp_Object font_object, n, glyph;
@@ -4427,7 +4431,7 @@ GSTRING. */)
4427 /* Try at most three times with larger gstring each time. */ 4431 /* Try at most three times with larger gstring each time. */
4428 for (i = 0; i < 3; i++) 4432 for (i = 0; i < 3; i++)
4429 { 4433 {
4430 n = font->driver->shape (gstring); 4434 n = font->driver->shape (gstring, direction);
4431 if (FIXNUMP (n)) 4435 if (FIXNUMP (n))
4432 break; 4436 break;
4433 gstring = larger_vector (gstring, 4437 gstring = larger_vector (gstring,
@@ -5350,6 +5354,10 @@ syms_of_font (void)
5350 5354
5351 DEFSYM (QCuser_spec, ":user-spec"); 5355 DEFSYM (QCuser_spec, ":user-spec");
5352 5356
5357 /* For shapers that need to know text directionality. */
5358 DEFSYM (QL2R, "L2R");
5359 DEFSYM (QR2L, "R2L");
5360
5353 staticpro (&scratch_font_spec); 5361 staticpro (&scratch_font_spec);
5354 scratch_font_spec = Ffont_spec (0, NULL); 5362 scratch_font_spec = Ffont_spec (0, NULL);
5355 staticpro (&scratch_font_prefer); 5363 staticpro (&scratch_font_prefer);
diff --git a/src/font.h b/src/font.h
index 1741b3f3964..52bdaa38899 100644
--- a/src/font.h
+++ b/src/font.h
@@ -700,7 +700,11 @@ struct font_driver
700 700
701 Return the number of output codes. If none of the features are 701 Return the number of output codes. If none of the features are
702 applicable to the input data, return 0. If GSTRING-OUT is too 702 applicable to the input data, return 0. If GSTRING-OUT is too
703 short, return -1. */ 703 short, return -1.
704
705 Note: This method is currently not implemented by any font
706 back-end, and is only called by 'font-drive-otf' and
707 'font-otf-alternates', which are themselves ifdef'ed away. */
704 int (*otf_drive) (struct font *font, Lisp_Object features, 708 int (*otf_drive) (struct font *font, Lisp_Object features,
705 Lisp_Object gstring_in, int from, int to, 709 Lisp_Object gstring_in, int from, int to,
706 Lisp_Object gstring_out, int idx, bool alternate_subst); 710 Lisp_Object gstring_out, int idx, bool alternate_subst);
@@ -723,6 +727,9 @@ struct font_driver
723 (N+1)th element of GSTRING is nil, input of shaping is from the 727 (N+1)th element of GSTRING is nil, input of shaping is from the
724 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and 728 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and
725 CODE are already set. 729 CODE are already set.
730 DIRECTION is either L2R or R2L, or nil if unknown. During
731 redisplay, this comes from applying the UBA, is passed from
732 composition_reseat_it, and is used by the HarfBuzz shaper.
726 733
727 This function updates all fields of the input glyphs. If the 734 This function updates all fields of the input glyphs. If the
728 output glyphs (M) are more than the input glyphs (N), (N+1)th 735 output glyphs (M) are more than the input glyphs (N), (N+1)th
@@ -730,7 +737,7 @@ struct font_driver
730 a new glyph object and storing it in GSTRING. If (M) is greater 737 a new glyph object and storing it in GSTRING. If (M) is greater
731 than the length of GSTRING, nil should be return. In that case, 738 than the length of GSTRING, nil should be return. In that case,
732 this function is called again with the larger GSTRING. */ 739 this function is called again with the larger GSTRING. */
733 Lisp_Object (*shape) (Lisp_Object lgstring); 740 Lisp_Object (*shape) (Lisp_Object lgstring, Lisp_Object direction);
734 741
735 /* Optional. 742 /* Optional.
736 743
@@ -887,7 +894,7 @@ extern Lisp_Object ftfont_list_family (struct frame *);
887extern Lisp_Object ftfont_match (struct frame *, Lisp_Object); 894extern Lisp_Object ftfont_match (struct frame *, Lisp_Object);
888extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); 895extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
889extern Lisp_Object ftfont_otf_capability (struct font *); 896extern Lisp_Object ftfont_otf_capability (struct font *);
890extern Lisp_Object ftfont_shape (Lisp_Object); 897extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object);
891extern unsigned ftfont_encode_char (struct font *, int); 898extern unsigned ftfont_encode_char (struct font *, int);
892extern void ftfont_close (struct font *); 899extern void ftfont_close (struct font *);
893extern void ftfont_filter_properties (Lisp_Object, Lisp_Object); 900extern void ftfont_filter_properties (Lisp_Object, Lisp_Object);
diff --git a/src/ftfont.c b/src/ftfont.c
index 74d72f94abd..5a8adfdb24c 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -2797,7 +2797,7 @@ get_hb_unicode_funcs (void)
2797 2797
2798static Lisp_Object 2798static Lisp_Object
2799ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, 2799ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
2800 FT_Matrix *matrix) 2800 FT_Matrix *matrix, Lisp_Object direction)
2801{ 2801{
2802 ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring); 2802 ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring);
2803 ptrdiff_t i; 2803 ptrdiff_t i;
@@ -2836,15 +2836,38 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
2836 hb_buffer_set_content_type (hb_buffer, HB_BUFFER_CONTENT_TYPE_UNICODE); 2836 hb_buffer_set_content_type (hb_buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
2837 hb_buffer_set_cluster_level (hb_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); 2837 hb_buffer_set_cluster_level (hb_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
2838 2838
2839 /* FIXME: guess_segment_properties is BAD BAD BAD. 2839 /* Set the default properties for when they cannot be determined
2840 * we need to get these properties with the LGSTRING. */ 2840 below. */
2841#if 1
2842 hb_buffer_guess_segment_properties (hb_buffer); 2841 hb_buffer_guess_segment_properties (hb_buffer);
2843#else 2842 hb_direction_t dir = HB_DIRECTION_INVALID;
2844 hb_buffer_set_direction (hb_buffer, XXX); 2843 if (EQ (direction, QL2R))
2844 dir = HB_DIRECTION_LTR;
2845 else if (EQ (direction, QR2L))
2846 dir = HB_DIRECTION_RTL;
2847 /* If the caller didn't provide a meaningful DIRECTION, let HarfBuzz
2848 guess it. */
2849 if (dir != HB_DIRECTION_INVALID)
2850 hb_buffer_set_direction (hb_buffer, dir);
2851 /* Leave the script determination to HarfBuzz, until Emacs has a
2852 better idea of the script of LGSTRING. FIXME. */
2853#if 0
2845 hb_buffer_set_script (hb_buffer, XXX); 2854 hb_buffer_set_script (hb_buffer, XXX);
2846 hb_buffer_set_language (hb_buffer, XXX);
2847#endif 2855#endif
2856 /* FIXME: This can only handle the single global language, which
2857 normally comes from the locale. In addition, if
2858 current-iso639-language is a list, we arbitrarily use the first
2859 one. We should instead have a notion of the language of the text
2860 being shaped. */
2861 Lisp_Object lang = Vcurrent_iso639_language;
2862 if (CONSP (Vcurrent_iso639_language))
2863 lang = XCAR (Vcurrent_iso639_language);
2864 if (SYMBOLP (lang))
2865 {
2866 Lisp_Object lang_str = SYMBOL_NAME (lang);
2867 hb_buffer_set_language (hb_buffer,
2868 hb_language_from_string (SSDATA (lang_str),
2869 SBYTES (lang_str)));
2870 }
2848 2871
2849 if (!hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL)) 2872 if (!hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL))
2850 return Qnil; 2873 return Qnil;
@@ -2919,7 +2942,7 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font,
2919#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ 2942#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
2920 2943
2921Lisp_Object 2944Lisp_Object
2922ftfont_shape (Lisp_Object lgstring) 2945ftfont_shape (Lisp_Object lgstring, Lisp_Object direction)
2923{ 2946{
2924 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); 2947 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
2925 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; 2948 struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
@@ -2929,7 +2952,7 @@ ftfont_shape (Lisp_Object lgstring)
2929 hb_font_t *hb_font = ftfont_get_hb_font (ftfont_info); 2952 hb_font_t *hb_font = ftfont_get_hb_font (ftfont_info);
2930 2953
2931 return ftfont_shape_by_hb (lgstring, ftfont_info->ft_size->face, 2954 return ftfont_shape_by_hb (lgstring, ftfont_info->ft_size->face,
2932 hb_font, &ftfont_info->matrix); 2955 hb_font, &ftfont_info->matrix, direction);
2933 } 2956 }
2934 else 2957 else
2935#endif /* HAVE_HARFBUZZ */ 2958#endif /* HAVE_HARFBUZZ */
diff --git a/src/macfont.m b/src/macfont.m
index d137648937c..ee6c1737269 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -38,6 +38,12 @@ Original author: YAMAMOTO Mitsuharu
38 38
39#include <libkern/OSByteOrder.h> 39#include <libkern/OSByteOrder.h>
40 40
41/* Values for `dir' argument to shaper functions. */
42enum lgstring_direction
43 {
44 DIR_R2L = -1, DIR_UNKNOWN = 0, DIR_L2R = 1,
45 };
46
41static double mac_font_get_advance_width_for_glyph (CTFontRef, CGGlyph); 47static double mac_font_get_advance_width_for_glyph (CTFontRef, CGGlyph);
42static CGRect mac_font_get_bounding_rect_for_glyph (CTFontRef, CGGlyph); 48static CGRect mac_font_get_bounding_rect_for_glyph (CTFontRef, CGGlyph);
43static CFArrayRef mac_font_create_available_families (void); 49static CFArrayRef mac_font_create_available_families (void);
@@ -48,7 +54,8 @@ static Boolean mac_font_descriptor_supports_languages (CTFontDescriptorRef,
48 CFArrayRef); 54 CFArrayRef);
49static CFStringRef mac_font_create_preferred_family_for_attributes (CFDictionaryRef); 55static CFStringRef mac_font_create_preferred_family_for_attributes (CFDictionaryRef);
50static CFIndex mac_font_shape (CTFontRef, CFStringRef, 56static CFIndex mac_font_shape (CTFontRef, CFStringRef,
51 struct mac_glyph_layout *, CFIndex); 57 struct mac_glyph_layout *, CFIndex,
58 enum lgstring_direction);
52static CFArrayRef mac_font_copy_default_descriptors_for_language (CFStringRef); 59static CFArrayRef mac_font_copy_default_descriptors_for_language (CFStringRef);
53static CFStringRef mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef, CFArrayRef); 60static CFStringRef mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef, CFArrayRef);
54#if USE_CT_GLYPH_INFO 61#if USE_CT_GLYPH_INFO
@@ -317,7 +324,8 @@ mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
317 324
318static CFIndex 325static CFIndex
319mac_font_shape_1 (NSFont *font, NSString *string, 326mac_font_shape_1 (NSFont *font, NSString *string,
320 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len) 327 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len,
328 enum lgstring_direction dir)
321{ 329{
322 NSUInteger i; 330 NSUInteger i;
323 CFIndex result = 0; 331 CFIndex result = 0;
@@ -581,11 +589,11 @@ mac_font_shape_1 (NSFont *font, NSString *string,
581static CFIndex 589static CFIndex
582mac_screen_font_shape (ScreenFontRef font, CFStringRef string, 590mac_screen_font_shape (ScreenFontRef font, CFStringRef string,
583 struct mac_glyph_layout *glyph_layouts, 591 struct mac_glyph_layout *glyph_layouts,
584 CFIndex glyph_len) 592 CFIndex glyph_len, enum lgstring_direction dir)
585{ 593{
586 return mac_font_shape_1 ([(NSFont *)font printerFont], 594 return mac_font_shape_1 ([(NSFont *)font printerFont],
587 (NSString *) string, 595 (NSString *) string,
588 glyph_layouts, glyph_len); 596 glyph_layouts, glyph_len, dir);
589} 597}
590 598
591static CGColorRef 599static CGColorRef
@@ -2916,7 +2924,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2916} 2924}
2917 2925
2918static Lisp_Object 2926static Lisp_Object
2919macfont_shape (Lisp_Object lgstring) 2927macfont_shape (Lisp_Object lgstring, Lisp_Object direction)
2920{ 2928{
2921 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); 2929 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
2922 struct macfont_info *macfont_info = (struct macfont_info *) font; 2930 struct macfont_info *macfont_info = (struct macfont_info *) font;
@@ -2966,12 +2974,18 @@ macfont_shape (Lisp_Object lgstring)
2966 kCFAllocatorNull); 2974 kCFAllocatorNull);
2967 if (string) 2975 if (string)
2968 { 2976 {
2977 enum lgstring_direction dir = DIR_UNKNOWN;
2978
2979 if (EQ (direction, QL2R))
2980 dir = DIR_L2R;
2981 else if (EQ (direction, QR2L))
2982 dir = DIR_R2L;
2969 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len); 2983 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len);
2970 if (macfont_info->screen_font) 2984 if (macfont_info->screen_font)
2971 used = mac_screen_font_shape (macfont_info->screen_font, string, 2985 used = mac_screen_font_shape (macfont_info->screen_font, string,
2972 glyph_layouts, glyph_len); 2986 glyph_layouts, glyph_len, dir);
2973 else 2987 else
2974 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len); 2988 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len, dir);
2975 CFRelease (string); 2989 CFRelease (string);
2976 } 2990 }
2977 2991
@@ -3652,7 +3666,8 @@ mac_font_create_line_with_string_and_font (CFStringRef string,
3652 3666
3653static CFIndex 3667static CFIndex
3654mac_font_shape (CTFontRef font, CFStringRef string, 3668mac_font_shape (CTFontRef font, CFStringRef string,
3655 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len) 3669 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len,
3670 lgstring_direction dir)
3656{ 3671{
3657 CFIndex used, result = 0; 3672 CFIndex used, result = 0;
3658 CTLineRef ctline = mac_font_create_line_with_string_and_font (string, font); 3673 CTLineRef ctline = mac_font_create_line_with_string_and_font (string, font);
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index 29c9c7a0bd1..3c400f38b13 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -198,6 +198,9 @@ uniscribe_otf_capability (struct font *font)
198 (N+1)th element of LGSTRING is nil, input of shaping is from the 198 (N+1)th element of LGSTRING is nil, input of shaping is from the
199 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and 199 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and
200 CODE are already set. 200 CODE are already set.
201 DIRECTION is either L2R or R2L, or nil if unknown. During
202 redisplay, this comes from applying the UBA, is passed from
203 composition_reseat_it, and is used by the HarfBuzz shaper.
201 204
202 This function updates all fields of the input glyphs. If the 205 This function updates all fields of the input glyphs. If the
203 output glyphs (M) are more than the input glyphs (N), (N+1)th 206 output glyphs (M) are more than the input glyphs (N), (N+1)th
@@ -206,7 +209,7 @@ uniscribe_otf_capability (struct font *font)
206 than the length of LGSTRING, nil should be returned. In that case, 209 than the length of LGSTRING, nil should be returned. In that case,
207 this function is called again with a larger LGSTRING. */ 210 this function is called again with a larger LGSTRING. */
208static Lisp_Object 211static Lisp_Object
209uniscribe_shape (Lisp_Object lgstring) 212uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
210{ 213{
211 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); 214 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
212 struct uniscribe_font_info *uniscribe_font 215 struct uniscribe_font_info *uniscribe_font
@@ -394,6 +397,8 @@ uniscribe_shape (Lisp_Object lgstring)
394 adjustment for the base character, which is 397 adjustment for the base character, which is
395 then updated for each successive glyph in the 398 then updated for each successive glyph in the
396 grapheme cluster. */ 399 grapheme cluster. */
400 /* FIXME: Should we use DIRECTION here instead
401 of what ScriptItemize guessed? */
397 if (items[i].a.fRTL) 402 if (items[i].a.fRTL)
398 { 403 {
399 int j1 = j; 404 int j1 = j;
diff --git a/src/xftfont.c b/src/xftfont.c
index 56d0e30e24c..6f56c053bb7 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -674,13 +674,13 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
674 674
675#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ 675#if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ
676static Lisp_Object 676static Lisp_Object
677xftfont_shape (Lisp_Object lgstring) 677xftfont_shape (Lisp_Object lgstring, Lisp_Object direction)
678{ 678{
679 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); 679 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
680 struct xftfont_info *xftfont_info = (struct xftfont_info *) font; 680 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
681 FT_Face ft_face = XftLockFace (xftfont_info->xftfont); 681 FT_Face ft_face = XftLockFace (xftfont_info->xftfont);
682 xftfont_info->ft_size = ft_face->size; 682 xftfont_info->ft_size = ft_face->size;
683 Lisp_Object val = ftfont_shape (lgstring); 683 Lisp_Object val = ftfont_shape (lgstring, direction);
684 XftUnlockFace (xftfont_info->xftfont); 684 XftUnlockFace (xftfont_info->xftfont);
685 return val; 685 return val;
686} 686}