Skip to content

Feature/rtl #573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 36 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6f9b72b
RTL layout support
elsassph Apr 8, 2025
39060ae
set beta version
elsassph Apr 11, 2025
92baf58
Merge pull request #568 from elsassph/feat/rtl-layout
wouterlucas Apr 15, 2025
5bf481b
Fix text texture RTL propagation
elsassph Apr 24, 2025
a8d1d4f
Merge pull request #570 from elsassph/fix/rtl-text-propagation
michielvandergeest Apr 24, 2025
f8d949b
Fix ES5 package
elsassph Apr 25, 2025
fe1944b
Fix advanced renderer text alignment mirroring
elsassph Apr 25, 2025
9c5cffd
Merge pull request #572 from elsassph/fix/advanced-rtl-align
michielvandergeest Apr 28, 2025
a711b56
Bumped version to 2.16.0-beta.1.
michielvandergeest Apr 28, 2025
9a9d7e3
Merge pull request #571 from elsassph/fix/es5-compat
michielvandergeest Apr 28, 2025
a66ae41
New text texture renderers with opt-in bidi
elsassph Apr 28, 2025
19caa4a
Improvements
elsassph May 7, 2025
db8b200
wordBreak
elsassph May 16, 2025
7588e9d
letter spacing advanced
elsassph May 16, 2025
1487e66
linter
elsassph May 16, 2025
af9585a
Keep under max texture width
elsassph Jul 2, 2025
a72101a
Merge pull request #574 from elsassph/feature/bidi-text
michielvandergeest Jul 3, 2025
9e3b73f
support negative clipping coordinates in c2d renderer
elsassph Jun 5, 2025
3b99c74
integration tests
elsassph Jun 5, 2025
aa718a5
ensure calculations are correct when scaled
elsassph Jun 5, 2025
2256656
test cleanup
elsassph Jun 5, 2025
cc73977
vertical mirroring
elsassph Jun 5, 2025
079381b
test cleanup
elsassph Jun 5, 2025
364061e
cleanup redundancy
elsassph Jun 5, 2025
cc99f56
tweak automation
elsassph Jun 5, 2025
5788277
Merge pull request #576 from elsassph/fix/c2d-mirroring
michielvandergeest Jul 3, 2025
0e72973
Modify renderInfo to expose more layout data
elsassph Jul 7, 2025
9565014
version bump
elsassph Jul 7, 2025
8c446f3
Merge pull request #577 from elsassph/feature/rtl-renderinfo
michielvandergeest Jul 7, 2025
72f481c
Fix ASCII detection
elsassph Jul 9, 2025
242a5b1
version bump
elsassph Jul 9, 2025
02015af
Merge pull request #578 from elsassph/fix/detectASCII
michielvandergeest Jul 9, 2025
4517730
Bumped version in package-lock.json.
michielvandergeest Jul 9, 2025
b600e20
regex fix
elsassph Jul 10, 2025
55d7921
version bump
elsassph Jul 15, 2025
2e4451b
Merge pull request #580 from elsassph/fix/zwsp-fix
michielvandergeest Jul 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/RTL/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Right-to-left (RTL) support

Lightning applications may have to be localised for regions where the language is written from right to left, like Hebrew or Arabic. Users expect not only text to be correctly rendered, but also expect the whole application layout to be mirrored. For instance rails would be populated from right to left, and a side navigation on the left would appear on the right instead.

By opposition, the default application layout and text direction is called "left-to-right" (LTR).

RTL support encompasses 2 aspects:

- RTL layout support; which means mirroring the application layout,
- RTL text rendering support; which means accurately rendering (and wrapping) RTL text.

## How RTL layout works

To limit adaption effort for the application developer, Lightning has built-in and transparent support for RTL layout mirroring: leave `x` and flexbox directions as they are for LTR, and they will be interpreted automatically when RTL layout is enabled.

**There is however an important caveat:** in a LTR only application it is often possible to omit specifying a `w` for containers, but for automatic RTL mirroring to function, the widths need to be known, either through an explicit `w` or horizontal flexbox layout.

Here's a simplified diagram of the calculations:
![LTR vs RTL layout calculations](./ltr-rtl.png)

Lightning elements (and components) have a `rtl` property to hint whether the elements children layout should be mirrored.

In practice, setting the application's `rtl` flag will mirror the entire application, as the property is inherited. It is however possible to set some element's `rtl` to an explicit `false` to prevent mirroring of a sub-tree of the application.

The `rtl` flag will also mirror the text alignment: `left` and `right` alignment are automatically reversed. Note that this
alone doesn't mean RTL text is correctly rendered - see "Bidirectional text layout" below.

### How input works in RTL

