Mirroring and bidirectional text

Some languages, such as Hebrew and Arabic, read from right to left. However, those languages often include text from other languages that read from left to right. Most of a sentence in Hebrew, for example, might read from right to left, but it might include English words that are read from left to right. This makes it necessary for Flex controls to support bidirectional text.

To use bidirectional text in a TLF text-based control, use the direction style.

Bidirectional text lets you render text from left-to-right (LTR) or right-to-left (RTL). You can embed RTL text inside an LTR block so that portions of a paragraph render LTR and portions render RTL. There is a dominant direction for the entire paragraph, but parts of the paragraph can be read in the opposite direction, and this can be nested.

The following simple example embeds a small amount of Hebrew text in a text control, and sets the direction style to rtl. The text is written and stored using the UTF-8 encoding.
<?xml version="1.0" encoding="utf-8"?>
<!-- sparktextcontrols/RTLHebrewExample.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">
        <s:layout><s:VerticalLayout/></s:layout>
    <s:Graphic>
        <s:Label direction="rtl" text="???? ??????? ????? ????? ??????  This is a Hebrew test" width="100" height="100"/>
    </s:Graphic>
</s:Application>

The executing SWF file for the previous example is shown below:

The following example includes English and two examples of RTL text (Hebrew and Arabic). The text is defined as Unicode characters, which makes it easier to follow. You can click the button to toggle the RichEditableText control from RTL to LTR.
<?xml version="1.0"?>
<!-- sparktextcontrols/RTLTest.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"
    creationComplete="addText()">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

  <fx:Style>
     @namespace s "library://ns.adobe.com/flex/spark";

     @font-face {
        src:url("../assets/MyriadWebPro.ttf");
        fontFamily: myFontFamily;
        advancedAntiAliasing: true;
        embedAsCFF: true;
        unicodeRange:
           U+0041-005A, /* Latin upper-case [A..Z] */
           U+0061-007A, /* Latin lower-case a-z */
           U+002E-002E, /* Latin period [.] */           
           U+05E1,      /* The necessary Hebrew letters */
           U+05B5, 
           U+05E4, 
           U+05B6, 
           U+05E8, 
           U+0645,      /* The necessary Arabic letters */
           U+062F, 
           U+0631, 
           U+0633, 
           U+0629; 
     }
     
     s|RichText {
        fontFamily: myFontFamily;
        fontSize: 32;
        paddingTop: 10;
     }     
  </fx:Style>
  
  <fx:Script>
  import flashx.textLayout.formats.*;
  import spark.utils.TextFlowUtil; 

    private function addText():void {
        myRT.textFlow = TextFlowUtil.importFromString("school is written " + 
            String.fromCharCode(0x0645, 0x062f, 0x0631, 0x0633, 0x0629) +
            " in Arabic and " + String.fromCharCode(0x05E1, 0x05B5, 0x05E4, 0x05B6, 0x05E8) + 
            " in Hebrew.");
    }

    private function mirrorText():void {
        if (myRT.getStyle("direction")=="ltr") {
            myRT.setStyle("direction", flashx.textLayout.formats.Direction.RTL);
        } else {
            myRT.setStyle("direction", flashx.textLayout.formats.Direction.LTR);        
        }
    }
  </fx:Script>

  <s:Panel title="RTL and LTR with embedded font">
        <s:RichText id="myRT" width="400" height="150"/>
  </s:Panel>

  <s:Button click="mirrorText()" label="Toggle Direction"/>

</s:Application>

The executing SWF file for the previous example is shown below:

Mirroring refers to laying the chrome of a component, or an entire application, out in one direction and then display in the opposite direction. For example, a mirrored TextArea would have its vertical scrollbar on the left. A mirrored Tree would have its disclosure triangles on the right. A mirrored HGroup would have its first child on the right, and a mirrored TabBar would have its first tab on the right. Mirroring can apply to subcomponents as well as chrome. For example, a mirrored RadioButton would have its label on the left side instead of the right side (the default).

Mirroring of components complement bidirectional text by having the application and components reflect the text direction.