Search code examples
cunicodeunicode-stringfreetypeharfbuzz

How to reorder bidirectional text using fribidi


I have a combined English-ASCII/ Arabic-Unicode string like :

متن
abc
یک

3 Unicode Arabic character + space + 3 ASCII English character + space + 2 Unicode Arabic character

UTF8:"\xD9\x85\xD8\xAA\xD9\x86\x20\x31\x32\x33\x20\xD9\x8C\xD8\xA9"

UTF16: "\xFEE3\xFE98\xFEE3\x20\x31\x32\x33\x20\xFBFE\xFB8F"

For Displaying text in joint form like above, my embedded devices API accepts Unicode Arabic Presentation Form B in reversed order. Therefor I need to reorder this string to below Form:

Reordered UTF16: "\xFB8F\xFBFE\x20\x31\x32\x33\x20\xFEE3\xFE98\xFEE3"

and convert it to the UTF8 Presentation Form B:

UTF8_FormB:"\xef\xae\x8f\xef\xaf\xbe\x20\x31\x32\x33\x20\xef\xbb\xa6\xef\xba\x98\xef\xbb\xa3"

My question is about reordering step which reorder

UTF16: "\xFEE3\xFE98\xFEE3\x20\x31\x32\x33\x20\xFBFE\xFB8F"

to

Reordered UTF16: "\xFB8F\xFBFE\x20\x31\x32\x33\x20\xFEE3\xFE98\xFEE3"

I think I need to use Fribidi to do this. This is How I'm using Fribidi:

uint32_t                utf16Str[256]       = { 0};
uint32_t                reorderedStr[256]   = { 0};
uint16_t                rawLen              = 0;
uint16_t                utf16Len            = 0;
FriBidiCharType         pbase_dir           = FRIBIDI_TYPE_ON;
fribidi_boolean         stat;

    stat =  fribidi_log2vis(
    /* input */
    utf16Str,//UTF16: "\xFEE3\xFE98\xFEE3\x20\x31\x32\x33\x20\xFBFE\xFB8F" // یک abc متن
    utf16Len,//10
    &pbase_dir,
    /* output */
    reorderedStr,//this must be filled with reordered string.
    NULL,
    NULL,
    NULL);

But the output is exactly the same as the input. And Fribidi instead of reordering just copied input to the output. Is there anything wrong with method Flags and such?


Solution

  • The problem was about using the wrong pbase_dir flag. Using the below flag

    FriBidiCharType pbase_dir = FRIBIDI_TYPE_RTL;
    

    Fribidi works fine and correctly reorders my text as expected.