Skip to content

Bidirectional text rendering (RTL) #574

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

Open
wants to merge 5 commits into
base: feature/rtl
Choose a base branch
from

Conversation

elsassph
Copy link
Contributor

@elsassph elsassph commented Apr 29, 2025

New renderers

New text texture renderers with opt-in bidirectional layout capability. This allows rendering right-to-left scripts (Arabic, Hebrew) and combination of left-to-right.

  • Text renderers were converted to TypeScript,
  • General code of renderers was largely unchanged, so there are no metrics changes for instance and the new renderers should be a drop-in upgrade,
  • TextTextureAdvancedRenderer now extends the TextTextureRenderer, allowing duplication to be removed,
  • Biggest change is around text layout: tokenization, wrapping and styling,
  • Text rendering tokenizer can now be overridden for instance to better support Chinese or Thai (not included by default),
  • By default bidirectional text isn't supported; it has to be enabled.

The API was designed for tree-shaking and performance: if you don't need bidi support, it won't be included and shouldn't be slower than before.

New implementation passes existing tests, and accuracy is confirmed by extra Mocha tests and new Playwright tests doing pixel comparison between real HTML rendering and the new renderer:

image

Usage

// RTL support
import { TextTexture, TextTokenizer } from '@lightningjs/core';
import { getBidiTokenizer } from '@lightningjs/core/bidiTokenizer';
TextTokenizer.setCustomTokenizer(getBidiTokenizer());
TextTexture.forceAdvancedRenderer = true; // only advanced renderer supports bidi layout
// Chinese/Thai support
import { TextTokenizer } from '@lightningjs/core';
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.

TODO

  • Fix (slightly) incorrect truncation of embedded RTL text inside LTR.

@elsassph elsassph force-pushed the feature/bidi-text branch 7 times, most recently from aa2c1ee to 21118fe Compare May 5, 2025 17:17
@elsassph elsassph force-pushed the feature/bidi-text branch from 21118fe to a66ae41 Compare May 5, 2025 17:18
@anand-patel-ap
Copy link

Hi Team,
When can we expect this PR to be reviewed and merged?

@elsassph
Copy link
Contributor Author

elsassph commented May 7, 2025

@anand-patel-ap I found some edge cases so I'm working on hardening the implementation and adding unit tests. You may need to build it yourself to try.

@anand-patel-ap
Copy link

Sure, While building i got few mirnor issues. PFA:
image

elsassph added 2 commits May 7, 2025 17:27
- allow disabling truncation (Arabic)
- WIP wordBreak (normal renderer)
- WIP unit tests
@rdkcmf-jenkins
Copy link

Coverity detected 3 issues; a quality concern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants