diff options
| author | Eli Zaretskii | 2010-09-04 18:16:08 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2010-09-04 18:16:08 +0300 |
| commit | 6e6b8e25b118a680ef322ab74e42f556b804c70b (patch) | |
| tree | 107ba0a89d51268e34351876ea02fbd10fe45956 /src | |
| parent | 5e5992c20ef5f5d0ea67d23839a298b8dae91eff (diff) | |
| download | emacs-6e6b8e25b118a680ef322ab74e42f556b804c70b.tar.gz emacs-6e6b8e25b118a680ef322ab74e42f556b804c70b.zip | |
Fix display of composed R2L text on MS-Windows.
w32uniscribe.c (uniscribe_shape): Update commentary. Don't
try to reorder grapheme clusters, since LGSTRING should always
hold them in the logical order.
(uniscribe_encode_char, uniscribe_shape): Force ScriptShape to
return glyph codes in the logical order.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 48 |
2 files changed, 35 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 404c19c8faa..c5bd692a7d1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2010-09-04 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * w32uniscribe.c (uniscribe_shape): Update commentary. Don't | ||
| 4 | try to reorder grapheme clusters, since LGSTRING should always | ||
| 5 | hold them in the logical order. | ||
| 6 | (uniscribe_encode_char, uniscribe_shape): Force ScriptShape to | ||
| 7 | return glyph codes in the logical order. | ||
| 8 | |||
| 1 | 2010-09-04 Andreas Schwab <schwab@linux-m68k.org> | 9 | 2010-09-04 Andreas Schwab <schwab@linux-m68k.org> |
| 2 | 10 | ||
| 3 | * image.c (imagemagick_image_p): Replace bcopy by memcpy. | 11 | * image.c (imagemagick_image_p): Replace bcopy by memcpy. |
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index 9edd6353ba3..05cc8346a50 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c | |||
| @@ -180,17 +180,18 @@ uniscribe_otf_capability (struct font *font) | |||
| 180 | 180 | ||
| 181 | /* Uniscribe implementation of shape for font backend. | 181 | /* Uniscribe implementation of shape for font backend. |
| 182 | 182 | ||
| 183 | Shape text in LGSTRING. See the docstring of `font-make-gstring' | 183 | Shape text in LGSTRING. See the docstring of |
| 184 | for the format of LGSTRING. If the (N+1)th element of LGSTRING | 184 | `composition-get-gstring' for the format of LGSTRING. If the |
| 185 | is nil, input of shaping is from the 1st to (N)th elements. In | 185 | (N+1)th element of LGSTRING is nil, input of shaping is from the |
| 186 | each input glyph, FROM, TO, CHAR, and CODE are already set. | 186 | 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and |
| 187 | CODE are already set. | ||
| 187 | 188 | ||
| 188 | This function updates all fields of the input glyphs. If the | 189 | This function updates all fields of the input glyphs. If the |
| 189 | output glyphs (M) are more than the input glyphs (N), (N+1)th | 190 | output glyphs (M) are more than the input glyphs (N), (N+1)th |
| 190 | through (M)th elements of LGSTRING are updated possibly by making | 191 | through (M)th elements of LGSTRING are updated possibly by making |
| 191 | a new glyph object and storing it in LGSTRING. If (M) is greater | 192 | a new glyph object and storing it in LGSTRING. If (M) is greater |
| 192 | than the length of LGSTRING, nil should be return. In that case, | 193 | than the length of LGSTRING, nil should be returned. In that case, |
| 193 | this function is called again with the larger LGSTRING. */ | 194 | this function is called again with a larger LGSTRING. */ |
| 194 | static Lisp_Object | 195 | static Lisp_Object |
| 195 | uniscribe_shape (Lisp_Object lgstring) | 196 | uniscribe_shape (Lisp_Object lgstring) |
| 196 | { | 197 | { |
| @@ -217,6 +218,9 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 217 | max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring); | 218 | max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring); |
| 218 | done_glyphs = 0; | 219 | done_glyphs = 0; |
| 219 | chars = (wchar_t *) alloca (nchars * sizeof (wchar_t)); | 220 | chars = (wchar_t *) alloca (nchars * sizeof (wchar_t)); |
| 221 | /* FIXME: This loop assumes that characters in the input LGSTRING | ||
| 222 | are all inside the BMP. Need to encode characters beyond the BMP | ||
| 223 | as UTF-16. */ | ||
| 220 | for (i = 0; i < nchars; i++) | 224 | for (i = 0; i < nchars; i++) |
| 221 | { | 225 | { |
| 222 | /* lgstring can be bigger than the number of characters in it, in | 226 | /* lgstring can be bigger than the number of characters in it, in |
| @@ -248,9 +252,6 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 248 | return Qnil; | 252 | return Qnil; |
| 249 | } | 253 | } |
| 250 | 254 | ||
| 251 | /* TODO: When we get BIDI support, we need to call ScriptLayout here. | ||
| 252 | Requires that we know the surrounding context. */ | ||
| 253 | |||
| 254 | glyphs = alloca (max_glyphs * sizeof (WORD)); | 255 | glyphs = alloca (max_glyphs * sizeof (WORD)); |
| 255 | clusters = alloca (nchars * sizeof (WORD)); | 256 | clusters = alloca (nchars * sizeof (WORD)); |
| 256 | attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR)); | 257 | attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR)); |
| @@ -259,8 +260,12 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 259 | 260 | ||
| 260 | for (i = 0; i < nitems; i++) | 261 | for (i = 0; i < nitems; i++) |
| 261 | { | 262 | { |
| 262 | int nglyphs, nchars_in_run, rtl = items[i].a.fRTL ? -1 : 1; | 263 | int nglyphs, nchars_in_run; |
| 263 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; | 264 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; |
| 265 | /* Force ScriptShape to generate glyphs in the same order as | ||
| 266 | they are in the input LGSTRING, which is in the logical | ||
| 267 | order. */ | ||
| 268 | items[i].a.fLogicalOrder = 1; | ||
| 264 | 269 | ||
| 265 | /* Context may be NULL here, in which case the cache should be | 270 | /* Context may be NULL here, in which case the cache should be |
| 266 | used without needing to select the font. */ | 271 | used without needing to select the font. */ |
| @@ -321,7 +326,7 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 321 | { | 326 | { |
| 322 | int j, nclusters, from, to; | 327 | int j, nclusters, from, to; |
| 323 | 328 | ||
| 324 | from = rtl > 0 ? 0 : nchars_in_run - 1; | 329 | from = 0; |
| 325 | to = from; | 330 | to = from; |
| 326 | 331 | ||
| 327 | for (j = 0; j < nglyphs; j++) | 332 | for (j = 0; j < nglyphs; j++) |
| @@ -342,22 +347,19 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 342 | gl = glyphs[j]; | 347 | gl = glyphs[j]; |
| 343 | LGLYPH_SET_CODE (lglyph, gl); | 348 | LGLYPH_SET_CODE (lglyph, gl); |
| 344 | 349 | ||
| 345 | /* Detect clusters, for linking codes back to characters. */ | 350 | /* Detect clusters, for linking codes back to |
| 351 | characters. */ | ||
| 346 | if (attributes[j].fClusterStart) | 352 | if (attributes[j].fClusterStart) |
| 347 | { | 353 | { |
| 348 | while (from >= 0 && from < nchars_in_run | 354 | while (from < nchars_in_run && clusters[from] < j) |
| 349 | && clusters[from] < j) | 355 | from++; |
| 350 | from += rtl; | 356 | if (from >= nchars_in_run) |
| 351 | if (from < 0) | ||
| 352 | from = to = 0; | ||
| 353 | else if (from >= nchars_in_run) | ||
| 354 | from = to = nchars_in_run - 1; | 357 | from = to = nchars_in_run - 1; |
| 355 | else | 358 | else |
| 356 | { | 359 | { |
| 357 | int k; | 360 | int k; |
| 358 | to = rtl > 0 ? nchars_in_run - 1 : 0; | 361 | to = nchars_in_run - 1; |
| 359 | for (k = from + rtl; k >= 0 && k < nchars_in_run; | 362 | for (k = from + 1; k < nchars_in_run; k++) |
| 360 | k += rtl) | ||
| 361 | { | 363 | { |
| 362 | if (clusters[k] > j) | 364 | if (clusters[k] > j) |
| 363 | { | 365 | { |
| @@ -486,6 +488,10 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 486 | SCRIPT_VISATTR attrs[2]; | 488 | SCRIPT_VISATTR attrs[2]; |
| 487 | int nglyphs; | 489 | int nglyphs; |
| 488 | 490 | ||
| 491 | /* Force ScriptShape to generate glyphs in the logical | ||
| 492 | order. */ | ||
| 493 | items[0].a.fLogicalOrder = 1; | ||
| 494 | |||
| 489 | result = ScriptShape (context, &(uniscribe_font->cache), | 495 | result = ScriptShape (context, &(uniscribe_font->cache), |
| 490 | ch, len, 2, &(items[0].a), | 496 | ch, len, 2, &(items[0].a), |
| 491 | glyphs, clusters, attrs, &nglyphs); | 497 | glyphs, clusters, attrs, &nglyphs); |