diff --git a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart index 7b036779059b5..6f6d724121136 100644 --- a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart +++ b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart @@ -15,10 +15,12 @@ const int _kSoftLineBreak = 0; const int _kHardLineBreak = 100; final List _testFonts = ['FlutterTest', 'Ahem']; -String _computeEffectiveFontFamily(String fontFamily) { - return ui_web.debugEmulateFlutterTesterEnvironment && !_testFonts.contains(fontFamily) - ? _testFonts.first - : fontFamily; +List _computeEffectiveFontFamilies(List fontFamilies) { + if (!ui_web.debugEmulateFlutterTesterEnvironment) { + return fontFamilies; + } + final Iterable filteredFonts = fontFamilies.where(_testFonts.contains); + return filteredFonts.isEmpty ? _testFonts : filteredFonts.toList(); } class SkwasmLineMetrics extends SkwasmObjectWrapper implements ui.LineMetrics { @@ -359,7 +361,7 @@ class SkwasmTextStyle implements ui.TextStyle { textStyleSetTextBaseline(handle, textBaseline!.index); } - final List effectiveFontFamilies = fontFamilies; + final List effectiveFontFamilies = _computeEffectiveFontFamilies(fontFamilies); if (effectiveFontFamilies.isNotEmpty) { withScopedFontList(effectiveFontFamilies, (Pointer families, int count) => @@ -438,8 +440,8 @@ class SkwasmTextStyle implements ui.TextStyle { } List get fontFamilies => [ - if (fontFamily != null) _computeEffectiveFontFamily(fontFamily!), - if (fontFamilyFallback != null) ...fontFamilyFallback!.map(_computeEffectiveFontFamily), + if (fontFamily != null) fontFamily!, + if (fontFamilyFallback != null) ...fontFamilyFallback!, ]; final ui.Color? color; @@ -576,16 +578,13 @@ final class SkwasmStrutStyle extends SkwasmObjectWrapper implemen ui.TextLeadingDistribution? leadingDistribution, }) { final StrutStyleHandle handle = strutStyleCreate(); - if (fontFamily != null || fontFamilyFallback != null) { - final List fontFamilies = [ - if (fontFamily != null) fontFamily, - if (fontFamilyFallback != null) ...fontFamilyFallback, - ]; - if (fontFamilies.isNotEmpty) { - withScopedFontList(fontFamilies, - (Pointer families, int count) => - strutStyleSetFontFamilies(handle, families, count)); - } + final List effectiveFontFamilies = _computeEffectiveFontFamilies([ + if (fontFamily != null) fontFamily, + if (fontFamilyFallback != null) ...fontFamilyFallback, + ]); + if (effectiveFontFamilies.isNotEmpty) { + withScopedFontList(effectiveFontFamilies, (Pointer families, int count) => + strutStyleSetFontFamilies(handle, families, count)); } if (fontSize != null) { strutStyleSetFontSize(handle, fontSize); @@ -728,9 +727,11 @@ class SkwasmParagraphStyle extends SkwasmObjectWrapper implem (renderer.fontCollection as SkwasmFontCollection).defaultTextStyle.copy(); final TextStyleHandle textStyleHandle = textStyle.handle; - if (fontFamily != null) { - withScopedFontList([fontFamily], - (Pointer families, int count) => + final List effectiveFontFamilies = _computeEffectiveFontFamilies([ + if (fontFamily != null) fontFamily + ]); + if (effectiveFontFamilies.isNotEmpty) { + withScopedFontList(effectiveFontFamilies, (Pointer families, int count) => textStyleAddFontFamilies(textStyleHandle, families, count)); } if (fontSize != null) { diff --git a/lib/web_ui/test/ui/line_metrics_test.dart b/lib/web_ui/test/ui/line_metrics_test.dart index b356c4c8d48fd..e287cb6d79cd6 100644 --- a/lib/web_ui/test/ui/line_metrics_test.dart +++ b/lib/web_ui/test/ui/line_metrics_test.dart @@ -5,6 +5,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/ui.dart' as ui; +import 'package:ui/ui_web/src/ui_web/testing.dart'; import '../common/test_initialization.dart'; import 'utils.dart'; @@ -117,17 +118,18 @@ Future testMain() async { } }, skip: isHtml); // The rounding hack doesn't apply to the html renderer - test('uses flutter test fonts when debugEmulateFlutterTesterEnvironment is enabled', () { + test('overrides with flutter test font when debugEmulateFlutterTesterEnvironment is enabled', () { final ui.ParagraphBuilder builder = ui.ParagraphBuilder(ui.ParagraphStyle()); builder.pushStyle(ui.TextStyle( fontSize: 10.0, - fontFamily: 'SomeOtherFontFamily', + fontFamily: 'Roboto', )); builder.addText('XXXX'); final ui.Paragraph paragraph = builder.build(); paragraph.layout(const ui.ParagraphConstraints(width: 400)); expect(paragraph.numberOfLines, 1); + expect(paragraph.height, 10); final ui.LineMetrics? metrics = paragraph.getLineMetricsAt(0); expect(metrics, isNotNull); @@ -135,4 +137,44 @@ Future testMain() async { // FlutterTest font's 'X' character is a square, so it's the font size (10.0) * 4 characters. expect(metrics!.width, 40.0); }); + + test('uses flutter test font by default when debugEmulateFlutterTesterEnvironment is enabled', () { + final ui.ParagraphBuilder builder = ui.ParagraphBuilder(ui.ParagraphStyle()); + builder.pushStyle(ui.TextStyle( + fontSize: 10.0, + )); + builder.addText('XXXX'); + final ui.Paragraph paragraph = builder.build(); + paragraph.layout(const ui.ParagraphConstraints(width: 400)); + + expect(paragraph.numberOfLines, 1); + expect(paragraph.height, 10); + + final ui.LineMetrics? metrics = paragraph.getLineMetricsAt(0); + expect(metrics, isNotNull); + + // FlutterTest font's 'X' character is a square, so it's the font size (10.0) * 4 characters. + expect(metrics!.width, 40.0); + }); + + test('uses specified font when debugEmulateFlutterTesterEnvironment is disabled', () { + debugEmulateFlutterTesterEnvironment = false; + + final ui.ParagraphBuilder builder = ui.ParagraphBuilder(ui.ParagraphStyle()); + builder.pushStyle(ui.TextStyle( + fontSize: 16.0, + fontFamily: 'Roboto', + )); + builder.addText('O'); + final ui.Paragraph paragraph = builder.build(); + paragraph.layout(const ui.ParagraphConstraints(width: 400)); + + expect(paragraph.numberOfLines, 1); + + final ui.LineMetrics? metrics = paragraph.getLineMetricsAt(0); + expect(metrics, isNotNull); + + // In Roboto, the width should be 11 here. In the test font, it would be square (16 points) + expect(metrics!.width, 11); + }, solo: true); }