<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="FR" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hello there,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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.
<o:p></o:p></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).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Consider the following utf16 string:<o:p></o:p></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”<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Or the following UTF8:<o:p></o:p></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";<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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).
<o:p></o:p></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…<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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 ?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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…)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Cheers,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Laurent<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Here is my test snippet:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">/*----------------------------------------------------------------------------<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">*<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">* HarfBuzz arabic shaping text<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">*<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">*----------------------------------------------------------------------------*/<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <stdio.h><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <string.h><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <wchar.h><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <harfbuzz/hb.h><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#include <harfbuzz/hb-ft.h><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#define ARIAL_TTF ("/usr/share/fonts/truetype/msttcorefonts/Arial.ttf")<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#define UTF16_TEST<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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";<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></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";<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">int main( int argc, char** argv )<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">{<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">/*data*/<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>hb_font_t*      font;<o:p></o:p></p>
<p class="MsoNormal">    hb_buffer_t*    buffer;<o:p></o:p></p>
<p class="MsoNormal">    <span lang="EN-US">hb_script_t     script;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    FT_Library      flib;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    FT_Face         face;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    int             found;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>int             ret;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">/*code*/<o:p></o:p></p>
<p class="MsoNormal">    ret     = -1;<o:p></o:p></p>
<p class="MsoNormal">    font    = NULL;<o:p></o:p></p>
<p class="MsoNormal">    <span lang="EN-US">buffer  = NULL;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    found   = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    script  = HB_SCRIPT_INVALID;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( FT_Init_FreeType(&flib) )<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("unable to initialize freetype library\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( FT_New_Face(flib, ARIAL_TTF, 0, &face) )<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("cannot create face\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    font = hb_ft_font_create(face, NULL);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( !font )<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("uanble to create font\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    buffer = hb_buffer_create();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    if( !buffer )<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    {   printf("uanble to create buffer\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        goto main_exit;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    // Assign text segment to buffer and examine its properties<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#ifdef UTF16_TEST<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>hb_buffer_add_utf16(buffer, (const uint16_t*)utf16le_content, 12, 0, 12);<o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">#else<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_add_utf8(buffer, utf8_content, -1, 0, -1);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#endif<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_guess_segment_properties(buffer);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    // Get script type of text<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    script = hb_buffer_get_script(buffer);   //Do not check here but Arabic script IS detected<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_set_direction(buffer, HB_DIRECTION_RTL);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_buffer_set_language(buffer, hb_language_from_string("ar", -1));<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    hb_shape(font, buffer, NULL, 0);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    printf("SHAPED !\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    printf("got %d characters as a result\n", hb_buffer_get_length(buffer) );<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    </span>ret = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">main_exit:<o:p></o:p></p>
<p class="MsoNormal">  //test only, free another day<o:p></o:p></p>
<p class="MsoNormal">    exit(ret);<o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></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.
</body>
</html>