import 'dart:ui' as ui; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:halkyon_ui/halkyon_ui.dart'; import 'package:material_ui/material_ui.dart'; /// How many pixels [text] inks in [family] at [weight]: heavier strokes ink /// more. Future ink(String text, String family, FontWeight weight) async { final painter = TextPainter( text: TextSpan( text: text, style: TextStyle( fontFamily: family, fontSize: 40, fontWeight: weight, color: const Color(0xFF000000), ), ), textDirection: TextDirection.ltr, )..layout(); final recorder = ui.PictureRecorder(); painter.paint(Canvas(recorder), Offset.zero); final image = await recorder.endRecording().toImage( painter.width.ceil(), painter.height.ceil(), ); final pixels = (await image.toByteData())!; var inked = 0; for (var alpha = 3; alpha < pixels.lengthInBytes; alpha += 4) { if (pixels.getUint8(alpha) > 128) { inked++; } } return inked; } void main() { TestWidgetsFlutterBinding.ensureInitialized(); test("the font is the package's own, as an app finds a package's font", () { expect(appFontFamily, 'packages/halkyon_ui/Noto Sans'); }); test("the theme sets text in Noto Sans, with the apps' CJK fonts for what " 'it lacks, named as an app declares them', () { for (final brightness in Brightness.values) { final style = appTheme(brightness).textTheme.bodyLarge!; expect(style.fontFamily, appFontFamily); expect(style.fontFamilyFallback, [ 'Noto Sans JP', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans KR', ]); } }); test("a language's own CJK font comes first, so shared Han characters " 'take its shapes', () { expect(appFontFallbackFor(null).first, 'Noto Sans JP'); expect(appFontFallbackFor('en'), appFontFallback); expect(appFontFallbackFor('ja').first, 'Noto Sans JP'); expect(appFontFallbackFor('zh-Hans').first, 'Noto Sans SC'); expect(appFontFallbackFor('zh').first, 'Noto Sans SC'); expect(appFontFallbackFor('zh-Hant').first, 'Noto Sans TC'); expect(appFontFallbackFor('zh-TW').first, 'Noto Sans TC'); expect(appFontFallbackFor('ko').first, 'Noto Sans KR'); expect(hasOwnFont('ko'), isTrue); expect(hasOwnFont('de'), isFalse); // Every font stays, once. expect(appFontFallbackFor('ko').toSet(), appFontFallback.toSet()); expect(appFontFallbackFor('ko'), hasLength(4)); }); test('Noto Sans draws every weight from its one file', () async { // In this package's own tests it is the root project, whose assets have // no `packages/` prefix; an app's test of the name is in example/. final loader = FontLoader(appFontFamily) ..addFont(rootBundle.load('assets/fonts/NotoSans-Variable.ttf')); await loader.load(); const text = 'Ἀθῆναι Halkyon'; final regular = await ink(text, appFontFamily, FontWeight.w400); final bold = await ink(text, appFontFamily, FontWeight.w700); expect(bold, greaterThan(regular * 1.2)); }); }