@@ -12,19 +12,19 @@ bool _registeredSymbolsAndEmoji = false;
1212
1313final Set <int > codeUnitsWithNoKnownFont = < int > {};
1414
15- Future <void > _findFontsForMissingCodeunits (List <int > codeunits) async {
15+ Future <void > findFontsForMissingCodeunits (List <int > codeunits) async {
1616 _ensureNotoFontTreeCreated ();
1717
1818 // If all of the code units are known to have no Noto Font which covers them,
1919 // then just give up. We have already logged a warning.
2020 if (codeunits.every ((u) => codeUnitsWithNoKnownFont.contains (u))) {
2121 return ;
2222 }
23- Set <_NotoFont > fonts = < _NotoFont > {};
23+ Set <NotoFont > fonts = < NotoFont > {};
2424 Set <int > coveredCodeUnits = < int > {};
2525 Set <int > missingCodeUnits = < int > {};
2626 for (int codeunit in codeunits) {
27- List <_NotoFont > fontsForUnit = _notoTree! .intersections (codeunit);
27+ List <NotoFont > fontsForUnit = _notoTree! .intersections (codeunit);
2828 fonts.addAll (fontsForUnit);
2929 if (fontsForUnit.isNotEmpty) {
3030 coveredCodeUnits.add (codeunit);
@@ -33,15 +33,15 @@ Future<void> _findFontsForMissingCodeunits(List<int> codeunits) async {
3333 }
3434 }
3535
36- fonts = _findMinimumFontsForCodeunits (coveredCodeUnits, fonts);
36+ fonts = findMinimumFontsForCodeunits (coveredCodeUnits, fonts);
3737
38- for (_NotoFont font in fonts) {
38+ for (NotoFont font in fonts) {
3939 await font.ensureResolved ();
4040 }
4141
4242 Set <_ResolvedNotoSubset > resolvedFonts = < _ResolvedNotoSubset > {};
4343 for (int codeunit in coveredCodeUnits) {
44- for (_NotoFont font in fonts) {
44+ for (NotoFont font in fonts) {
4545 if (font.resolvedFont == null ) {
4646 // We failed to resolve the font earlier.
4747 continue ;
@@ -232,18 +232,20 @@ Future<void> _registerSymbolsAndEmoji() async {
232232/// which finds the font which covers the most codeunits. If multiple CJK
233233/// fonts match the same number of codeunits, we choose one based on the user's
234234/// locale.
235- Set <_NotoFont > _findMinimumFontsForCodeunits (
236- Iterable <int > codeunits, Set <_NotoFont > fonts) {
235+ Set <NotoFont > findMinimumFontsForCodeunits (
236+ Iterable <int > codeunits, Set <NotoFont > fonts) {
237+ assert (fonts.isNotEmpty || codeunits.isEmpty);
237238 List <int > unmatchedCodeunits = List <int >.from (codeunits);
238- Set <_NotoFont > minimumFonts = < _NotoFont > {};
239- List <_NotoFont > bestFonts = < _NotoFont > [];
240- int maxCodeunitsCovered = 0 ;
239+ Set <NotoFont > minimumFonts = < NotoFont > {};
240+ List <NotoFont > bestFonts = < NotoFont > [];
241241
242242 String language = html.window.navigator.language;
243243
244244 // This is guaranteed to terminate because [codeunits] is a list of fonts
245245 // which we've already determined are covered by [fonts].
246246 while (unmatchedCodeunits.isNotEmpty) {
247+ int maxCodeunitsCovered = 0 ;
248+ bestFonts.clear ();
247249 for (var font in fonts) {
248250 int codeunitsCovered = 0 ;
249251 for (int codeunit in unmatchedCodeunits) {
@@ -259,10 +261,13 @@ Set<_NotoFont> _findMinimumFontsForCodeunits(
259261 bestFonts.add (font);
260262 }
261263 }
262- assert (bestFonts.isNotEmpty);
264+ assert (
265+ bestFonts.isNotEmpty,
266+ 'Did not find any fonts that cover code units: ${unmatchedCodeunits .join (', ' )}' ,
267+ );
263268 // If the list of best fonts are all CJK fonts, choose the best one based
264269 // on locale. Otherwise just choose the first font.
265- _NotoFont bestFont = bestFonts.first;
270+ NotoFont bestFont = bestFonts.first;
266271 if (bestFonts.length > 1 ) {
267272 if (bestFonts.every ((font) => _cjkFonts.contains (font))) {
268273 if (language == 'zh-Hans' ||
@@ -301,27 +306,27 @@ void _ensureNotoFontTreeCreated() {
301306 return ;
302307 }
303308
304- Map <_NotoFont , List <CodeunitRange >> ranges =
305- < _NotoFont , List <CodeunitRange >> {};
309+ Map <NotoFont , List <CodeunitRange >> ranges =
310+ < NotoFont , List <CodeunitRange >> {};
306311
307- for (_NotoFont font in _notoFonts) {
312+ for (NotoFont font in _notoFonts) {
308313 for (CodeunitRange range in font.unicodeRanges) {
309314 ranges.putIfAbsent (font, () => < CodeunitRange > []).add (range);
310315 }
311316 }
312317
313- _notoTree = IntervalTree <_NotoFont >.createFromRanges (ranges);
318+ _notoTree = IntervalTree <NotoFont >.createFromRanges (ranges);
314319}
315320
316- class _NotoFont {
321+ class NotoFont {
317322 final String name;
318323 final List <CodeunitRange > unicodeRanges;
319324
320325 Completer <void >? _decodingCompleter;
321326
322327 _ResolvedNotoFont ? resolvedFont;
323328
324- _NotoFont (this .name, this .unicodeRanges);
329+ NotoFont (this .name, this .unicodeRanges);
325330
326331 bool matchesCodeunit (int codeunit) {
327332 for (CodeunitRange range in unicodeRanges) {
@@ -397,45 +402,45 @@ class _ResolvedNotoSubset {
397402 String toString () => '_ResolvedNotoSubset($family , $url )' ;
398403}
399404
400- _NotoFont _notoSansSC = _NotoFont ('Noto Sans SC' , < CodeunitRange > [
405+ NotoFont _notoSansSC = NotoFont ('Noto Sans SC' , < CodeunitRange > [
401406 CodeunitRange (12288 , 12591 ),
402407 CodeunitRange (12800 , 13311 ),
403408 CodeunitRange (19968 , 40959 ),
404409 CodeunitRange (65072 , 65135 ),
405410 CodeunitRange (65280 , 65519 ),
406411]);
407412
408- _NotoFont _notoSansTC = _NotoFont ('Noto Sans TC' , < CodeunitRange > [
413+ NotoFont _notoSansTC = NotoFont ('Noto Sans TC' , < CodeunitRange > [
409414 CodeunitRange (12288 , 12351 ),
410415 CodeunitRange (12549 , 12585 ),
411416 CodeunitRange (19968 , 40959 ),
412417]);
413418
414- _NotoFont _notoSansHK = _NotoFont ('Noto Sans HK' , < CodeunitRange > [
419+ NotoFont _notoSansHK = NotoFont ('Noto Sans HK' , < CodeunitRange > [
415420 CodeunitRange (12288 , 12351 ),
416421 CodeunitRange (12549 , 12585 ),
417422 CodeunitRange (19968 , 40959 ),
418423]);
419424
420- _NotoFont _notoSansJP = _NotoFont ('Noto Sans JP' , < CodeunitRange > [
425+ NotoFont _notoSansJP = NotoFont ('Noto Sans JP' , < CodeunitRange > [
421426 CodeunitRange (12288 , 12543 ),
422427 CodeunitRange (19968 , 40959 ),
423428 CodeunitRange (65280 , 65519 ),
424429]);
425430
426- List <_NotoFont > _cjkFonts = < _NotoFont > [
431+ List <NotoFont > _cjkFonts = < NotoFont > [
427432 _notoSansSC,
428433 _notoSansTC,
429434 _notoSansHK,
430435 _notoSansJP,
431436];
432437
433- List <_NotoFont > _notoFonts = < _NotoFont > [
438+ List <NotoFont > _notoFonts = < NotoFont > [
434439 _notoSansSC,
435440 _notoSansTC,
436441 _notoSansHK,
437442 _notoSansJP,
438- _NotoFont ('Noto Naskh Arabic UI' , < CodeunitRange > [
443+ NotoFont ('Noto Naskh Arabic UI' , < CodeunitRange > [
439444 CodeunitRange (1536 , 1791 ),
440445 CodeunitRange (8204 , 8206 ),
441446 CodeunitRange (8208 , 8209 ),
@@ -444,44 +449,44 @@ List<_NotoFont> _notoFonts = <_NotoFont>[
444449 CodeunitRange (64336 , 65023 ),
445450 CodeunitRange (65132 , 65276 ),
446451 ]),
447- _NotoFont ('Noto Sans Armenian' , < CodeunitRange > [
452+ NotoFont ('Noto Sans Armenian' , < CodeunitRange > [
448453 CodeunitRange (1328 , 1424 ),
449454 CodeunitRange (64275 , 64279 ),
450455 ]),
451- _NotoFont ('Noto Sans Bengali UI' , < CodeunitRange > [
456+ NotoFont ('Noto Sans Bengali UI' , < CodeunitRange > [
452457 CodeunitRange (2404 , 2405 ),
453458 CodeunitRange (2433 , 2555 ),
454459 CodeunitRange (8204 , 8205 ),
455460 CodeunitRange (8377 , 8377 ),
456461 CodeunitRange (9676 , 9676 ),
457462 ]),
458- _NotoFont ('Noto Sans Myanmar UI' , < CodeunitRange > [
463+ NotoFont ('Noto Sans Myanmar UI' , < CodeunitRange > [
459464 CodeunitRange (4096 , 4255 ),
460465 CodeunitRange (8204 , 8205 ),
461466 CodeunitRange (9676 , 9676 ),
462467 ]),
463- _NotoFont ('Noto Sans Egyptian Hieroglyphs' , < CodeunitRange > [
468+ NotoFont ('Noto Sans Egyptian Hieroglyphs' , < CodeunitRange > [
464469 CodeunitRange (77824 , 78894 ),
465470 ]),
466- _NotoFont ('Noto Sans Ethiopic' , < CodeunitRange > [
471+ NotoFont ('Noto Sans Ethiopic' , < CodeunitRange > [
467472 CodeunitRange (4608 , 5017 ),
468473 CodeunitRange (11648 , 11742 ),
469474 CodeunitRange (43777 , 43822 ),
470475 ]),
471- _NotoFont ('Noto Sans Georgian' , < CodeunitRange > [
476+ NotoFont ('Noto Sans Georgian' , < CodeunitRange > [
472477 CodeunitRange (1417 , 1417 ),
473478 CodeunitRange (4256 , 4351 ),
474479 CodeunitRange (11520 , 11567 ),
475480 ]),
476- _NotoFont ('Noto Sans Gujarati UI' , < CodeunitRange > [
481+ NotoFont ('Noto Sans Gujarati UI' , < CodeunitRange > [
477482 CodeunitRange (2404 , 2405 ),
478483 CodeunitRange (2688 , 2815 ),
479484 CodeunitRange (8204 , 8205 ),
480485 CodeunitRange (8377 , 8377 ),
481486 CodeunitRange (9676 , 9676 ),
482487 CodeunitRange (43056 , 43065 ),
483488 ]),
484- _NotoFont ('Noto Sans Gurmukhi UI' , < CodeunitRange > [
489+ NotoFont ('Noto Sans Gurmukhi UI' , < CodeunitRange > [
485490 CodeunitRange (2404 , 2405 ),
486491 CodeunitRange (2561 , 2677 ),
487492 CodeunitRange (8204 , 8205 ),
@@ -490,13 +495,13 @@ List<_NotoFont> _notoFonts = <_NotoFont>[
490495 CodeunitRange (9772 , 9772 ),
491496 CodeunitRange (43056 , 43065 ),
492497 ]),
493- _NotoFont ('Noto Sans Hebrew' , < CodeunitRange > [
498+ NotoFont ('Noto Sans Hebrew' , < CodeunitRange > [
494499 CodeunitRange (1424 , 1535 ),
495500 CodeunitRange (8362 , 8362 ),
496501 CodeunitRange (9676 , 9676 ),
497502 CodeunitRange (64285 , 64335 ),
498503 ]),
499- _NotoFont ('Noto Sans Devanagari UI' , < CodeunitRange > [
504+ NotoFont ('Noto Sans Devanagari UI' , < CodeunitRange > [
500505 CodeunitRange (2304 , 2431 ),
501506 CodeunitRange (7376 , 7414 ),
502507 CodeunitRange (7416 , 7417 ),
@@ -507,29 +512,29 @@ List<_NotoFont> _notoFonts = <_NotoFont>[
507512 CodeunitRange (43056 , 43065 ),
508513 CodeunitRange (43232 , 43259 ),
509514 ]),
510- _NotoFont ('Noto Sans Kannada UI' , < CodeunitRange > [
515+ NotoFont ('Noto Sans Kannada UI' , < CodeunitRange > [
511516 CodeunitRange (2404 , 2405 ),
512517 CodeunitRange (3202 , 3314 ),
513518 CodeunitRange (8204 , 8205 ),
514519 CodeunitRange (8377 , 8377 ),
515520 CodeunitRange (9676 , 9676 ),
516521 ]),
517- _NotoFont ('Noto Sans Khmer UI' , < CodeunitRange > [
522+ NotoFont ('Noto Sans Khmer UI' , < CodeunitRange > [
518523 CodeunitRange (6016 , 6143 ),
519524 CodeunitRange (8204 , 8204 ),
520525 CodeunitRange (9676 , 9676 ),
521526 ]),
522- _NotoFont ('Noto Sans KR' , < CodeunitRange > [
527+ NotoFont ('Noto Sans KR' , < CodeunitRange > [
523528 CodeunitRange (12593 , 12686 ),
524529 CodeunitRange (12800 , 12828 ),
525530 CodeunitRange (12896 , 12923 ),
526531 CodeunitRange (44032 , 55215 ),
527532 ]),
528- _NotoFont ('Noto Sans Lao UI' , < CodeunitRange > [
533+ NotoFont ('Noto Sans Lao UI' , < CodeunitRange > [
529534 CodeunitRange (3713 , 3807 ),
530535 CodeunitRange (9676 , 9676 ),
531536 ]),
532- _NotoFont ('Noto Sans Malayalam UI' , < CodeunitRange > [
537+ NotoFont ('Noto Sans Malayalam UI' , < CodeunitRange > [
533538 CodeunitRange (775 , 775 ),
534539 CodeunitRange (803 , 803 ),
535540 CodeunitRange (2404 , 2405 ),
@@ -538,33 +543,33 @@ List<_NotoFont> _notoFonts = <_NotoFont>[
538543 CodeunitRange (8377 , 8377 ),
539544 CodeunitRange (9676 , 9676 ),
540545 ]),
541- _NotoFont ('Noto Sans Sinhala' , < CodeunitRange > [
546+ NotoFont ('Noto Sans Sinhala' , < CodeunitRange > [
542547 CodeunitRange (2404 , 2405 ),
543548 CodeunitRange (3458 , 3572 ),
544549 CodeunitRange (8204 , 8205 ),
545550 CodeunitRange (9676 , 9676 ),
546551 ]),
547- _NotoFont ('Noto Sans Tamil UI' , < CodeunitRange > [
552+ NotoFont ('Noto Sans Tamil UI' , < CodeunitRange > [
548553 CodeunitRange (2404 , 2405 ),
549554 CodeunitRange (2946 , 3066 ),
550555 CodeunitRange (8204 , 8205 ),
551556 CodeunitRange (8377 , 8377 ),
552557 CodeunitRange (9676 , 9676 ),
553558 ]),
554- _NotoFont ('Noto Sans Telugu UI' , < CodeunitRange > [
559+ NotoFont ('Noto Sans Telugu UI' , < CodeunitRange > [
555560 CodeunitRange (2385 , 2386 ),
556561 CodeunitRange (2404 , 2405 ),
557562 CodeunitRange (3072 , 3199 ),
558563 CodeunitRange (7386 , 7386 ),
559564 CodeunitRange (8204 , 8205 ),
560565 CodeunitRange (9676 , 9676 ),
561566 ]),
562- _NotoFont ('Noto Sans Thai UI' , < CodeunitRange > [
567+ NotoFont ('Noto Sans Thai UI' , < CodeunitRange > [
563568 CodeunitRange (3585 , 3675 ),
564569 CodeunitRange (8204 , 8205 ),
565570 CodeunitRange (9676 , 9676 ),
566571 ]),
567- _NotoFont ('Noto Sans' , < CodeunitRange > [
572+ NotoFont ('Noto Sans' , < CodeunitRange > [
568573 CodeunitRange (0 , 255 ),
569574 CodeunitRange (305 , 305 ),
570575 CodeunitRange (338 , 339 ),
@@ -639,7 +644,7 @@ class FallbackFontDownloadQueue {
639644 downloads.add (Future <void >(() async {
640645 ByteBuffer buffer;
641646 try {
642- buffer = await downloader.downloadAsBytes (subset.url);
647+ buffer = await downloader.downloadAsBytes (subset.url, debugDescription : subset.family );
643648 } catch (e) {
644649 html.window.console
645650 .warn ('Failed to load font ${subset .family } at ${subset .url }' );
@@ -695,7 +700,7 @@ class NotoDownloader {
695700 /// Downloads the [url] and returns it as a [ByteBuffer] .
696701 ///
697702 /// Override this for testing.
698- Future <ByteBuffer > downloadAsBytes (String url) {
703+ Future <ByteBuffer > downloadAsBytes (String url, { String ? debugDescription} ) {
699704 if (assertionsEnabled) {
700705 _debugActiveDownloadCount += 1 ;
701706 }
@@ -714,7 +719,7 @@ class NotoDownloader {
714719 /// Downloads the [url] and returns is as a [String] .
715720 ///
716721 /// Override this for testing.
717- Future <String > downloadAsString (String url) {
722+ Future <String > downloadAsString (String url, { String ? debugDescription} ) {
718723 if (assertionsEnabled) {
719724 _debugActiveDownloadCount += 1 ;
720725 }
@@ -731,6 +736,12 @@ class NotoDownloader {
731736}
732737
733738/// The Noto font interval tree.
734- IntervalTree <_NotoFont >? _notoTree;
739+ IntervalTree <NotoFont >? _notoTree;
740+
741+ /// Returns the tree of Noto fonts for tests.
742+ IntervalTree <NotoFont > get debugNotoTree {
743+ _ensureNotoFontTreeCreated ();
744+ return _notoTree! ;
745+ }
735746
736747FallbackFontDownloadQueue notoDownloadQueue = FallbackFontDownloadQueue ();
0 commit comments