[HarfBuzz] Arabic vowels and shaping - incomplete behavior
Hey, Is it just me, or do vowels break shaping in Arabic? If so, what should be done to fix it? I can't think of a way of solving it, maybe only removing the vowels, shaping without them and then adding previously shaped glyphs, and then vowels and then the glyphs again and reshaping, but that's annoying Any ideas? Example text that works in gtk but doesn't with my implementation: ضَلُّو Thanks, Tom. ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On Wed, Oct 27, 2010 at 01:28:38PM +0200, Tom Hacohen wrote: Hey, Is it just me, or do vowels break shaping in Arabic? It shouldn't, either the font is broken or you are not doing it right. Regards, Khaled -- Khaled Hosny Arabic localiser and member of Arabeyes.org team Free font developer ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On 10/27/10 07:28, Tom Hacohen wrote: Hey, Is it just me, or do vowels break shaping in Arabic? Pango has code to work around Arabic fonts that have no GDEF table, and no GPOS table. I've had planned to implement that in HarfBuzz but been putting it off for a while. I'll go ahead and do that today. What font are you using? behdad Any ideas? Example text that works in gtk but doesn't with my implementation: ضَلُّو Thanks, Tom. ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
Maybe you can attach a screenshot at least? On 10/27/10 09:19, Tom Hacohen wrote: On Wed, 2010-10-27 at 14:26 +0200, Khaled Hosny wrote: On Wed, Oct 27, 2010 at 01:28:38PM +0200, Tom Hacohen wrote: Hey, Is it just me, or do vowels break shaping in Arabic? It shouldn't, either the font is broken or you are not doing it right. Regards, Khaled Probably the latter. What I'm currently doing produces (for the word ضَلُّو): infos[0] = {codepoint = 1390, mask = 1, cluster = 5, internal1 = 0, internal2 = 2} positions[0] = {x_advance = 2304, y_advance = 0, x_offset = 0, y_offset = 0, internal = 0} infos[1] = {codepoint = 5333, mask = 1, cluster = 3, internal1 = 0, internal2 = 8} positions[1] = {x_advance = 0, y_advance = 0, x_offset = 322, y_offset = 233, internal = 0} infos[2] = {codepoint = 1386, mask = 1, cluster = 2, internal1 = 0, internal2 = 2} positions[2] = {x_advance = 3520, y_advance = 0, x_offset = 0, y_offset = 0, internal = 0} infos[3] = {codepoint = 1396, mask = 1, cluster = 1, internal1 = 0, internal2 = 8} positions[3] = {x_advance = 0, y_advance = 0, x_offset = 206, y_offset = -934, internal = 0} infos[4] = {codepoint = 1377, mask = 1, cluster = 0, internal1 = 0, internal2 = 2} positions[4] = {x_advance = 5824, y_advance = 0, x_offset = 0, y_offset = 0, internal = 0} Which as you can see is 5 chars while the original string was 6 (the two vowels merged into one), but other chars didn't substituted. My font is DejaVuSans and I just checked with font forge, LAM does have a medial form in the font, furthermore, removing the vowels make it transform correctly. After thinking about it, I realized it's maybe because I didn't use Unicode functions with the harfbuzz buffer (disabled them, waiting for a non-glib implementation), since maybe harfbuzz depends on get combining class, but after enabling them I get: Program received signal SIGSEGV, Segmentation fault. _hb_ot_shape_complex_setup_masks_arabic (c=0xbfff9d30) at hb-ot-shape-complex-arabic.cc:712 712 c-buffer-info[i].mask |= mask_array[c-buffer-info[i].gproperty]; because c-buffer-info[i].gproperty == 65535 So I think there's still an issue. Language = en, Script = HB_SCRIPT_ARABIC, Buffer = as I said Anything more needed? Thanks, Tom. ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On Wed, 2010-10-27 at 09:48 -0400, Behdad Esfahbod wrote: Maybe you can attach a screenshot at least? I just get isolated forms of all of them, anyhow, screenshot attached. But please also look at the bottom of the previous message where I described a SEGFAULT I was getting and also what I think I did wrong that made it not work in the first place. -- Tom. attachment: Screenshot-Notepad-1.png___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On 10/27/10 09:58, Tom Hacohen wrote: On Wed, 2010-10-27 at 09:48 -0400, Behdad Esfahbod wrote: Maybe you can attach a screenshot at least? I just get isolated forms of all of them, anyhow, screenshot attached. I fixed that bug and pushed out this morning. Please check with master. But please also look at the bottom of the previous message where I described a SEGFAULT I was getting and also what I think I did wrong that made it not work in the first place. Busy debugging some other bug. Will check later if your problem persists. behdad -- Tom. ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
[HarfBuzz] harfbuzz-ng: Branch 'master'
src/hb-ot-shape-complex-arabic.cc |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) New commits: commit aefdb64689aab19df76590a36c4a04052a8bffdb Author: Behdad Esfahbod beh...@behdad.org Date: Wed Oct 27 10:40:39 2010 -0400 Fix segfault with Arabic combining marks diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 4055e36..584fc51 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -689,8 +689,10 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c) unsigned int this_type = get_joining_type (c-buffer-info[i].codepoint, c-buffer-unicode-v.get_general_category (c-buffer-info[i].codepoint)); -if (unlikely (this_type == JOINING_TYPE_T)) +if (unlikely (this_type == JOINING_TYPE_T)) { + c-buffer-info[i].gproperty = NONE; continue; +} const arabic_state_table_entry *entry = arabic_state_table[state][this_type]; ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On 10/27/10 09:19, Tom Hacohen wrote: because c-buffer-info[i].gproperty == 65535 So I think there's still an issue. Fixed that too. Pushed out. behdad ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
Re: [HarfBuzz] Arabic vowels and shaping - incomplete behavior
On Wed, 2010-10-27 at 10:41 -0400, Behdad Esfahbod wrote: On 10/27/10 09:19, Tom Hacohen wrote: because c-buffer-info[i].gproperty == 65535 So I think there's still an issue. Fixed that too. Pushed out. Cool to know my assumptions were correct. Thank you very much, works like a charm. -- Tom. ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz
[HarfBuzz] harfbuzz-ng: Branch 'master'
src/hb-ot-layout-gpos-private.hh | 124 --- 1 file changed, 3 insertions(+), 121 deletions(-) New commits: commit ea22c749c7371cf66ca44f0bfe7030aef1926edd Author: Behdad Esfahbod beh...@behdad.org Date: Wed Oct 27 11:09:48 2010 -0400 Fix Cursive positioning Test case: ٠را rendered using IranNastaliq. diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 1860b09..4e08d4f 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -826,123 +826,6 @@ struct CursivePosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (); -/* Now comes the messiest part of the whole OpenType - specification. At first glance, cursive connections seem easy - to understand, but there are pitfalls! The reason is that - the specs don't mention how to compute the advance values - resp. glyph offsets. I was told it would be an omission, to - be fixed in the next OpenType version... Again many thanks to - Andrei Burago andr...@microsoft.com for clarifications. - - Consider the following example: - - | xadv1| -+-+ -| | - +-+--+ 1| - | | .| | - |0+--+--+ - | 2| - || - 0++ - | xadv2 | - -glyph1: advance width = 12 -anchor point = (3,1) - -glyph2: advance width = 11 -anchor point = (9,4) - -LSB is 1 for both glyphs (so the boxes drawn above are glyph -bboxes). Writing direction is R2L; `0' denotes the glyph's -coordinate origin. - - Now the surprising part: The advance width of the *left* glyph - (resp. of the *bottom* glyph) will be modified, no matter - whether the writing direction is L2R or R2L (resp. T2B or - B2T)! This assymetry is caused by the fact that the glyph's - coordinate origin is always the lower left corner for all - writing directions. - - Continuing the above example, we can compute the new - (horizontal) advance width of glyph2 as - -9 - 3 = 6 , - - and the new vertical offset of glyph2 as - -1 - 4 = -3 . - - - Vertical writing direction is far more complicated: - - a) Assuming that we recompute the advance height of the lower glyph: - - -- -+-+ - -- | | - +-+--+ 1| yadv1 - | | .| | -yadv2 |0+--+--+-- BSB1 -- - | 2| -- --y_offset - || - BSB2 -- 0++-- - ---- - -glyph1: advance height = 6 -anchor point = (3,1) - -glyph2: advance height = 7 -anchor point = (9,4) - -TSB is 1 for both glyphs; writing direction is T2B. - - - BSB1 = yadv1 - (TSB1 + ymax1) - BSB2 = yadv2 - (TSB2 + ymax2) - y_offset = y2 - y1 - -vertical advance width of glyph2 - = y_offset + BSB2 - BSB1 - = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1)) - = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1) - = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1 - - - b) Assuming that we recompute the advance height of the upper glyph: - - -- -- -+-+-- TSB1 - ---- | | - TSB2 -- +-+--+ 1| yadv1 ymax1 - | | .| | -yadv2 |0+--+--+-- -- - ymax2| 2| --y_offset - || - -- 0++-- - -- - -glyph1: advance height = 6 -anchor point = (3,1) - -glyph2: advance height = 7 -anchor point = (9,4) - -TSB is 1 for both glyphs; writing direction is T2B. - -y_offset = y2 - y1 - -vertical advance width of glyph2 - = TSB1 + ymax1 + y_offset - (TSB2 + ymax2) - = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2 - - - Comparing a) with b) shows that b) is easier to compute. I'll wait - for a reply from Andrei to see what should really be implemented... - - Since horizontal advance widths or vertical advance heights - can be used alone but not together, no ambiguity occurs.*/ - struct hb_ot_layout_context_t::info_t::gpos_t *gpi = c-layout-info.gpos; hb_codepoint_t last_pos = gpi-last; gpi-last =
[HarfBuzz] harfbuzz-ng: Branch 'master' - 6 commits
src/hb-ot-layout-common-private.hh |2 - src/hb-ot-layout-gdef-private.hh | 34 +++-- src/hb-ot-layout-gpos-private.hh | 31 ++- src/hb-ot-layout-gsubgpos-private.hh |6 --- src/hb-ot-layout.cc | 55 +-- src/hb-ot-layout.h | 13 6 files changed, 80 insertions(+), 61 deletions(-) New commits: commit 13528d0c78cadb1f67267c9a692558caef9fdaa6 Author: Behdad Esfahbod beh...@behdad.org Date: Wed Oct 27 14:09:27 2010 -0400 Supposedly implement vertical support in GPOS Not tested at all. diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 6be604e..187dc98 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -855,27 +855,40 @@ struct CursivePosFormat1 (this+this_record.exitAnchor).get_anchor (c-layout, c-buffer-info[i].codepoint, exit_x, exit_y); (this+next_record.entryAnchor).get_anchor (c-layout, c-buffer-info[j].codepoint, entry_x, entry_y); -/* TODO vertical */ +hb_direction_t direction = c-buffer-props.direction; -/* Align the exit anchor of the left glyph with the entry anchor of the right glyph. */ -if (c-buffer-props.direction == HB_DIRECTION_RTL) +/* Align the exit anchor of the left/top glyph with the entry anchor of the right/bottom glyph + * by adjusting advance of the left/top glyph. */ +if (HB_DIRECTION_IS_BACKWARD (direction)) { - c-buffer-pos[j].x_advance = c-buffer-pos[j].x_offset + entry_x - exit_x; + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + c-buffer-pos[j].x_advance = c-buffer-pos[j].x_offset + entry_x - exit_x; + else + c-buffer-pos[j].y_advance = c-buffer-pos[j].y_offset + entry_y - exit_y; } else { - c-buffer-pos[i].x_advance = c-buffer-pos[i].x_offset + exit_x - entry_x; + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + c-buffer-pos[i].x_advance = c-buffer-pos[i].x_offset + exit_x - entry_x; + else + c-buffer-pos[i].y_advance = c-buffer-pos[i].y_offset + exit_y - entry_y; } if (c-lookup_flag LookupFlag::RightToLeft) { c-buffer-pos[i].cursive_chain = j - i; - c-buffer-pos[i].y_offset = entry_y - exit_y; + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + c-buffer-pos[i].y_offset = entry_y - exit_y; + else + c-buffer-pos[i].x_offset = entry_x - exit_x; } else { c-buffer-pos[j].cursive_chain = i - j; - c-buffer-pos[j].y_offset = exit_y - entry_y; + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + c-buffer-pos[j].y_offset = exit_y - entry_y; + else + c-buffer-pos[j].x_offset = exit_x - entry_x; } c-buffer-i = j; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 75fa203..f85bf86 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -607,25 +607,34 @@ hb_ot_layout_position_finish (hb_font_t*font HB_UNUSED, unsigned int i, j; unsigned int len = hb_buffer_get_length (buffer); hb_internal_glyph_position_t *pos = (hb_internal_glyph_position_t *) hb_buffer_get_glyph_positions (buffer); + hb_direction_t direction = buffer-props.direction; /* TODO: Vertical */ - /* Handle cursive connections */ - /* First handle all chain-back connections */ - for (j = 0; j len; j++) { -if (pos[j].cursive_chain 0) -{ - pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset; - pos[j].cursive_chain = 0; + /* Handle cursive connections: + * First handle all chain-back connections, then handle all chain-forward connections. */ + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + { +for (j = 0; j len; j++) { + if (pos[j].cursive_chain 0) + pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset; +} +for (i = len; i 0; i--) { + j = i - 1; + if (pos[j].cursive_chain 0) + pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset; } } - /* Then handle all chain-forward connections */ - for (i = len; i 0; i--) { -j = i - 1; -if (pos[j].cursive_chain 0) -{ - pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset; - pos[j].cursive_chain = 0; + else + { +for (j = 0; j len; j++) { + if (pos[j].cursive_chain 0) + pos[j].x_offset += pos[j + pos[j].cursive_chain].x_offset; +} +for (i = len; i 0; i--) { + j = i - 1; + if (pos[j].cursive_chain 0) + pos[j].x_offset += pos[j + pos[j].cursive_chain].x_offset; } } @@ -639,7 +648,7 @@ hb_ot_layout_position_finish (hb_font_t*font HB_UNUSED, pos[i].x_offset += pos[back].x_offset; pos[i].y_offset += pos[back].y_offset; - if (buffer-props.direction == HB_DIRECTION_RTL) + if (HB_DIRECTION_IS_BACKWARD (buffer-props.direction)) for (j = back + 1; j i + 1; j++) {
Re: [HarfBuzz] harfbuzz coordinate system
BE == Behdad Esfahbod beh...@behdad.org writes: BE I'm wondering, should increasing y move upwards, or downwards? Most BE graphics API I've seen (PS-based API being the only exception) has y BE moving downward. I find that more intuitive in a text layout BE library, so we can say: in-line glyphs are stacked in the BE increasing x direction, lines are stacked in the increasing y BE direction. I've always thought of y going up w/in a font. It would be weird for the capsheight to be negative and descender depth to be positive. Especially since everything else has -ve descenders and +ve ascenders. -JimC -- James Cloos cl...@jhcloos.com OpenPGP: 1024D/ED7DAEA6 ___ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz