Font shaping function
#1
hi all,
i have the code for implementing font shaping. it is a simple method of "lookup and replace". the function the do the font shaping takes a string as an argument and returns the string with the proper font shape. can someone give me a few pointer on how subtitles are displayed. this was mint to be a helper function for fribidi. as fribidi does not support font shaping and the developers are working on that issue for version 2.

the code for the function

Quote:#define n_distinct_characters 36
//////////////////////////////////////////////////////////////////////
isfromtheset1(wchar ch)
{
   static wchar theset1[22]={
       0x62c, 0x62d, 0x62e, 0x647, 0x639, 0x63a, 0x641, 0x642,
       0x62b, 0x635, 0x636, 0x637, 0x643, 0x645, 0x646, 0x62a,
       0x644, 0x628, 0x64a, 0x633, 0x634, 0x638};
   int i = 0;
   while (i < 22)
   {
       if(ch == theset1[i])
           return true;
       ++i;
   }
   return false;
}
//////////////////////////////////////////////////////////////////////
isfromtheset2(wchar ch)
{
   static wchar theset2[12]={
       0x627, 0x623, 0x625, 0x622, 0x62f, 0x630, 0x631, 0x632,
       0x648, 0x624, 0x629, 0x649};
   int i = 0;
   while (i < 12)
   {
       if(ch == theset2[i])
           return true;
       ++i;
   }
   return false;
}

//////////////////////////////////////////////////////////////////////
cstdstringw arabicfontshaping (lpctstr in)
{
   static struct
   {
       wchar character;
       wchar endglyph;
       wchar iniglyph;
       wchar midglyph;
       wchar isoglyph;
   }a[n_distinct_characters]=
   {
       {0x630, 0xfeac, 0xfeab, 0xfeac, 0xfeab},
       {0x62f, 0xfeaa, 0xfea9, 0xfeaa, 0xfea9},
       {0x62c, 0xfe9e, 0xfe9f, 0xfea0, 0xfe9d},
       {0x62d, 0xfea2, 0xfea3, 0xfea4, 0xfea1},
       {0x62e, 0xfea6, 0xfea7, 0xfea8, 0xfea5},
       {0x647, 0xfeea, 0xfeeb, 0xfeec, 0xfee9},
       {0x639, 0xfeca, 0xfecb, 0xfecc, 0xfec9},
       {0x63a, 0xfece, 0xfecf, 0xfed0, 0xfecd},
       {0x641, 0xfed2, 0xfed3, 0xfed4, 0xfed1},
       {0x642, 0xfed6, 0xfed7, 0xfed8, 0xfed5},
       {0x62b, 0xfe9a, 0xfe9b, 0xfe9c, 0xfe99},
       {0x635, 0xfeba, 0xfebb, 0xfebc, 0xfeb9},
       {0x636, 0xfebe, 0xfebf, 0xfec0, 0xfebd},
       {0x637, 0xfec2, 0xfec3, 0xfec4, 0xfec1},
       {0x643, 0xfeda, 0xfedb, 0xfedc, 0xfed9},
       {0x645, 0xfee2, 0xfee3, 0xfee4, 0xfee1},
       {0x646, 0xfee6, 0xfee7, 0xfee8, 0xfee5},
       {0x62a, 0xfe96, 0xfe97, 0xfe98, 0xfe95},
       {0x627, 0xfe8e, 0xfe8d, 0xfe8e, 0xfe8d},
       {0x644, 0xfede, 0xfedf, 0xfee0, 0xfedd},
       {0x628, 0xfe90, 0xfe91, 0xfe92, 0xfe8f},
       {0x64a, 0xfef2, 0xfef3, 0xfef4, 0xfef1},
       {0x633, 0xfeb2, 0xfeb3, 0xfeb4, 0xfeb1},
       {0x634, 0xfeb6, 0xfeb7, 0xfeb8, 0xfeb5},
       {0x638, 0xfec6, 0xfec7, 0xfec8, 0xfec5},
       {0x632, 0xfeb0, 0xfeaf, 0xfeb0, 0xfeaf},
       {0x648, 0xfeee, 0xfeed, 0xfeee, 0xfeed},
       {0x629, 0xfe94, 0xfe93, 0xfe93, 0xfe93},
       {0x649, 0xfef0, 0xfeef, 0xfef0, 0xfeef},
       {0x631, 0xfeae, 0xfead, 0xfeae, 0xfead},
       {0x624, 0xfe86, 0xfe85, 0xfe86, 0xfe85},
       {0x621, 0xfe80, 0xfe80, 0xfe80, 0xfe7f},
       {0x626, 0xfe8a, 0xfe8b, 0xfe8c, 0xfe89},
       {0x623, 0xfe84, 0xfe83, 0xfe84, 0xfe83},
       {0x622, 0xfe82, 0xfe81, 0xfe82, 0xfe81},
       {0x625, 0xfe88, 0xfe87, 0xfe88, 0xfe87}
   };
   bool linkbefore, linkafter;
   cstdstringw out;
   out=in;
   for(uint i=0; i<_tcslen(in); i++)
   {
       wchar ch=in[i];
       if((ch>=0x0621 && ch<=0x064a)) // is an arabic character?
       {
           int idx = 0;
           while (idx < n_distinct_characters)
           {
               if (a[idx].character == in[i])
                   break;
               ++idx;
           }
           
           if(i == _tcslen(in) - 1)
               linkafter=0;
           else
               linkafter = (isfromtheset1(in[i+1]) ||
                                  isfromtheset2(in[i+1]));
           if(i == 0)
               linkbefore=0;
           else
               linkbefore=isfromtheset1(in[i-1]);
   
           if(linkbefore && linkafter)
               out.setat(i, a[idx].midglyph);
           if(linkbefore && !linkafter)
               out.setat(i, a[idx].endglyph);
           if(!linkbefore && linkafter)
               out.setat(i, a[idx].iniglyph);
           if(!linkbefore && !linkafter)
               out.setat(i, a[idx].isoglyph);
       }
   }
   return out;
}

