Skip to content

RTL Support

Lexis provides comprehensive Right-to-Left (RTL) language support for Arabic, Hebrew, Persian, Urdu, and other RTL languages.

The RtlSupport static class provides core RTL detection and layout utilities.

csharp
using Lexis.Utilities;

// Check if a locale is RTL
bool isArabicRtl = RtlSupport.IsRtlLocale("ar");      // true
bool isEnglishRtl = RtlSupport.IsRtlLocale("en");    // false
bool isCurrentRtl = RtlSupport.IsCurrentLocaleRtl(); // Based on active locale

// Character and text analysis
bool hasRtl = RtlSupport.ContainsRtlCharacters("Hello مرحبا");
var direction = RtlSupport.DetectTextDirection("مرحبا Hello");
// direction.IsRTL, direction.RtlRatio, direction.RtlCharCount

// Layout flipping
TextAnchor flipped = RtlSupport.FlipAnchor(TextAnchor.MiddleLeft, isRtl: true);
// Result: TextAnchor.MiddleRight

// Unicode directional marks
string marked = RtlSupport.AddDirectionalMark("Text", isRtl: true);
string wrapped = RtlSupport.WrapWithDirectionalEmbedding("مرحبا", isRtl: true);

Supported RTL Locales:

  • Arabic (ar, ar-SA, ar-EG, ar-AE, etc.)
  • Hebrew (he, he-IL, iw)
  • Persian/Farsi (fa, fa-IR)
  • Urdu (ur, ur-PK)
  • Pashto (ps), Kurdish (ckb), Sindhi (sd), Uyghur (ug), Yiddish (yi), Divehi (dv)

Handles bidirectional text processing for mixed LTR/RTL content using Unicode BiDi algorithm principles.

csharp
using Lexis.Utilities;

// Process mixed text for proper display
string text = "Hello مرحبا World";
string processed = BidirectionalTextHandler.Process(text, TextDirection.RightToLeft);

// Isolate LTR content within RTL text
string arabicText = $"رقم المنتج: {BidirectionalTextHandler.IsolateLtr("ABC-123")}";

// Isolate RTL content within LTR text
string englishText = $"Welcome, {BidirectionalTextHandler.IsolateRtl("محمد")}!";

// Get directional segments for analysis
var segments = BidirectionalTextHandler.GetDirectionalSegments("Hello مرحبا");
// Returns segments with Text, Direction, StartIndex, Length

// Check for mixed content
bool hasMixed = BidirectionalTextHandler.ContainsMixedDirections("Hello مرحبا");

TextDirection Enum:

  • LeftToRight - Force LTR processing
  • RightToLeft - Force RTL processing
  • Auto - Detect from first strong character

Mirrors paired punctuation for RTL display according to Unicode Bidi_Mirrored property.

csharp
using Lexis.Utilities;

// Mirror single character
char mirrored = PunctuationMirror.Mirror('(');  // Returns ')'

// Mirror all punctuation in a string
string result = PunctuationMirror.MirrorPunctuation("f(x) = [a + b]");
// Returns: "f)x( = ]a + b["

// Check if character has a mirror
bool hasMirror = PunctuationMirror.HasMirror('[');  // true

// Mirror only in RTL segments of mixed text
string mixed = PunctuationMirror.MirrorPunctuationInRtlSegments("Hello (x) مرحبا (y)");

Supported Mirror Pairs:

  • Basic: (), [], {}, <>
  • Guillemets: «», ‹›
  • Quotes: '', "", „", ‚'
  • CJK: 「」, 『』, 【】, 〔〕
  • Fullwidth: (), [], {}
  • Mathematical: ⟨⟩, ⌈⌉, ⌊⌋, ⟦⟧

LocalizedText and LocalizedTMP

Both text components support RTL with the RtlMode property:

csharp
using Lexis.Components;

// In Inspector or code
localizedText.RtlMode = RtlMode.Auto;        // Detect from locale (default)
localizedText.RtlMode = RtlMode.ForceRtl;    // Always RTL
localizedText.RtlMode = RtlMode.Disabled;    // Ignore RTL

// Additional RTL properties
localizedText.FlipAlignment = true;   // Auto-flip Left ↔ Right alignment
localizedText.ProcessBidiText = true; // Process mixed direction text

LocalizedTMP Additional Features:

csharp
localizedTMP.UseTmpRtl = true;  // Enable TMP's native isRightToLeftText

LocalizedLabel (UI Toolkit)

csharp
using Lexis.UIToolkit;

var label = new LocalizedLabel();
label.RtlMode = RtlMode.Auto;
label.ProcessBidiText = true;

// USS classes are automatically toggled:
// .rtl - Applied when in RTL mode
// .ltr - Applied when in LTR mode

RtlLayoutGroup (uGUI)

Automatically flips HorizontalLayoutGroup children for RTL locales.

csharp
using Lexis.Components;

// Add to GameObject with HorizontalLayoutGroup
[RequireComponent(typeof(HorizontalLayoutGroup))]
public class MyPanel : MonoBehaviour
{
    [SerializeField] private RtlLayoutGroup rtlLayout;

    void ConfigureLayout()
    {
        rtlLayout.AutoFlip = true;      // Auto-flip based on locale
        rtlLayout.ForceRtl = false;     // Manual override
        rtlLayout.FlipAlignment = true; // Also flip child alignment
        rtlLayout.FlipPadding = true;   // Flip left/right padding
    }
}

RtlContainer (UI Toolkit)

xml
<!-- UXML -->
<ui:UXML xmlns:lexis="Lexis.UIToolkit">
    <lexis:RtlContainer auto-flip="true" flip-justify="true">
        <ui:Label text="First" />
        <ui:Label text="Second" />
        <ui:Label text="Third" />
    </lexis:RtlContainer>
</ui:UXML>
csharp
using Lexis.UIToolkit;

var container = new RtlContainer();
container.AutoFlip = true;       // Auto-flip based on locale
container.FlipJustify = true;    // Flip justify-content

// Vertical containers
var vertical = new RtlVerticalContainer();
vertical.AutoFlip = true;        // Flips horizontal alignment in RTL

USS Styling:

css
.rtl-container.rtl {
    /* RTL-specific styles */
}

.rtl-container.ltr {
    /* LTR-specific styles */
}
  1. Use Start/End instead of Left/Right when possible:

    csharp
    var alignment = RtlSupport.ResolveAlignment(
        LocalizedTextAlignment.Start,  // Left in LTR, Right in RTL
        TextAnchor.MiddleCenter,
        RtlSupport.IsCurrentLocaleRtl());
  2. Test with Arabic and Hebrew - They have different character sets but both are RTL.

  3. Handle mixed content - Product codes, numbers, and brand names often need isolation:

    csharp
    string price = $"{BidirectionalTextHandler.IsolateLtr("$99.99")} السعر";
  4. Use locale fonts - Arabic and Hebrew often require specific fonts:

    csharp
    localizedTMP.UseLocaleFont = true;  // Uses Locale.Font if set
  5. Consider layout mirroring - Use RtlLayoutGroup for horizontal UI panels.


Professional Unity Development Tools