From 1a32fb81914e954e06ebfa66ba4c00bbcc550e75 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Wed, 28 Sep 2022 16:35:56 -0700 Subject: [PATCH] Fix bug in binary search for font.contains (flutter/engine#36426) --- .../lib/src/engine/canvaskit/noto_font.dart | 29 ++++--------------- .../canvaskit/fallback_fonts_golden_test.dart | 29 +++++++++++++++++-- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/noto_font.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/noto_font.dart index 83964c6f42..ad5b43e92a 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/noto_font.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/noto_font.dart @@ -37,33 +37,16 @@ class NotoFont { // is a range that contains the codeunit. int min = 0; int max = _rangeStarts.length - 1; - // Search for the first rangeStart that is greater than codeunit. - while (min < max) { + while (min <= max) { final int mid = (min + max) ~/ 2; if (_rangeStarts[mid] > codeUnit) { - if (mid == 0) { - final int rangeStart = _rangeStarts[mid]; - final int rangeEnd = _rangeEnds[mid]; - return rangeStart <= codeUnit && codeUnit <= rangeEnd; - } - final int rangeStart = _rangeStarts[mid - 1]; - if (rangeStart <= codeUnit) { - final int rangeEnd = _rangeEnds[mid - 1]; - return rangeStart <= codeUnit && codeUnit <= rangeEnd; - } else { - max = mid - 1; - } - } else if (_rangeStarts[mid] < codeUnit) { - // If this is the last index, check if the codeunit is contained within it. - if (mid == _rangeStarts.length) { - final int rangeStart = _rangeStarts[mid]; - final int rangeEnd = _rangeEnds[mid]; - return rangeStart <= codeUnit && codeUnit <= rangeEnd; + max = mid - 1; + } else { + // _rangeStarts[mid] <= codeUnit + if (_rangeEnds[mid] >= codeUnit) { + return true; } min = mid + 1; - } else { - // _rangeStarts[mid] == codeUnit - return true; } } return false; diff --git a/engine/src/flutter/lib/web_ui/test/canvaskit/fallback_fonts_golden_test.dart b/engine/src/flutter/lib/web_ui/test/canvaskit/fallback_fonts_golden_test.dart index 66ba97d7eb..84c05602b8 100644 --- a/engine/src/flutter/lib/web_ui/test/canvaskit/fallback_fonts_golden_test.dart +++ b/engine/src/flutter/lib/web_ui/test/canvaskit/fallback_fonts_golden_test.dart @@ -199,6 +199,31 @@ void testMain() { expect(loggingDownloader.log, isEmpty); }); + test('can find glyph for 2/3 symbol', () async { + final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer; + final LoggingDownloader loggingDownloader = + LoggingDownloader(NotoDownloader()); + notoDownloadQueue.downloader = loggingDownloader; + // Try rendering text that requires fallback fonts, initially before the fonts are loaded. + + CkParagraphBuilder(CkParagraphStyle()).addText('⅔'); + rasterizer.debugRunPostFrameCallbacks(); + await notoDownloadQueue.debugWhenIdle(); + expect( + loggingDownloader.log, + [ + 'Noto Sans', + ], + ); + + // Do the same thing but this time with loaded fonts. + loggingDownloader.log.clear(); + CkParagraphBuilder(CkParagraphStyle()).addText('⅔'); + rasterizer.debugRunPostFrameCallbacks(); + await notoDownloadQueue.debugWhenIdle(); + expect(loggingDownloader.log, isEmpty); + }); + test('findMinimumFontsForCodeunits for all supported code units', () async { final LoggingDownloader loggingDownloader = LoggingDownloader(NotoDownloader()); @@ -213,9 +238,7 @@ void testMain() { for (final NotoFont font in notoTree.root.enumerateAllElements()) { testedFonts.add(font.name); for (final CodeunitRange range in font.computeUnicodeRanges()) { - for (int codeUnit = range.start; - codeUnit < range.end; - codeUnit += 1) { + for (int codeUnit = range.start; codeUnit < range.end; codeUnit++) { supportedUniqueCodeUnits.add(codeUnit); } }