From 3409fb1c767118067cf7edfb97068936b6f4b717 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Aug 2013 17:22:21 -0400 Subject: [PATCH] [uniscribe] Ask Uniscribe to return shaping results in logical order See discussion on the list in the thread "Arabic presentation forms and the uniscribe backend". Based on patch from Jonathan Kew. --- src/hb-uniscribe.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 075875046..2bda0bc2e 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -832,9 +832,8 @@ retry: unsigned int glyphs_offset = 0; unsigned int glyphs_len; bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - for (unsigned int j = 0; j < item_count; j++) + for (unsigned int i = 0; i < item_count; i++) { - unsigned int i = backward ? item_count - 1 - j : j; unsigned int chars_offset = items[i].iCharPos; unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; @@ -875,6 +874,10 @@ retry: } } + /* Asking for glyphs in logical order circumvents at least + * one bug in Uniscribe. */ + items[i].a.fLogicalOrder = true; + retry_shape: hr = funcs->ScriptShapeOpenType (font_data->hdc, &font_data->script_cache, @@ -962,15 +965,9 @@ retry: uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; *p = MIN (*p, buffer->info[i].cluster); } - if (!backward) { - for (unsigned int i = 1; i < glyphs_len; i++) - if (vis_clusters[i] == -1) - vis_clusters[i] = vis_clusters[i - 1]; - } else { - for (int i = glyphs_len - 2; i >= 0; i--) - if (vis_clusters[i] == -1) - vis_clusters[i] = vis_clusters[i + 1]; - } + for (unsigned int i = 1; i < glyphs_len; i++) + if (vis_clusters[i] == -1) + vis_clusters[i] = vis_clusters[i - 1]; #undef utf16_index @@ -1004,10 +1001,13 @@ retry: /* TODO vertical */ pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; + pos->x_offset = backward ? -info->var1.u32 : info->var1.u32; pos->y_offset = info->var2.u32; } + if (backward) + hb_buffer_reverse (buffer); + /* Wow, done! */ return true; }