diff options
| author | Eli Zaretskii | 2018-12-29 16:35:09 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2018-12-29 16:35:09 +0200 |
| commit | 48776b70115edf3775df19d80f734048dadff198 (patch) | |
| tree | 10a7e72a45bbbdf8dbfed4afce59fc9a5b975110 /src | |
| parent | 1a80b5d9b8cfa0e523b596db5d1e7e6074dbee46 (diff) | |
| download | emacs-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.c | 28 | ||||
| -rw-r--r-- | src/font.c | 16 | ||||
| -rw-r--r-- | src/font.h | 13 | ||||
| -rw-r--r-- | src/ftfont.c | 41 | ||||
| -rw-r--r-- | src/macfont.m | 31 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 7 | ||||
| -rw-r--r-- | src/xftfont.c | 4 |
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) | |||
| 873 | static Lisp_Object | 873 | static Lisp_Object |
| 874 | autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, | 874 | autocmp_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. |
| 1946 | This function is called from the display routine with four arguments: | 1947 | This function is called from the display engine with 6 arguments: |
| 1947 | FROM, TO, WINDOW, and STRING. | 1948 | FUNC, FROM, TO, FONT-OBJECT, STRING, and DIRECTION. |
| 1949 | |||
| 1950 | FUNC is the function to compose characters. On text-mode display, | ||
| 1951 | FUNC is ignored and `compose-gstring-for-terminal' is used instead. | ||
| 1948 | 1952 | ||
| 1949 | If STRING is nil, the function must compose characters in the region | 1953 | If STRING is nil, the function must compose characters in the region |
| 1950 | between FROM and TO in the current buffer. | 1954 | between FROM and TO in the current buffer. |
| 1951 | 1955 | ||
| 1952 | Otherwise, STRING is a string, and FROM and TO are indices into the | 1956 | Otherwise, STRING is a string, and FROM and TO are indices into the |
| 1953 | string. In this case, the function must compose characters in the | 1957 | string. In this case, the function must compose characters in the |
| 1954 | string. */); | 1958 | string. |
| 1959 | |||
| 1960 | FONT-OBJECT is the font to use, or nil if characters are to be | ||
| 1961 | composed on a text-mode display. | ||
| 1962 | |||
| 1963 | DIRECTION is the bidi directionality of the text to shape. It could | ||
| 1964 | be 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 | ||
| 4400 | DEFUN ("font-shape-gstring", Ffont_shape_gstring, Sfont_shape_gstring, 1, 1, 0, | 4400 | DEFUN ("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. |
| 4402 | Shaping means substituting glyphs and/or adjusting positions of glyphs | 4402 | Shaping means substituting glyphs and/or adjusting positions of glyphs |
| 4403 | to get the correct visual image of character sequences set in the | 4403 | to get the correct visual image of character sequences set in the |
| 4404 | header of the glyph-string. | 4404 | header of the glyph-string. |
| 4405 | 4405 | ||
| 4406 | DIRECTION should be produced by the UBA, the Unicode Bidirectional | ||
| 4407 | Algorithm, and should be a symbol, either L2R or R2L. It can also | ||
| 4408 | be nil if the bidi context is unknown. | ||
| 4409 | |||
| 4406 | If the shaping was successful, the value is GSTRING itself or a newly | 4410 | If the shaping was successful, the value is GSTRING itself or a newly |
| 4407 | created glyph-string. Otherwise, the value is nil. | 4411 | created glyph-string. Otherwise, the value is nil. |
| 4408 | 4412 | ||
| 4409 | See the documentation of `composition-get-gstring' for the format of | 4413 | See the documentation of `composition-get-gstring' for the format of |
| 4410 | GSTRING. */) | 4414 | GSTRING. */) |
| 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 *); | |||
| 887 | extern Lisp_Object ftfont_match (struct frame *, Lisp_Object); | 894 | extern Lisp_Object ftfont_match (struct frame *, Lisp_Object); |
| 888 | extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); | 895 | extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); |
| 889 | extern Lisp_Object ftfont_otf_capability (struct font *); | 896 | extern Lisp_Object ftfont_otf_capability (struct font *); |
| 890 | extern Lisp_Object ftfont_shape (Lisp_Object); | 897 | extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object); |
| 891 | extern unsigned ftfont_encode_char (struct font *, int); | 898 | extern unsigned ftfont_encode_char (struct font *, int); |
| 892 | extern void ftfont_close (struct font *); | 899 | extern void ftfont_close (struct font *); |
| 893 | extern void ftfont_filter_properties (Lisp_Object, Lisp_Object); | 900 | extern 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 | ||
| 2798 | static Lisp_Object | 2798 | static Lisp_Object |
| 2799 | ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, | 2799 | ftfont_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 | ||
| 2921 | Lisp_Object | 2944 | Lisp_Object |
| 2922 | ftfont_shape (Lisp_Object lgstring) | 2945 | ftfont_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. */ | ||
| 42 | enum lgstring_direction | ||
| 43 | { | ||
| 44 | DIR_R2L = -1, DIR_UNKNOWN = 0, DIR_L2R = 1, | ||
| 45 | }; | ||
| 46 | |||
| 41 | static double mac_font_get_advance_width_for_glyph (CTFontRef, CGGlyph); | 47 | static double mac_font_get_advance_width_for_glyph (CTFontRef, CGGlyph); |
| 42 | static CGRect mac_font_get_bounding_rect_for_glyph (CTFontRef, CGGlyph); | 48 | static CGRect mac_font_get_bounding_rect_for_glyph (CTFontRef, CGGlyph); |
| 43 | static CFArrayRef mac_font_create_available_families (void); | 49 | static CFArrayRef mac_font_create_available_families (void); |
| @@ -48,7 +54,8 @@ static Boolean mac_font_descriptor_supports_languages (CTFontDescriptorRef, | |||
| 48 | CFArrayRef); | 54 | CFArrayRef); |
| 49 | static CFStringRef mac_font_create_preferred_family_for_attributes (CFDictionaryRef); | 55 | static CFStringRef mac_font_create_preferred_family_for_attributes (CFDictionaryRef); |
| 50 | static CFIndex mac_font_shape (CTFontRef, CFStringRef, | 56 | static CFIndex mac_font_shape (CTFontRef, CFStringRef, |
| 51 | struct mac_glyph_layout *, CFIndex); | 57 | struct mac_glyph_layout *, CFIndex, |
| 58 | enum lgstring_direction); | ||
| 52 | static CFArrayRef mac_font_copy_default_descriptors_for_language (CFStringRef); | 59 | static CFArrayRef mac_font_copy_default_descriptors_for_language (CFStringRef); |
| 53 | static CFStringRef mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef, CFArrayRef); | 60 | static 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 | ||
| 318 | static CFIndex | 325 | static CFIndex |
| 319 | mac_font_shape_1 (NSFont *font, NSString *string, | 326 | mac_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, | |||
| 581 | static CFIndex | 589 | static CFIndex |
| 582 | mac_screen_font_shape (ScreenFontRef font, CFStringRef string, | 590 | mac_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 | ||
| 591 | static CGColorRef | 599 | static CGColorRef |
| @@ -2916,7 +2924,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, | |||
| 2916 | } | 2924 | } |
| 2917 | 2925 | ||
| 2918 | static Lisp_Object | 2926 | static Lisp_Object |
| 2919 | macfont_shape (Lisp_Object lgstring) | 2927 | macfont_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 | ||
| 3653 | static CFIndex | 3667 | static CFIndex |
| 3654 | mac_font_shape (CTFontRef font, CFStringRef string, | 3668 | mac_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. */ |
| 208 | static Lisp_Object | 211 | static Lisp_Object |
| 209 | uniscribe_shape (Lisp_Object lgstring) | 212 | uniscribe_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 |
| 676 | static Lisp_Object | 676 | static Lisp_Object |
| 677 | xftfont_shape (Lisp_Object lgstring) | 677 | xftfont_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 | } |