A consequence of the choice of transparent mirroring is that the Left and Right key shoud be interpreted in accordance to the layout direction.

This is also automatic, and pressing a Left or Right key will result in the opposite Right or Left key event to be received by components when their layout is mirrored.

### How bidirectional text layout works

When working with RTL languages, we must support any combinations of LTR and RTL text: numbers and some words aren't translated; you may even have entire sentences untranslated.

Correctly rendering RTL text requires to support "bidirectional text layout", which is an advanced feature you must opt-in to.

```typescript
import { TextTexture, TextTokenizer } from '@lightningjs/core';
import { getBidiTokenizer } from '@lightningjs/core/bidiTokenizer';

// Initialize bidi text support
TextTokenizer.setCustomTokenizer(getBidiTokenizer());

// Only the "advanced renderer" supports bidi layout
TextTexture.forceAdvancedRenderer = true;
```
Binary file added docs/RTL/ltr-rtl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 43 additions & 25 deletions docs/RenderEngine/Textures/Text.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,29 @@ You can use various properties to control the way in which you want to render te

## Word Wrap in Non-Latin Based Languages

(or long URLs!)

Enabling the `wordWrap` option causes lines of text that are too long for the
specified `wordWrapWidth` to be broken into multiple lines. Lines are broken
only at word boundaries. In most latin script based languages (i.e. English,
Dutch, French, etc) the space " " character is the primary separator of word
Dutch, French, etc) the space `" "` character is the primary separator of word
boundaries.

Many non-latin based languages (i.e. Chinese, Japanese, Thai and more) do not use spaces
to separate words. Instead there is an assortment of rules that determine where
word boundaries, for the purpose of line breaking, are allowed. Lightning
currently does not implement these rules as there are many languages and writing
systems to consider when implementing them. However, we do offer a work around
that can be employed in your application as needed.
word boundaries are, for the purpose of line breaking, are allowed. Lightning
does not implement these rules as there are many languages and writing
systems to consider when implementing them. However, we do offer solutions which
can be employed in your application as needed.

See [this GitHub issue](https://github.com/rdkcentral/Lightning/issues/450) for
more information.

### Tokenization

Tokenization is the process of taking one text string and separating it in individual
words which can be wrapped. By default Lightning will break the text on spaces, but
also zero-width spaces.

### Zero-Width Spaces

Expand All @@ -67,33 +78,40 @@ Lightning supports line breaking at [Zero-Width Space](https://en.wikipedia.org/
take up no actual space between visible characers. You can use them in
your text strings and Lightning will line break on them when it needs to.

You may want to write a function that you funnel all of your application's
text strings into:
You may pre-process text and add zero-width space characters to allow Lightning
to wrap these texts.

```js
function addZeroWidthSpaces(text) {
// Code that inserts Zero-Width Spaces into text and returns the new text
}
### Custom tokenizer

class ZeroWidthSpaceTextDemo extends lng.Application {
static _template() {
return {
Text: {
text: {
text: addZeroWidthSpaces('こんにちは。初めまして!')
}
}
}
}
}
Another approach is to override Lightning's default tokenizer.

```typescript
import { TextTokenizer } from '@lightningjs/core';

// `budoux` is a tokenization library for Asian languages (Chinese, Thai...)
import { loadDefaultSimplifiedChineseParser } from 'budoux';

const getSimplifiedChineseTokenizer = (): TextTokenizer.ITextTokenizerFunction => {
const parser = loadDefaultSimplifiedChineseParser();
return (text) => [{ tokens: parser.parse(text) }];
};

TextTokenizer.setCustomTokenizer(getSimplifiedChineseTokenizer(), true);
// This Chinese tokenizer is very efficient but doesn't correctly tokenize English,
// so the second `true` parameter hints `TextTokenizer` to handle 100% English text
// with the default tokenizer.
```

See [this GitHub issue](https://github.com/rdkcentral/Lightning/issues/450) for
more information.
### Right-to-Left (RTL) support

## Live Demo
Languages like Arabic or Hebrew require special effort to be wrapped and rendered correctly.

See [Right-to-left (RTL) support](../../RTL/index.md)



## Live Demo

```
class TextDemo extends lng.Application {
static _template() {
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ The Reference Documentation for Lightning Core contains detailed descriptions ab
* [Signal](Communication/Signal.md)
* [Fire Ancestors](Communication/FireAncestors.md)
* [Accessibility](Accessibility/index.md)
* [Right-to-left support](RTL/index.md)
* [TypeScript](TypeScript/index.md)
* [Components](TypeScript/Components/index.md)
* [Template Specs](TypeScript/Components/TemplateSpecs.md)
Expand Down
Loading
Loading