aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2012-08-21 20:14:08 +0300
committerEli Zaretskii2012-08-21 20:14:08 +0300
commitb2f09701eadc7dfb70f331869daf295628926af6 (patch)
treeeff040b5ac752af49ce63656f0e08a13148e135f /src
parent9b994fed3cc7af2cd748f92316e75d962b545728 (diff)
downloademacs-b2f09701eadc7dfb70f331869daf295628926af6.tar.gz
emacs-b2f09701eadc7dfb70f331869daf295628926af6.zip
Fix bug #11860 with displaying composite RTL characters on MS-Windows.
src/w32uniscribe.c (uniscribe_shape): Fix producing gstring components for RTL text. Adjust X-OFFSET of each non-base glyph for the width of the base character, according to what x_draw_composite_glyph_string_foreground expects. Generate WADJUST value according to composition_gstring_width's expectations, to produce correct width of the composed character. Reverse the sign of the DU offset produced by ScriptPlace.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/w32uniscribe.c57
2 files changed, 60 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b8da88f3d6c..960639af152 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12012-08-21 Eli Zaretskii <eliz@gnu.org>
2
3 * w32uniscribe.c (uniscribe_shape): Fix producing gstring
4 components for RTL text (Bug#11860). Adjust X-OFFSET of each
5 non-base glyph for the width of the base character, according to
6 what x_draw_composite_glyph_string_foreground expects. Generate
7 WADJUST value according to composition_gstring_width's
8 expectations, to produce correct width of the composed character.
9 Reverse the sign of the DU offset produced by ScriptPlace.
10
12012-08-21 Paul Eggert <eggert@cs.ucla.edu> 112012-08-21 Paul Eggert <eggert@cs.ucla.edu>
2 12
3 * dbusbind.c (xd_remove_watch): Do not assume C99 comments. 13 * dbusbind.c (xd_remove_watch): Do not assume C99 comments.
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index 06f7b1bd192..50532acaff3 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -320,7 +320,23 @@ uniscribe_shape (Lisp_Object lgstring)
320 } 320 }
321 if (SUCCEEDED (result)) 321 if (SUCCEEDED (result))
322 { 322 {
323 int j, from, to; 323 int j, from, to, adj_offset = 0;
324
325 /* For RTL text, the Uniscribe shaper prepares the
326 values in ADVANCES array for layout in reverse order,
327 whereby "advance width" is applied to move the pen in
328 reverse direction and _before_ drawing the glyph.
329 Since we draw glyphs in their normal left-to-right
330 order, we need to adjust the coordinates of each
331 non-base glyph in a grapheme cluster via X-OFF
332 component of the gstring's ADJUSTMENT sub-vector.
333 This loop computes the initial value of the
334 adjustment for the base character, which is then
335 updated for each successive glyph in the grapheme
336 cluster. */
337 if (items[i].a.fRTL)
338 for (j = 1; j < nglyphs; j++)
339 adj_offset += advances[j];
324 340
325 from = 0; 341 from = 0;
326 to = from; 342 to = from;
@@ -392,9 +408,11 @@ uniscribe_shape (Lisp_Object lgstring)
392 408
393 if (SUCCEEDED (result)) 409 if (SUCCEEDED (result))
394 { 410 {
395 LGLYPH_SET_LBEARING (lglyph, char_metric.abcA); 411 int lbearing = char_metric.abcA;
396 LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA 412 int rbearing = char_metric.abcA + char_metric.abcB;
397 + char_metric.abcB)); 413
414 LGLYPH_SET_LBEARING (lglyph, lbearing);
415 LGLYPH_SET_RBEARING (lglyph, rbearing);
398 } 416 }
399 else 417 else
400 { 418 {
@@ -402,18 +420,43 @@ uniscribe_shape (Lisp_Object lgstring)
402 LGLYPH_SET_RBEARING (lglyph, advances[j]); 420 LGLYPH_SET_RBEARING (lglyph, advances[j]);
403 } 421 }
404 422
405 if (offsets[j].du || offsets[j].dv) 423 if (offsets[j].du || offsets[j].dv
424 /* For non-base glyphs of RTL grapheme clusters,
425 adjust the X offset even if both DU and DV
426 are zero. */
427 || (!attributes[j].fClusterStart && items[i].a.fRTL))
406 { 428 {
407 Lisp_Object vec; 429 Lisp_Object vec;
408 vec = Fmake_vector (make_number (3), Qnil); 430 vec = Fmake_vector (make_number (3), Qnil);
409 ASET (vec, 0, make_number (offsets[j].du)); 431 if (items[i].a.fRTL)
432 {
433 /* Empirically, it looks like Uniscribe
434 interprets DU in reverse direction for
435 RTL clusters. E.g., if we don't reverse
436 the direction, the Hebrew point HOLAM is
437 drawn above the right edge of the base
438 consonant, instead of above the left edge. */
439 ASET (vec, 0, make_number (-offsets[j].du
440 + adj_offset));
441 /* Update the adjustment value for the width
442 advance of the glyph we just emitted. */
443 adj_offset -= 2 * advances[j];
444 }
445 else
446 ASET (vec, 0, make_number (offsets[j].du + adj_offset));
410 ASET (vec, 1, make_number (offsets[j].dv)); 447 ASET (vec, 1, make_number (offsets[j].dv));
411 /* Based on what ftfont.c does... */ 448 /* Based on what ftfont.c does... */
412 ASET (vec, 2, make_number (advances[j])); 449 ASET (vec, 2, make_number (advances[j]));
413 LGLYPH_SET_ADJUSTMENT (lglyph, vec); 450 LGLYPH_SET_ADJUSTMENT (lglyph, vec);
414 } 451 }
415 else 452 else
416 LGLYPH_SET_ADJUSTMENT (lglyph, Qnil); 453 {
454 LGLYPH_SET_ADJUSTMENT (lglyph, Qnil);
455 /* Update the adjustment value to compensate for
456 the width of the base character. */
457 if (items[i].a.fRTL)
458 adj_offset -= advances[j];
459 }
417 } 460 }
418 } 461 }
419 } 462 }