emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r109726: Fix bug #11860 with displayi


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109726: Fix bug #11860 with displaying composite RTL characters on MS-Windows.
Date: Tue, 21 Aug 2012 20:14:08 +0300
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109726
fixes bug: http://debbugs.gnu.org/11860
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Tue 2012-08-21 20:14:08 +0300
message:
  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.
modified:
  src/ChangeLog
  src/w32uniscribe.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-08-21 16:54:50 +0000
+++ b/src/ChangeLog     2012-08-21 17:14:08 +0000
@@ -1,3 +1,13 @@
+2012-08-21  Eli Zaretskii  <address@hidden>
+
+       * w32uniscribe.c (uniscribe_shape): Fix producing gstring
+       components for RTL text (Bug#11860).  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.
+
 2012-08-21  Paul Eggert  <address@hidden>
 
        * dbusbind.c (xd_remove_watch): Do not assume C99 comments.

=== modified file 'src/w32uniscribe.c'
--- a/src/w32uniscribe.c        2012-07-05 06:32:41 +0000
+++ b/src/w32uniscribe.c        2012-08-21 17:14:08 +0000
@@ -320,7 +320,23 @@
            }
           if (SUCCEEDED (result))
            {
-             int j, from, to;
+             int j, from, to, adj_offset = 0;
+
+             /* For RTL text, the Uniscribe shaper prepares the
+                values in ADVANCES array for layout in reverse order,
+                whereby "advance width" is applied to move the pen in
+                reverse direction and _before_ drawing the glyph.
+                Since we draw glyphs in their normal left-to-right
+                order, we need to adjust the coordinates of each
+                non-base glyph in a grapheme cluster via X-OFF
+                component of the gstring's ADJUSTMENT sub-vector.
+                This loop computes the initial value of the
+                adjustment for the base character, which is then
+                updated for each successive glyph in the grapheme
+                cluster.  */
+             if (items[i].a.fRTL)
+               for (j = 1; j < nglyphs; j++)
+                 adj_offset += advances[j];
 
              from = 0;
              to = from;
@@ -392,9 +408,11 @@
 
                  if (SUCCEEDED (result))
                    {
-                     LGLYPH_SET_LBEARING (lglyph, char_metric.abcA);
-                     LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA
-                                                   + char_metric.abcB));
+                     int lbearing = char_metric.abcA;
+                     int rbearing = char_metric.abcA + char_metric.abcB;
+
+                     LGLYPH_SET_LBEARING (lglyph, lbearing);
+                     LGLYPH_SET_RBEARING (lglyph, rbearing);
                    }
                  else
                    {
@@ -402,18 +420,43 @@
                      LGLYPH_SET_RBEARING (lglyph, advances[j]);
                    }
 
-                 if (offsets[j].du || offsets[j].dv)
+                 if (offsets[j].du || offsets[j].dv
+                     /* For non-base glyphs of RTL grapheme clusters,
+                        adjust the X offset even if both DU and DV
+                        are zero.  */
+                     || (!attributes[j].fClusterStart && items[i].a.fRTL))
                    {
                      Lisp_Object vec;
                      vec = Fmake_vector (make_number (3), Qnil);
-                     ASET (vec, 0, make_number (offsets[j].du));
+                     if (items[i].a.fRTL)
+                       {
+                         /* Empirically, it looks like Uniscribe
+                            interprets DU in reverse direction for
+                            RTL clusters.  E.g., if we don't reverse
+                            the direction, the Hebrew point HOLAM is
+                            drawn above the right edge of the base
+                            consonant, instead of above the left edge.  */
+                         ASET (vec, 0, make_number (-offsets[j].du
+                                                    + adj_offset));
+                         /* Update the adjustment value for the width
+                            advance of the glyph we just emitted.  */
+                         adj_offset -= 2 * advances[j];
+                       }
+                     else
+                       ASET (vec, 0, make_number (offsets[j].du + adj_offset));
                      ASET (vec, 1, make_number (offsets[j].dv));
                      /* Based on what ftfont.c does... */
                      ASET (vec, 2, make_number (advances[j]));
                      LGLYPH_SET_ADJUSTMENT (lglyph, vec);
                    }
                  else
-                   LGLYPH_SET_ADJUSTMENT (lglyph, Qnil);
+                   {
+                     LGLYPH_SET_ADJUSTMENT (lglyph, Qnil);
+                     /* Update the adjustment value to compensate for
+                        the width of the base character.  */
+                     if (items[i].a.fRTL)
+                       adj_offset -= advances[j];
+                   }
                }
            }
        }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]