From d01050e5fcb8ba7978fed65dfde5ae4c94e082f7 Mon Sep 17 00:00:00 2001 From: Ferhat Date: Fri, 6 Sep 2019 14:05:52 -0700 Subject: [PATCH] Fix multi span text ruler cache lookup failure. (flutter/engine#12023) --- .../lib/web_ui/lib/src/engine/text/ruler.dart | 7 +++- .../lib/web_ui/test/paragraph_test.dart | 34 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/text/ruler.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/text/ruler.dart index 242621668ff..0bfe2154698 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/text/ruler.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/text/ruler.dart @@ -759,8 +759,13 @@ class ParagraphRuler { MeasurementResult cacheLookup( EngineParagraph paragraph, ui.ParagraphConstraints constraints) { + final String plainText = paragraph._plainText; + if (plainText == null) { + // Multi span paragraph, do not use cache item. + return null; + } final List constraintCache = - _measurementCache[paragraph._plainText]; + _measurementCache[plainText]; if (constraintCache == null) { return null; } diff --git a/engine/src/flutter/lib/web_ui/test/paragraph_test.dart b/engine/src/flutter/lib/web_ui/test/paragraph_test.dart index de1796636d1..99700e11ed5 100644 --- a/engine/src/flutter/lib/web_ui/test/paragraph_test.dart +++ b/engine/src/flutter/lib/web_ui/test/paragraph_test.dart @@ -62,4 +62,38 @@ void main() async { ); } }); + + // Regression test for https://github.com/flutter/flutter/issues/37744 + test('measures heights of multiple multi-span paragraphs', () { + const double fontSize = 20.0; + final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle( + fontFamily: 'Ahem', + fontStyle: FontStyle.normal, + fontWeight: FontWeight.normal, + fontSize: fontSize, + )); + builder.addText('1234567890 1234567890 1234567890 1234567890 1234567890'); + builder.addText('1234567890 1234567890 1234567890 1234567890 1234567890'); + builder.pushStyle(TextStyle(fontWeight: FontWeight.bold)); + builder.addText('span0'); + final Paragraph paragraph = builder.build(); + paragraph.layout(ParagraphConstraints(width: fontSize * 5.0)); + expect( + paragraph.height, closeTo(fontSize * 3.0, 0.001)); // because it wraps + + // Now create another builder with just a single line of text so + // it tries to reuse ruler cache but misses. + final ParagraphBuilder builder2 = ParagraphBuilder(ParagraphStyle( + fontFamily: 'Ahem', + fontStyle: FontStyle.normal, + fontWeight: FontWeight.normal, + fontSize: fontSize, + )); + builder2.addText('span1'); + builder2.pushStyle(TextStyle(fontWeight: FontWeight.bold)); + builder2.addText('span2'); + final Paragraph paragraph2 = builder2.build(); + paragraph2.layout(ParagraphConstraints(width: fontSize * 5.0)); + expect(paragraph2.height, closeTo(fontSize, 0.001)); // because it wraps + }); }