Sunday, October 25, 2009

BiDi & Oh So Many Changes!

Bidi has finally landed after quite a wait this effort was contributed by Telmap and implemented mostly by Ofir Leitner.

Besides bidi Chen and myself committed allot of groundbreaking changes. Chen made some very significant performance improvements for LWUIT very noticeable in the Virtual Keyboard code. I committed more elaborate Scrollbar styling code, we now also have HorizontalScroll and can generally customize all aspects of a scroll/scroll thumb using the theme rather than using the old approach of look & feel override.

But the meat and potatoes of the commit is the bidi code... BiDi is the term refering to Bi-directional language support, generally RTL languages. There is plenty of information about RTL languages (Arabic, Hebrew, Syriac, Thaana) on the internet but as a brief primer here is a minor summary.

Most western languages are written from left to right (LTR), however some languages are normally written from right to left (RTL) speakers of these languages expect the UI to flow in the opposite direction otherwise it seems weird just like reading this word would be to most English speakers: "drieW".

The problem posed by RTL languages is known as BiDi (Bi-directional) and not as RTL since the "true" problem isn't the reversal of the writing/UI but rather the mixing of RTL and LTR together. E.g. numbers are always written from left to right (just like in English) so in an RTL language the direction is from right to left and once we reach a number or English text embedded in the middle of the sentence (such as a name) the direction switches for a duration and is later restored.

LWUIT's support for bidi includes the following components:

  • Bidi algorithm - allows converting between logical to visual representation for rendering
  • Globabl RTL flag - default flag for the entire application indicating the UI should flow from right to left
  • Individual RTL flag - flag indicating that the specific component/container should be presented as an RTL/LTR component (e.g. for displaying English elements within a RTL UI).
  • RTL text field input
  • RTL bitmap font rendering

Most of LWUIT's RTL support is under the hood, the LookAndFeel global RTL flag can be enabled using:
UIManager.getInstance().getLookAndFeel().setRTL(true);

(Notice that setting the RTL to true implicitly activates the bidi algorithm).

Once RTL is activated all positions in LWUIT become reversed and the UI becomes a mirror of itself. E.g. A softkey placed on the left moves to the right, padding on the left becomes padding on the right, the scroll moves to the left etc.
This applies to the layout managers (except for group layout) and most components. Bidi is mostly seamless in LWUIT but a developer still needs to be aware that his UI might be mirrored for these cases.

3 comments:

  1. good job Shai,
    what's the situation of the RTL language support? can i get the source and make the jar to use in my app?

    ReplyDelete
  2. Hey Shai,

    Great post, thanks. Had one question though about cutom components that use Graphics.drawString(str,x,y). The algorithms that LWUIT uses to handle RTL text, are those available via the API so i can use their output to ensure my cusotm components are rendering text correctly? Or, is all the magic done in the chain from Graphics.drawString(...)? If not, do you have any suggestions for those using custom components?

    ReplyDelete
  3. ...as a follow up to my last comment, I think I answered my own question. I hacked up a MIDlet using LWUIT and a vanilla Canvas just to see what the behaviour was for some Arabic text. It seems MIDP itself handles the RTL rendering for text, so thats all fine. I guess where LWUIT comes in for bidi is for custom fonts and layout of components.
    So I think all I need to handle is the right alignment of the text inside my component and I'm away...at least I think so :)

    ReplyDelete