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

Commit 1513a20

Browse files
committed
[web] Fix text alignment when transform + tight constraints + DOM rendering
1 parent 7e0078f commit 1513a20

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

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

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,6 @@ class CanvasParagraph implements EngineParagraph {
128128
return domElement.clone(true) as html.HtmlElement;
129129
}
130130

131-
double _getParagraphAlignOffset() {
132-
final EngineLineMetrics? longestLine = _layoutService.longestLine;
133-
if (longestLine != null) {
134-
return longestLine.left;
135-
}
136-
return 0.0;
137-
}
138-
139131
html.HtmlElement _createDomElement() {
140132
final html.HtmlElement rootElement =
141133
domRenderer.createElement('p') as html.HtmlElement;
@@ -149,9 +141,13 @@ class CanvasParagraph implements EngineParagraph {
149141
// to insert our own <BR> breaks based on layout results.
150142
..whiteSpace = 'pre';
151143

152-
final double alignOffset = _getParagraphAlignOffset();
153-
if (alignOffset != 0.0) {
154-
cssStyle.marginLeft = '${alignOffset}px';
144+
if (width > longestLine) {
145+
// In this case, we set the width so that the CSS text-align property
146+
// works correctly.
147+
// When `longestLine` is >= `paragraph.width` that means the DOM element
148+
// will automatically size itself to fit the longest line, so there's no
149+
// need to set an explicit width.
150+
cssStyle.width = '${width}px';
155151
}
156152

157153
if (paragraphStyle._maxLines != null || paragraphStyle._ellipsis != null) {

lib/web_ui/test/golden_tests/engine/canvas_paragraph/general_test.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// @dart = 2.6
66
import 'dart:async';
7+
import 'dart:math' as math;
78

89
import 'package:test/bootstrap/browser.dart';
910
import 'package:test/test.dart';
@@ -153,6 +154,50 @@ void testMain() async {
153154
return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_dom');
154155
});
155156

157+
void testAlignAndTransform(EngineCanvas canvas) {
158+
CanvasParagraph paragraph;
159+
160+
void build(CanvasParagraphBuilder builder) {
161+
builder.pushStyle(EngineTextStyle.only(color: white));
162+
builder.addText('Lorem ');
163+
builder.pushStyle(EngineTextStyle.only(color: red));
164+
builder.addText('ipsum\n');
165+
builder.pushStyle(EngineTextStyle.only(color: yellow));
166+
builder.addText('dolor');
167+
}
168+
169+
void drawParagraphAt(Offset offset, TextAlign align) {
170+
paragraph = rich(
171+
ParagraphStyle(fontFamily: 'Roboto', fontSize: 20.0, textAlign: align),
172+
build,
173+
)..layout(constrain(150.0));
174+
canvas.save();
175+
canvas.translate(offset.dx, offset.dy);
176+
canvas.rotate(math.pi / 4);
177+
final Rect rect =
178+
Rect.fromLTRB(0.0, 0.0, 150.0, paragraph.height);
179+
canvas.drawRect(rect, SurfacePaintData()..color = black);
180+
canvas.drawParagraph(paragraph, Offset.zero);
181+
canvas.restore();
182+
}
183+
184+
drawParagraphAt(Offset(50.0, 0.0), TextAlign.left);
185+
drawParagraphAt(Offset(150.0, 0.0), TextAlign.center);
186+
drawParagraphAt(Offset(250.0, 0.0), TextAlign.right);
187+
}
188+
189+
test('alignment and transform', () {
190+
final canvas = BitmapCanvas(bounds, RenderStrategy());
191+
testAlignAndTransform(canvas);
192+
return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_transform');
193+
});
194+
195+
test('alignment and transform (DOM)', () {
196+
final canvas = DomCanvas(domRenderer.createElement('flt-picture'));
197+
testAlignAndTransform(canvas);
198+
return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_transform_dom');
199+
});
200+
156201
test('paints spans with varying heights/baselines', () {
157202
final canvas = BitmapCanvas(bounds, RenderStrategy());
158203

0 commit comments

Comments
 (0)