Skip to content

Commit b06ff83

Browse files
authored
[web] Render RTL text correctly (flutter#26811)
1 parent 36a247f commit b06ff83

File tree

11 files changed

+1361
-151
lines changed

11 files changed

+1361
-151
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/measurement.dart
587587
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/paint_service.dart
588588
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/paragraph.dart
589589
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/ruler.dart
590+
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/text_direction.dart
590591
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/unicode_range.dart
591592
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/word_break_properties.dart
592593
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/word_breaker.dart

lib/web_ui/dev/goldens_lock.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
repository: https://github.com/flutter/goldens.git
2-
revision: 8df047cbfb1edb34569f3170a26e718fef22ffa7
2+
revision: 2b69a902e4c70b4e29044e66837e6b64aab1f473

lib/web_ui/lib/src/engine.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ export 'engine/text/canvas_paragraph.dart';
165165

166166
export 'engine/text/ruler.dart';
167167

168+
export 'engine/text/text_direction.dart';
169+
168170
export 'engine/text/unicode_range.dart';
169171

170172
export 'engine/text/word_break_properties.dart';

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class CanvasParagraph implements EngineParagraph {
7474
@override
7575
bool isLaidOut = false;
7676

77+
bool get isRtl => paragraphStyle.effectiveTextDirection == ui.TextDirection.rtl;
78+
7779
ui.ParagraphConstraints? _lastUsedConstraints;
7880

7981
late final TextLayoutService _layoutService = TextLayoutService(this);
@@ -168,7 +170,7 @@ class CanvasParagraph implements EngineParagraph {
168170

169171
// 2. Append all spans to the paragraph.
170172

171-
ParagraphSpan? span;
173+
FlatTextSpan? span;
172174

173175
html.HtmlElement element = rootElement;
174176
final List<EngineLineMetrics> lines = computeLineMetrics();
@@ -180,21 +182,34 @@ class CanvasParagraph implements EngineParagraph {
180182
}
181183

182184
final EngineLineMetrics line = lines[i];
183-
for (final RangeBox box in line.boxes!) {
185+
final List<RangeBox> boxes = line.boxes!;
186+
final StringBuffer buffer = StringBuffer();
187+
188+
int j = 0;
189+
while (j < boxes.length) {
190+
final RangeBox box = boxes[j++];
191+
if (box is SpanBox && box.span == span) {
192+
buffer.write(box.toText());
193+
continue;
194+
}
195+
196+
if (buffer.isNotEmpty) {
197+
domRenderer.appendText(element, buffer.toString());
198+
buffer.clear();
199+
}
200+
184201
if (box is SpanBox) {
185-
if (box.span != span) {
186-
span = box.span;
187-
element = domRenderer.createElement('span') as html.HtmlElement;
188-
applyTextStyleToElement(
189-
element: element,
190-
style: box.span.style,
191-
isSpan: true
192-
);
193-
domRenderer.append(rootElement, element);
194-
}
195-
domRenderer.appendText(element, box.toText());
202+
span = box.span;
203+
element = domRenderer.createElement('span') as html.HtmlElement;
204+
applyTextStyleToElement(
205+
element: element,
206+
style: box.span.style,
207+
isSpan: true,
208+
);
209+
domRenderer.append(rootElement, element);
210+
buffer.write(box.toText());
196211
} else if (box is PlaceholderBox) {
197-
span = box.placeholder;
212+
span = null;
198213
// If there's a line-end after this placeholder, we want the <BR> to
199214
// be inserted in the root paragraph element.
200215
element = rootElement;
@@ -207,6 +222,11 @@ class CanvasParagraph implements EngineParagraph {
207222
}
208223
}
209224

225+
if (buffer.isNotEmpty) {
226+
domRenderer.appendText(element, buffer.toString());
227+
buffer.clear();
228+
}
229+
210230
final String? ellipsis = line.ellipsis;
211231
if (ellipsis != null) {
212232
domRenderer.appendText(element, ellipsis);

0 commit comments

Comments
 (0)