Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion lib/web_ui/dev/goldens_lock.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
repository: https://github.com/flutter/goldens.git
revision: 0e62a287b5109053bc3e59dd8fc832f488d904c9
revision: 0dd2e82050422c05e9daf652fa4267fb7c01f260
15 changes: 3 additions & 12 deletions lib/web_ui/lib/src/engine/html/bitmap_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ class BitmapCanvas extends EngineCanvas {
///
/// The text is drawn starting at coordinates ([x], [y]). It uses the current
/// font set by the most recent call to [setCssFont].
void drawText(String text, double x, double y, {ui.PaintingStyle? style, List<ui.Shadow>? shadows}) {
void fillText(String text, double x, double y, {List<ui.Shadow>? shadows}) {
final html.CanvasRenderingContext2D ctx = _canvasPool.context;
if (shadows != null) {
ctx.save();
Expand All @@ -919,20 +919,11 @@ class BitmapCanvas extends EngineCanvas {
ctx.shadowOffsetX = shadow.offset.dx;
ctx.shadowOffsetY = shadow.offset.dy;

if (style == ui.PaintingStyle.stroke) {
ctx.strokeText(text, x, y);
} else {
ctx.fillText(text, x, y);
}
ctx.fillText(text, x, y);
}
ctx.restore();
}

if (style == ui.PaintingStyle.stroke) {
ctx.strokeText(text, x, y);
} else {
ctx.fillText(text, x, y);
}
ctx.fillText(text, x, y);
}

@override
Expand Down
8 changes: 3 additions & 5 deletions lib/web_ui/lib/src/engine/text/paint_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,15 @@ class TextPaintService {
);
final double? letterSpacing = span.style.letterSpacing;
if (letterSpacing == null || letterSpacing == 0.0) {
canvas.drawText(text, x, y,
style: span.style.foreground?.style, shadows: span.style.shadows);
canvas.fillText(text, x, y, shadows: span.style.shadows);
} else {
// TODO(mdebbar): Implement letter-spacing on canvas more efficiently:
// https://github.com/flutter/flutter/issues/51234
double charX = x;
final int len = text.length;
for (int i = 0; i < len; i++) {
final String char = text[i];
canvas.drawText(char, charX.roundToDouble(), y,
style: span.style.foreground?.style,
canvas.fillText(char, charX.roundToDouble(), y,
shadows: span.style.shadows);
charX += letterSpacing + canvas.measureText(char).width!;
}
Expand All @@ -124,7 +122,7 @@ class TextPaintService {
final String? ellipsis = line.ellipsis;
if (ellipsis != null && box == line.boxes.last) {
final double x = offset.dx + line.left + box.right;
canvas.drawText(ellipsis, x, y, style: span.style.foreground?.style);
canvas.fillText(ellipsis, x, y);
}

canvas.tearDownPaint();
Expand Down
16 changes: 1 addition & 15 deletions lib/web_ui/lib/src/engine/text/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -696,21 +696,7 @@ void applyTextStyleToElement({
final html.CssStyleDeclaration cssStyle = element.style;

final ui.Color? color = style.foreground?.color ?? style.color;
if (style.foreground?.style == ui.PaintingStyle.stroke) {
// When comparing the outputs of the Bitmap Canvas and the DOM
// implementation, we have found, that we need to set the background color
// of the text to transparent to achieve the same effect as in the Bitmap
// Canvas and the Skia Engine where only the text stroke is painted.
// If we don't set it here to transparent, the text will inherit the color
// of it's parent element.
cssStyle.color = 'transparent';
// Use hairline (device pixel when strokeWidth is not specified).
final double? strokeWidth = style.foreground?.strokeWidth;
final double adaptedWidth = strokeWidth != null && strokeWidth > 0
? strokeWidth
: 1.0 / ui.window.devicePixelRatio;
cssStyle.textStroke = '${adaptedWidth}px ${colorToCssString(color)}';
} else if (color != null) {
if (color != null) {
cssStyle.color = colorToCssString(color);
}
final ui.Color? background = style.background?.color;
Expand Down
38 changes: 0 additions & 38 deletions lib/web_ui/test/html/paragraph/general_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -502,42 +502,4 @@ Future<void> testMain() async {
testBackgroundStyle(canvas);
return takeScreenshot(canvas, bounds, 'canvas_paragraph_background_style_dom');
});

void testForegroundStyle(EngineCanvas canvas) {
final CanvasParagraph paragraph = rich(
EngineParagraphStyle(fontFamily: 'Roboto', fontSize: 40.0),
(CanvasParagraphBuilder builder) {
builder.pushStyle(EngineTextStyle.only(color: blue));
builder.addText('Lorem');
builder.pop();
builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = red..style = PaintingStyle.stroke));
builder.addText('ipsum\n');
builder.pop();
builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = blue..style = PaintingStyle.stroke..strokeWidth = 0.0));
builder.addText('dolor');
builder.pop();
builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = green..style = PaintingStyle.stroke..strokeWidth = 2.0));
builder.addText('sit\n');
builder.pop();
builder.pushStyle(EngineTextStyle.only(foreground: Paint()..color = yellow..style = PaintingStyle.stroke..strokeWidth = 4.0));
builder.addText('amet');
},
);
paragraph.layout(constrain(double.infinity));
canvas.drawParagraph(paragraph, Offset.zero);
}

test('foreground style', () {
const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
final BitmapCanvas canvas = BitmapCanvas(bounds, RenderStrategy());
testForegroundStyle(canvas);
return takeScreenshot(canvas, bounds, 'canvas_paragraph_foreground_style');
});

test('foreground style (DOM)', () {
const Rect bounds = Rect.fromLTWH(0, 0, 300, 200);
final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture'));
testForegroundStyle(canvas);
return takeScreenshot(canvas, bounds, 'canvas_paragraph_foreground_style_dom');
});
}