<div dir="ltr">That happens when ligatures are applied to text.  In general, there is no 1-to-1 relationship between characters and glyphs.  You can use the cluster values in hb_glyph_info_t to match clusters of glyphs to clusters of characters.  That's the most granular mapping you can get.  In this case, you will see that one glyph (LAM-ALEF) corresponds to two characters (LAM and ALEF).<br></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 31, 2018 at 7:28 AM Laurent CRUAU <<a href="mailto:Laurent.CRUAU@ingenico.com">Laurent.CRUAU@ingenico.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="FR" link="#0563C1" vlink="#954F72">
<div class="m_-466919912107759754WordSection1">
<p class="MsoNormal">Hello there,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><span lang="EN-US">I am pretty new to harfbuzz but anyway I had not been into trouble for long using arabic shaping until recently.
<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">And now I am submitted something weird with very few Arabic strings (the vast majority of them do not cause any problem).<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">I use HB v1.0.1 on Ubuntu 16, using the regular ArialTTF mscorefont. I also tried HB v2.0.2. on an embedded target and got the same issue.<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Consider the following utf16 string:<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">"\x8D\xFE" "\xDF\xFE" "\xB4\xFE" "\xE0\xFE" "\x8E\xFE" "\xE1\xFE" "\x20\x00" "\xCB\xFE" "\xE0\xFE" "\xF4\xFE" "\xDC\xFE" "\xE2\xE”<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Or the following UTF8:<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">"\xEF\xBA\x8D\xEF\xBB\x9F\xEF\xBA\xB4\xEF\xBB\xA0\xEF\xBA\x8E\xEF\xBB\xA1\x20\xEF\xBB\x8B\xEF\xBB\xA0\xEF\xBB\xB4\xEF\xBB\x9C\xEF\xBB\xA2\x00";<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">After shaping has been performed, the following string is counted for 11 glyphs (i.e. w/ hb_buffer_len).
<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">The strange thing is that some arabic speaking persons have told me that VISUALLY, we still have 12 glyphs. And I can confirm this myself if I paste this string in an online UTF8/16 decoder. I can move through 12 characters…<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Is there some implicit fusion at stake there, or some information I should grab somewhere to match the visuals ?<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">I did not mention I played with a lot of HB options to configure shaping and I hope I have forgot something important. (hb_buffer_set_flags, hb_buffer_set_unicode_funcs(…get_default()) etc…)<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Cheers,<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Laurent<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">Here is my test snippet:<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">/*----------------------------------------------------------------------------<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">*<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">* HarfBuzz arabic shaping text<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">*<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">*----------------------------------------------------------------------------*/<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <stdio.h><u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <string.h><u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <wchar.h><u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <harfbuzz/hb.h><u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <harfbuzz/hb-ft.h><u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#define ARIAL_TTF ("/usr/share/fonts/truetype/msttcorefonts/Arial.ttf")<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#define UTF16_TEST<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">static const char utf8_content[] = "\xEF\xBA\x8D\xEF\xBB\x9F\xEF\xBA\xB4\xEF\xBB\xA0\xEF\xBA\x8E\xEF\xBB\xA1\x20\xEF\xBB\x8B\xEF\xBB\xA0\xEF\xBB\xB4\xEF\xBB\x9C\xEF\xBB\xA2\x00";<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">static const char utf16le_content[] = "\x8D\xFE" "\xDF\xFE" "\xB4\xFE" "\xE0\xFE" "\x8E\xFE" "\xE1\xFE" "\x20\x00" "\xCB\xFE" "\xE0\xFE" "\xF4\xFE" "\xDC\xFE" "\xE2\xE" "\x0\x0";<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">int main( int argc, char** argv )<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">{<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">/*data*/<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>hb_font_t*      font;<u></u><u></u></p>
<p class="MsoNormal">    hb_buffer_t*    buffer;<u></u><u></u></p>
<p class="MsoNormal">    <span lang="EN-US">hb_script_t     script;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    FT_Library      flib;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    FT_Face         face;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    int             found;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>int             ret;<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">/*code*/<u></u><u></u></p>
<p class="MsoNormal">    ret     = -1;<u></u><u></u></p>
<p class="MsoNormal">    font    = NULL;<u></u><u></u></p>
<p class="MsoNormal">    <span lang="EN-US">buffer  = NULL;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    found   = 0;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    script  = HB_SCRIPT_INVALID;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( FT_Init_FreeType(&flib) )<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("unable to initialize freetype library\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( FT_New_Face(flib, ARIAL_TTF, 0, &face) )<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("cannot create face\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    font = hb_ft_font_create(face, NULL);<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( !font )<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("uanble to create font\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    buffer = hb_buffer_create();<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( !buffer )<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("uanble to create buffer\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    // Assign text segment to buffer and examine its properties<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#ifdef UTF16_TEST<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>hb_buffer_add_utf16(buffer, (const uint16_t*)utf16le_content, 12, 0, 12);<u></u><u></u></p>
<p class="MsoNormal"><span lang="EN-US">#else<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_add_utf8(buffer, utf8_content, -1, 0, -1);<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">#endif<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_guess_segment_properties(buffer);<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    // Get script type of text<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    script = hb_buffer_get_script(buffer);   //Do not check here but Arabic script IS detected<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_set_direction(buffer, HB_DIRECTION_RTL);<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_set_language(buffer, hb_language_from_string("ar", -1));<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_shape(font, buffer, NULL, 0);<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    printf("SHAPED !\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    printf("got %d characters as a result\n", hb_buffer_get_length(buffer) );<u></u><u></u></span></p>
<p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>ret = 0;<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">main_exit:<u></u><u></u></p>
<p class="MsoNormal">  //test only, free another day<u></u><u></u></p>
<p class="MsoNormal">    exit(ret);<u></u><u></u></p>
<p class="MsoNormal"><span lang="EN-US">}<u></u><u></u></span></p>
</div>
This email and its content belong to Ingenico Group. The enclosed information is confidential and may not be disclosed to any unauthorized person. If you have received it by mistake do not forward it and delete it from your system. Cet email et son contenu
 sont la propriété du Groupe Ingenico. L’information qu’il contient est confidentielle et ne peut être communiquée à des personnes non autorisées. Si vous l’avez reçu par erreur ne le transférez pas et supprimez-le.
</div>

_______________________________________________<br>
HarfBuzz mailing list<br>
<a href="mailto:HarfBuzz@lists.freedesktop.org" target="_blank">HarfBuzz@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/harfbuzz" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/harfbuzz</a><br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">behdad<br><a href="http://behdad.org/" target="_blank">http://behdad.org/</a></div>