diff options
| author | Eli Zaretskii | 2012-08-21 20:14:08 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2012-08-21 20:14:08 +0300 |
| commit | b2f09701eadc7dfb70f331869daf295628926af6 (patch) | |
| tree | eff040b5ac752af49ce63656f0e08a13148e135f /src | |
| parent | 9b994fed3cc7af2cd748f92316e75d962b545728 (diff) | |
| download | emacs-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/ChangeLog | 10 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 57 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-08-21 Paul Eggert <eggert@cs.ucla.edu> | 11 | 2012-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 | } |