Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 692b82f

Browse files
committed
[Web][HTML] Add mirrored characters support for RTL languages
1 parent 8e7bc50 commit 692b82f

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/web_ui/lib/src/engine/text/canvas_paragraph.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ class CanvasParagraph implements ui.Paragraph {
174174
}
175175

176176
final DomElement spanElement = domDocument.createElement('flt-span');
177+
if (fragment.textDirection == ui.TextDirection.rtl) {
178+
spanElement.setAttribute('dir', 'rtl');
179+
}
177180
applyTextStyleToElement(element: spanElement, style: fragment.style);
178181
_positionSpanElement(spanElement, line, fragment);
179182

lib/web_ui/test/text/canvas_paragraph_builder_test.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,41 @@ Future<void> testMain() async {
455455
);
456456
debugEmulateFlutterTesterEnvironment = true;
457457
});
458+
459+
// Regression test for https://github.com/flutter/flutter/issues/108431.
460+
// Set dir attribute for RTL fragments in order to let the browser
461+
// handle mirrored characters.
462+
test('Sets "dir" attribute for RTL fragment', () {
463+
const double fontSize = 20.0;
464+
final EngineParagraphStyle style = EngineParagraphStyle(
465+
fontSize: fontSize,
466+
textDirection: TextDirection.rtl,
467+
);
468+
final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);
469+
470+
builder.addText('(1)');
471+
472+
final CanvasParagraph paragraph = builder.build();
473+
expect(paragraph.paragraphStyle, style);
474+
expect(paragraph.plainText, '(1)');
475+
476+
paragraph.layout(const ParagraphConstraints(width: double.infinity));
477+
expectOuterHtml(
478+
paragraph,
479+
'<flt-paragraph style="${paragraphStyle()}">'
480+
'<flt-span dir="rtl" style="${spanStyle(top: null, left: null, width: null, fontSize: fontSize)}">'
481+
'('
482+
'</flt-span>'
483+
'<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: fontSize)}">'
484+
'1'
485+
'</flt-span>'
486+
'<flt-span dir="rtl" style="${spanStyle(top: null, left: null, width: null, fontSize: fontSize)}">'
487+
')'
488+
'</flt-span>'
489+
'</flt-paragraph>',
490+
ignorePositions: true,
491+
);
492+
});
458493
}
459494

460495
const String defaultFontFamily = 'Ahem';

0 commit comments

Comments
 (0)