thanks in advance for any help

ps : orginal coder mohamed abdel-monem
Reply
#2
the code to display subs is in xbmc/guiwindowfullscreen.cpp. it runs a routine in the charsetconvertor - that would probably be the place to put it.

let me know how it goes.

cheers,
jonathan
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


Image
Reply
#3
Sorry for the huge delayBlush,
I have finished integrating the font shaping functionality of Arabic characters in XBMC ( thanks "jmarshall" for the help ) .
XBMC can now display CP1256 and UTF-8 characters set (using arial.ttf) in skins and subtitles with font shaping.
However, there are some problems still exist for iso8859-6 charset. I'll try looking into it as soon as I can.

Ps: I uploaded a patch into the SVN.

XBMC Skin before Arabic font shaping
Image

XBMC Subtitles before Arabic font shaping
Image

XBMC after Arabic font shaping

XBMC Skin using Arabic CP1256
Image

XBMC subtitle in Arabic CP1256
Image

XBMC subtitle in Arabic UTF-8
Image
Reply
#4
Information 
For reference, more discussion about character joining/shaping for Semitic languages files (Amharic, Tigrinya, Hebrew, Farsi...) here:
http://forum.xbmc.org/showthread.php?tid=12637
and here:
http://forum.xbmc.org/showthread.php?tid=31425
and here:
http://forum.xbmc.org/showthread.php?tid=21599

Nerd
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#5
I have altered the rss handling routine so it can now handle RSS feeds in Arabic correctly. However, the feed is scrolling from right to left and it should be for RTL languages (at least Arabic) left to right. Can someone point me how I can achieve this.

code for handling bidi RSS feeds
Code:
if (m_shouldFlip)
    {
        // If We reaches this point, then have a bidirectional language
        // If the characters set is not UTF-8, logicalToVisualBiDi() will convert it to UTF-8
        g_charsetConverter.logicalToVisualBiDi(strSource, flippedStrSource, m_encoding, FRIBIDI_TYPE_RTL);
        // update the iconv description so it reflects the new UTF-8 to UTF-16LE not the old charset to UTF-16LE
        if (m_encoding != "UTF-8")
            m_iconv = iconv_open("UTF-16LE", "UTF-8");
    }

moreover, if the RSS feed is encoded in UTF-8, the bidi routin isn't called so I had to add an optional gui setting to force bidi that only affects the RSS display routine.
Or perhaps the routing should see if the displayed Charest in xbmc is bidi then it should force bidi conversation!?

Code:
    if (g_charsetConverter.isBidiCharset(m_encoding) || g_guiSettings.GetBool("locale.forcbidi"))
  {
      m_shouldFlip = true;
  }

RSS feed in complex Arabic script (using arial.ttf unicode)
Image

the GUI option to force RSS feeds to be handled by the bidi implementation.
Image

Ps. It goes without saying that to have complex Arabic script in xbmc gui and subtitles, arial.tff Unicode must be used
And the original fribidi implementation in xbmc hasn't been altered.
Reply
#6
^
Please inform if you find a way to change the movement of the RSS from right to left.
thanks ahead.
Reply
#7
Did this go any further? Didnt it get to the SVN?
Im curious because i want to translate XBMC to pashto
Reply
#8
I just committed this patch. It's a modified version of nirbas but performs the same. Let me know if there are any issues with it. RSS is still scrolling in the "wrong" way.

-Yuval
Reply
#9
Sooo...
Does that mean that font shaping will work in the next build of XBMC?
Reply
#10
Yes, for linux/windows/mac. For XBOX someone will need to backport it.
Reply
#11
I'm not really a programmer but is that a hard task?
Reply
#12
Shouldn't be too difficult. Just look the change set in SVN.
Reply
#13
I don't really have a hold of these kind of things so i wanted to ask if you could have a look at it if you can do it.
Reply
#14
Ah, sorry I don't have XDK nor an environment to fix it. Some other devs might.
Reply
#15
Alright... thanks for all your help.
Anybody else up for helping me out?
Reply

Logout Mark Read Team Forum Stats Members Help
Font shaping function0