Subject: bug#11860: 24.1; Arabic - Harakat (diacritics, short vowels) don't appear

From: Kenichi Handa <[email-masked]>
Date: Wed, 22 Aug 2012 18:15:05 +0900

In article <[email-masked]>, Eli Zaretskii <[email-masked]> writes:

> Well, it turns out that the truth is slightly different.  When the
> Uniscribe shaper is handed a chunk of RTL text with the fLogicalOrder
> flag set to TRUE, it prepares the glyphs in the logical order, but
> assumes that they will be laid out in reverse.  In this reverse order,
> the width advance value is applied _before_ drawing the glyph, and
> positive width advance values move the pen to the _left_.  I found
> this important information on some Web page, which I unfortunately can
> no longer find.

> In addition, it looks like in this "reverse" mode, the X-OFFSET value
> is also interpreted in the reverse direction, so its sign must be
> flipped for glyphs in RTL grapheme clusters.

> Armed with this knowledge, with the information you posted, and after
> studying the drawing code in w32term.c, I made some semi-empirical
> changes in uniscribe_shape that produce good results both with Arabic
> and with Hebrew.  In a nutshell, I adjusted the X-OFFSET values for
> the width of the base-character glyph.  The results are committed as
> trunk revision 109726; as I only tested the modification on a small
> sample of composed texts, please see if you can run more tests with as
> complex compositions as you can find.

As I currently don't have an environment for building Emasc
on Windows, 

> > > If it is correct, then how come the glyphs shown on GNU/Linux also
> > > have non-zero value of xadvance:
> > 
> > >   [0 1 1593 969 8 2 8 4 4 nil]
> > >   [0 1 1618 760 0 -6 -3 8 -11 [-9 2 0]]
> > 
> > Emacs draws the first glyph at its base point and advance
> > the base point 8 pixels to the right (because the WIDTH of
> > the first glyph is 8).  Then Emacs draw the second glyph at
> > 9 pixels left and 2 pixels up from the base point.  So, the
> > second glyph is drawn above the first glyph.

> I see.  This was somewhat counter-intuitive (why move first and then
> correct that by negative offsets, instead of not moving until all the
> glyphs in the cluster are drawn?).

I think it's more intuitive.  It draws glyphs as you write
by hand.  The exact place to draw a dependent vowel depends
on a base consonant.  So, you anyway have to adjust vowel's
base point of drawing.

> > > > For instance, in the above case, we may have to render glyphs in
> > > > this order (diacritical mark first):
> > > > 
> > > >   [0 1 1593 760 0 3 6 12 4 [1 -2 0]]
> > > >   [0 1 1593 969 8 1 8 12 4 nil]
> > 
> > > I tried the naive patch below, but it didn't quite work.  It seems
> > > like those changes somehow prevented character composition.  Perhaps
> > > Handa-san could give me some guidance here.
> > 
> > Did your patch produced the above GSTRING?

> Yes.  But I think swapping the glyphs in the cluster was not the right
> idea, because it violates the assumptions in w32font_draw, the drawing
> routine called by the font back-end.  That routine expects the first
> glyph to be for the base character of the composition.

As far as WIDTH, XOFF, YOFF, WADJUST are correct, the
drawing routines should work even if a combining mark comes
first.  The code that expects the first glyph to be a base
is Ffont_shape_gstring.  If the shaped GSTRING returned from
font->driver->shape has GLYPH sequence "Abc", A's
offset vector [X-OFF Y-OFF WADJUST] is nil, b and c's offset
vectors are not nil, Ffont_shape_gstring assumes that "Abc"
constitutes a grapheme cluster.

Anyway, thank you very much for the patch.  I have not yet
tried it because I currently don't have an environment to
build Emacs on windows.

---
Kenichi Handa
[email-masked]