aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-09-04 18:16:08 +0300
committerEli Zaretskii2010-09-04 18:16:08 +0300
commit6e6b8e25b118a680ef322ab74e42f556b804c70b (patch)
tree107ba0a89d51268e34351876ea02fbd10fe45956 /src
parent5e5992c20ef5f5d0ea67d23839a298b8dae91eff (diff)
downloademacs-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/ChangeLog8
-rw-r--r--src/w32uniscribe.c48
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 @@
12010-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
12010-09-04 Andreas Schwab <schwab@linux-m68k.org> 92010-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. */
194static Lisp_Object 195static Lisp_Object
195uniscribe_shape (Lisp_Object lgstring) 196uniscribe_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);