Fix bug in binary search for font.contains (flutter/engine#36426)

This commit is contained in:
Harry Terkelsen
2022-09-28 16:35:56 -07:00
committed by GitHub
parent 9fdbb5ad9c
commit 1a32fb8191
2 changed files with 32 additions and 26 deletions

View File

@@ -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;

View File

@@ -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,
<String>[
'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);
}
}