Add new test font (#39809)
Add new test font
diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files
index c22d001..72f2fb7 100644
--- a/ci/licenses_golden/excluded_files
+++ b/ci/licenses_golden/excluded_files
@@ -408,6 +408,7 @@
../../../flutter/third_party/web_locale_keymap/README.md
../../../flutter/third_party/web_locale_keymap/pubspec.yaml
../../../flutter/third_party/web_locale_keymap/test
+../../../flutter/third_party/web_test_fonts/pubspec.yaml
../../../flutter/third_party/web_unicode/README.md
../../../flutter/third_party/web_unicode/pubspec.yaml
../../../flutter/tools
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index c7359b0..10d1b02 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -680,6 +680,7 @@
LIBRARY: spring_animation
LIBRARY: tonic
LIBRARY: txt
+LIBRARY: web_test_fonts
LIBRARY: web_unicode
ORIGIN: ../../../flutter/LICENSE
ORIGIN: ../../../flutter/assets/asset_manager.cc + ../../../flutter/LICENSE
@@ -3166,6 +3167,8 @@
ORIGIN: ../../../flutter/third_party/txt/src/txt/platform_linux.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/third_party/txt/src/txt/platform_mac.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/third_party/txt/src/txt/platform_windows.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/third_party/web_test_fonts/lib/web_test_fonts.dart + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/third_party/web_test_fonts/lib/web_test_fonts/web_test_fonts.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/third_party/web_unicode/lib/web_unicode.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/third_party/web_unicode/tool/unicode_sync_script.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/vulkan/procs/vulkan_handle.cc + ../../../flutter/LICENSE
@@ -5712,6 +5715,8 @@
FILE: ../../../flutter/third_party/txt/src/txt/platform_linux.cc
FILE: ../../../flutter/third_party/txt/src/txt/platform_mac.mm
FILE: ../../../flutter/third_party/txt/src/txt/platform_windows.cc
+FILE: ../../../flutter/third_party/web_test_fonts/lib/web_test_fonts.dart
+FILE: ../../../flutter/third_party/web_test_fonts/lib/web_test_fonts/web_test_fonts.dart
FILE: ../../../flutter/third_party/web_unicode/lib/web_unicode.dart
FILE: ../../../flutter/third_party/web_unicode/tool/unicode_sync_script.dart
FILE: ../../../flutter/vulkan/procs/vulkan_handle.cc
diff --git a/lib/ui/text/font_collection.cc b/lib/ui/text/font_collection.cc
index afc39b0..5a4afd3 100644
--- a/lib/ui/text/font_collection.cc
+++ b/lib/ui/text/font_collection.cc
@@ -121,19 +121,16 @@
}
void FontCollection::RegisterTestFonts() {
- std::vector<sk_sp<SkTypeface>> test_typefaces;
- std::vector<std::unique_ptr<SkStreamAsset>> font_data = GetTestFontData();
- for (auto& font : font_data) {
- test_typefaces.push_back(SkTypeface::MakeFromStream(std::move(font)));
- }
-
+ std::vector<sk_sp<SkTypeface>> test_typefaces = GetTestFontData();
std::unique_ptr<txt::TypefaceFontAssetProvider> font_provider =
std::make_unique<txt::TypefaceFontAssetProvider>();
size_t index = 0;
std::vector<std::string> names = GetTestFontFamilyNames();
for (sk_sp<SkTypeface> typeface : test_typefaces) {
- font_provider->RegisterTypeface(std::move(typeface), names[index]);
+ if (typeface) {
+ font_provider->RegisterTypeface(std::move(typeface), names[index]);
+ }
index++;
}
diff --git a/lib/web_ui/lib/src/engine/assets.dart b/lib/web_ui/lib/src/engine/assets.dart
index 0b39168..3daa73c 100644
--- a/lib/web_ui/lib/src/engine/assets.dart
+++ b/lib/web_ui/lib/src/engine/assets.dart
@@ -12,8 +12,15 @@
const String ahemFontUrl = '/assets/fonts/ahem.ttf';
const String robotoFontFamily = 'Roboto';
const String robotoTestFontUrl = '/assets/fonts/Roboto-Regular.ttf';
-const String robotoVariableFontFamily = 'RobotoVariable';
-const String robotoVariableTestFontUrl = '/assets/fonts/RobotoSlab-VariableFont_wght.ttf';
+
+/// The list of test fonts, in the form of font family name - font file url pairs.
+/// This list does not include embedded test fonts, which need to be loaded and
+/// registered separately in [FontCollection.debugDownloadTestFonts].
+const Map<String, String> testFontUrls = <String, String>{
+ ahemFontFamily: ahemFontUrl,
+ robotoFontFamily: robotoTestFontUrl,
+ 'RobotoVariable': '/assets/fonts/RobotoSlab-VariableFont_wght.ttf',
+};
/// This class downloads assets over the network.
///
diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart
index 660f8a1..84475d4 100644
--- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart
+++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart
@@ -6,6 +6,8 @@
import 'dart:convert';
import 'dart:typed_data';
+import 'package:web_test_fonts/web_test_fonts.dart';
+
import '../assets.dart';
import '../dom.dart';
import '../fonts.dart';
@@ -176,17 +178,17 @@
@override
Future<void> debugDownloadTestFonts() async {
final List<Future<UnregisteredFont?>> pendingFonts = <Future<UnregisteredFont?>>[];
- if (!_isFontFamilyDownloaded(ahemFontFamily)) {
- _downloadFont(pendingFonts, ahemFontUrl, ahemFontFamily);
+ for (final MapEntry<String, String> fontEntry in testFontUrls.entries) {
+ if (!_isFontFamilyDownloaded(fontEntry.key)) {
+ _downloadFont(pendingFonts, fontEntry.value, fontEntry.key);
+ }
}
- if (!_isFontFamilyDownloaded(robotoFontFamily)) {
- _downloadFont(pendingFonts, robotoTestFontUrl, robotoFontFamily);
- }
- if (!_isFontFamilyDownloaded(robotoVariableFontFamily)) {
- _downloadFont(pendingFonts, robotoVariableTestFontUrl, robotoVariableFontFamily);
- }
-
final List<UnregisteredFont?> completedPendingFonts = await Future.wait(pendingFonts);
+ completedPendingFonts.add(UnregisteredFont(
+ EmbeddedTestFont.flutterTest.data.buffer,
+ '<embedded>',
+ EmbeddedTestFont.flutterTest.fontFamily,
+ ));
_unregisteredFonts.addAll(completedPendingFonts.whereType<UnregisteredFont>());
// Ahem must be added to font fallbacks list regardless of where it was
diff --git a/lib/web_ui/lib/src/engine/canvaskit/text.dart b/lib/web_ui/lib/src/engine/canvaskit/text.dart
index ae1d233..b0dcf96 100644
--- a/lib/web_ui/lib/src/engine/canvaskit/text.dart
+++ b/lib/web_ui/lib/src/engine/canvaskit/text.dart
@@ -16,6 +16,13 @@
import 'text_fragmenter.dart';
import 'util.dart';
+final List<String> _testFonts = <String>['Ahem', 'FlutterTest'];
+String? _effectiveFontFamily(String? fontFamily) {
+ return ui.debugEmulateFlutterTesterEnvironment && !_testFonts.contains(fontFamily)
+ ? _testFonts.first
+ : fontFamily;
+}
+
@immutable
class CkParagraphStyle implements ui.ParagraphStyle {
CkParagraphStyle({
@@ -35,7 +42,7 @@
textAlign,
textDirection,
maxLines,
- ui.debugEmulateFlutterTesterEnvironment ? 'Ahem' : fontFamily,
+ _effectiveFontFamily(fontFamily),
fontSize,
height,
textHeightBehavior,
@@ -45,7 +52,7 @@
ellipsis,
locale,
),
- _fontFamily = ui.debugEmulateFlutterTesterEnvironment ? 'Ahem' : fontFamily,
+ _fontFamily = _effectiveFontFamily(fontFamily),
_fontSize = fontSize,
_height = height,
_leadingDistribution = textHeightBehavior?.leadingDistribution,
@@ -231,7 +238,7 @@
fontWeight,
fontStyle,
textBaseline,
- ui.debugEmulateFlutterTesterEnvironment ? 'Ahem' : fontFamily,
+ _effectiveFontFamily(fontFamily),
ui.debugEmulateFlutterTesterEnvironment ? null : fontFamilyFallback,
fontSize,
letterSpacing,
@@ -483,7 +490,7 @@
ui.FontWeight? fontWeight,
ui.FontStyle? fontStyle,
bool? forceStrutHeight,
- }) : _fontFamily = ui.debugEmulateFlutterTesterEnvironment ? 'Ahem' : fontFamily,
+ }) : _fontFamily = _effectiveFontFamily(fontFamily),
_fontFamilyFallback = ui.debugEmulateFlutterTesterEnvironment ? null : fontFamilyFallback,
_fontSize = fontSize,
_height = height,
diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart
index a4abd96..7c863d5 100644
--- a/lib/web_ui/lib/src/engine/text/font_collection.dart
+++ b/lib/web_ui/lib/src/engine/text/font_collection.dart
@@ -7,6 +7,7 @@
import 'dart:typed_data';
import 'package:ui/src/engine/fonts.dart';
+import 'package:web_test_fonts/web_test_fonts.dart';
import '../assets.dart';
import '../dom.dart';
@@ -74,14 +75,15 @@
/// Downloads fonts that are used by tests.
@override
Future<void> debugDownloadTestFonts() async {
- _testFontManager = FontManager();
- _testFontManager!.downloadAsset(
- ahemFontFamily, 'url($ahemFontUrl)', const <String, String>{});
- _testFontManager!.downloadAsset(robotoFontFamily,
- 'url($robotoTestFontUrl)', const <String, String>{});
- _testFontManager!.downloadAsset(robotoVariableFontFamily,
- 'url($robotoVariableTestFontUrl)', const <String, String>{});
- await _testFontManager!.downloadAllFonts();
+ final FontManager fontManager = _testFontManager = FontManager();
+ for (final MapEntry<String, String> fontEntry in testFontUrls.entries) {
+ fontManager.downloadAsset(fontEntry.key, 'url(${fontEntry.value})', const <String, String>{});
+ }
+ fontManager._downloadedFonts.add(createDomFontFace(
+ EmbeddedTestFont.flutterTest.fontFamily,
+ EmbeddedTestFont.flutterTest.data,
+ ));
+ await fontManager.downloadAllFonts();
}
@override
diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart
index 165e40e..0ac7735 100644
--- a/lib/web_ui/lib/src/engine/text/paragraph.dart
+++ b/lib/web_ui/lib/src/engine/text/paragraph.dart
@@ -464,18 +464,14 @@
final ui.Paint? foreground;
final List<ui.Shadow>? shadows;
+ static final List<String> _testFonts = <String>['Ahem', 'FlutterTest'];
String get effectiveFontFamily {
- if (assertionsEnabled) {
- // In the flutter tester environment, we use a predictable-size font
- // "Ahem". This makes widget tests predictable and less flaky.
- if (ui.debugEmulateFlutterTesterEnvironment) {
- return 'Ahem';
- }
- }
- if (fontFamily.isEmpty) {
- return FlutterViewEmbedder.defaultFontFamily;
- }
- return fontFamily;
+ final String fontFamily = this.fontFamily.isEmpty ? FlutterViewEmbedder.defaultFontFamily : this.fontFamily;
+ // In the flutter tester environment, we use predictable-size test fonts.
+ // This makes widget tests predictable and less flaky.
+ return assertionsEnabled && ui.debugEmulateFlutterTesterEnvironment && !_testFonts.contains(fontFamily)
+ ? _testFonts.first
+ : fontFamily;
}
String? _cssFontString;
@@ -815,7 +811,7 @@
style.fontStyle == ui.FontStyle.normal ? 'normal' : 'italic';
}
// For test environment use effectiveFontFamily since we need to
- // consistently use Ahem font.
+ // consistently use the correct test font.
if (ui.debugEmulateFlutterTesterEnvironment) {
cssStyle.fontFamily = canonicalizeFontFamily(style.effectiveFontFamily)!;
} else {
diff --git a/lib/web_ui/pubspec.yaml b/lib/web_ui/pubspec.yaml
index c658f6c..f35dafa 100644
--- a/lib/web_ui/pubspec.yaml
+++ b/lib/web_ui/pubspec.yaml
@@ -14,6 +14,9 @@
web_unicode:
path: ../../third_party/web_unicode
+ web_test_fonts:
+ path: ../../third_party/web_test_fonts
+
dev_dependencies:
analyzer: 5.2.0
archive: 3.1.2
diff --git a/lib/web_ui/test/canvaskit/text_test.dart b/lib/web_ui/test/canvaskit/text_test.dart
index 87efad2..e46b851 100644
--- a/lib/web_ui/test/canvaskit/text_test.dart
+++ b/lib/web_ui/test/canvaskit/text_test.dart
@@ -92,6 +92,37 @@
expect(await matchImage(tabImage, spaceImage), isTrue);
expect(await matchImage(tabImage, tofuImage), isFalse);
});
+
+ group('test fonts in flutterTester environment', () {
+ final bool resetValue = ui.debugEmulateFlutterTesterEnvironment;
+ ui.debugEmulateFlutterTesterEnvironment = true;
+ tearDownAll(() => ui.debugEmulateFlutterTesterEnvironment = resetValue);
+ const List<String> testFonts = <String>['Ahem', 'FlutterTest'];
+
+ test('The default test font is used when a non-test fontFamily is specified', () {
+ final String defaultTestFontFamily = testFonts.first;
+
+ expect(CkTextStyle(fontFamily: 'BogusFontFamily').fontFamily, defaultTestFontFamily);
+ expect(CkParagraphStyle(fontFamily: 'BogusFontFamily').getTextStyle().fontFamily, defaultTestFontFamily);
+ expect(CkStrutStyle(fontFamily: 'BogusFontFamily'), CkStrutStyle(fontFamily: defaultTestFontFamily));
+ });
+
+ test('The default test font is used when fontFamily is unspecified', () {
+ final String defaultTestFontFamily = testFonts.first;
+
+ expect(CkTextStyle().fontFamily, defaultTestFontFamily);
+ expect(CkParagraphStyle().getTextStyle().fontFamily, defaultTestFontFamily);
+ expect(CkStrutStyle(), CkStrutStyle(fontFamily: defaultTestFontFamily));
+ });
+
+ test('Can specify test fontFamily to use', () {
+ for (final String testFont in testFonts) {
+ expect(CkTextStyle(fontFamily: testFont).fontFamily, testFont);
+ expect(CkParagraphStyle(fontFamily: testFont).getTextStyle().fontFamily, testFont);
+ }
+ });
+ });
// TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
}, skip: isSafari || isFirefox);
+
}
diff --git a/lib/web_ui/test/text_test.dart b/lib/web_ui/test/text_test.dart
index f24fc22..5dc319a 100644
--- a/lib/web_ui/test/text_test.dart
+++ b/lib/web_ui/test/text_test.dart
@@ -358,4 +358,24 @@
expect(FontWeight.w800.value, 800);
expect(FontWeight.w900.value, 900);
});
+
+ group('test fonts in flutterTester environment', () {
+ final bool resetValue = debugEmulateFlutterTesterEnvironment;
+ debugEmulateFlutterTesterEnvironment = true;
+ tearDownAll(() => debugEmulateFlutterTesterEnvironment = resetValue);
+ const List<String> testFonts = <String>['Ahem', 'FlutterTest'];
+
+ test('The default test font is used when a non-test fontFamily is specified, or fontFamily is not specified', () {
+ final String defaultTestFontFamily = testFonts.first;
+
+ expect(EngineTextStyle.only().effectiveFontFamily, defaultTestFontFamily);
+ expect(EngineTextStyle.only(fontFamily: 'BogusFontFamily').effectiveFontFamily, defaultTestFontFamily);
+ });
+
+ test('Can specify test fontFamily to use', () {
+ for (final String testFont in testFonts) {
+ expect(EngineTextStyle.only(fontFamily: testFont).effectiveFontFamily, testFont);
+ }
+ });
+ });
}
diff --git a/runtime/test_font_data.cc b/runtime/test_font_data.cc
index ce21eef..9f86698 100644
--- a/runtime/test_font_data.cc
+++ b/runtime/test_font_data.cc
@@ -1205,6 +1205,8 @@
0x69, 0x69, 0x33, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x08, 0x00, 0x02, 0x00, 0x10, 0x00, 0x01, 0xff, 0xff, 0x00, 0x03};
+static const unsigned int kAhemFontLength = 13884;
+
// "Cough" font is Flutter's custom test font and may expand to cover
// font-dependent testing specific features that "Ahem" cannot cover.
//
@@ -1357,41 +1359,284 @@
0xd5, 0xed, 0x45, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xe6, 0x56, 0x09,
0x00, 0x00, 0x00, 0x00, 0xd9, 0xe6, 0x7e, 0x49};
-static const unsigned int kAhemFontLength = 13884;
static const unsigned int kCoughFontLength = 1576;
-#else // EMBED_TEST_FONT_DATA
+static const unsigned char kFlutterTestFont[] = {
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x80, 0x00, 0x03, 0x00, 0x60,
+ 0x42, 0x41, 0x53, 0x45, 0x8a, 0x4b, 0x87, 0x01, 0x00, 0x00, 0x0b, 0x24,
+ 0x00, 0x00, 0x00, 0x82, 0x47, 0x44, 0x45, 0x46, 0x00, 0x29, 0x00, 0x14,
+ 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x4f, 0x53, 0x2f, 0x32,
+ 0x13, 0xfd, 0x90, 0xf2, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60,
+ 0x63, 0x6d, 0x61, 0x70, 0xec, 0x11, 0x06, 0x0f, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x05, 0x04, 0x63, 0x76, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x00, 0x02, 0x67, 0x6c, 0x79, 0x66,
+ 0x09, 0x85, 0x89, 0xf8, 0x00, 0x00, 0x07, 0x3c, 0x00, 0x00, 0x00, 0xd8,
+ 0x68, 0x65, 0x61, 0x64, 0x81, 0x1b, 0xef, 0xfd, 0x00, 0x00, 0x00, 0xec,
+ 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61, 0x07, 0x02, 0x03, 0x0f,
+ 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
+ 0x1b, 0x86, 0x00, 0x80, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x38,
+ 0x6c, 0x6f, 0x63, 0x61, 0x02, 0x7e, 0x02, 0x50, 0x00, 0x00, 0x07, 0x1c,
+ 0x00, 0x00, 0x00, 0x1e, 0x6d, 0x61, 0x78, 0x70, 0x00, 0x52, 0x00, 0x2d,
+ 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
+ 0x1a, 0xef, 0x7a, 0x5b, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x02, 0x25,
+ 0x70, 0x6f, 0x73, 0x74, 0x89, 0x84, 0x28, 0x37, 0x00, 0x00, 0x0a, 0x3c,
+ 0x00, 0x00, 0x00, 0xc7, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x48, 0x68, 0x25,
+ 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xab, 0xb4, 0x91, 0x15, 0x5f, 0x0f, 0x3c, 0xf5,
+ 0x00, 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xf4, 0x56, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x8e, 0xf4, 0x56, 0x80, 0x00, 0x00, 0xff, 0x00,
+ 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x02, 0x05, 0x01, 0x90, 0x00, 0x05, 0x00, 0x00, 0x02, 0x99,
+ 0x02, 0xcc, 0x00, 0x00, 0x00, 0x8f, 0x02, 0x99, 0x02, 0xcc, 0x00, 0x00,
+ 0x01, 0xeb, 0x00, 0x33, 0x01, 0x09, 0x00, 0x00, 0x02, 0x00, 0x05, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0xfe, 0xff, 0x03, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01,
+ 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00,
+ 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0xfe, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x04, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x64, 0x00, 0x40, 0x00, 0x05,
+ 0x00, 0x24, 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x01, 0x53, 0x01, 0x78,
+ 0x01, 0x92, 0x02, 0xc9, 0x02, 0xdd, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xc0,
+ 0x20, 0x0a, 0x20, 0x26, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x44, 0x21, 0x26,
+ 0x22, 0x06, 0x22, 0x12, 0x22, 0x1e, 0x22, 0x2b, 0x22, 0x48, 0x22, 0x65,
+ 0x22, 0xf2, 0x25, 0xca, 0x30, 0x07, 0x4e, 0x03, 0x4e, 0x09, 0x4e, 0x2d,
+ 0x4e, 0x5d, 0x4e, 0x8c, 0x4e, 0x94, 0x51, 0x6d, 0x53, 0x41, 0x54, 0x26,
+ 0x56, 0xdb, 0x57, 0x1f, 0x65, 0x87, 0x66, 0x2f, 0x67, 0x2c, 0x6b, 0x63,
+ 0x6c, 0x34, 0x6d, 0x4b, 0x70, 0x6b, 0x78, 0x6e, 0x8b, 0xd5, 0x91, 0xd1,
+ 0xf0, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa1,
+ 0x01, 0x31, 0x01, 0x52, 0x01, 0x78, 0x01, 0x92, 0x02, 0xc6, 0x02, 0xd8,
+ 0x03, 0x94, 0x03, 0xa5, 0x03, 0xbc, 0x20, 0x02, 0x20, 0x13, 0x20, 0x30,
+ 0x20, 0x39, 0x20, 0x44, 0x21, 0x22, 0x22, 0x02, 0x22, 0x0f, 0x22, 0x19,
+ 0x22, 0x2b, 0x22, 0x48, 0x22, 0x60, 0x22, 0xf2, 0x25, 0xca, 0x30, 0x07,
+ 0x4e, 0x00, 0x4e, 0x09, 0x4e, 0x2d, 0x4e, 0x5d, 0x4e, 0x8c, 0x4e, 0x94,
+ 0x51, 0x6b, 0x53, 0x41, 0x54, 0x26, 0x56, 0xd7, 0x57, 0x1f, 0x65, 0x87,
+ 0x66, 0x2f, 0x67, 0x28, 0x6b, 0x63, 0x6c, 0x34, 0x6d, 0x4b, 0x70, 0x6b,
+ 0x78, 0x6e, 0x8b, 0xd5, 0x91, 0xd1, 0xf0, 0x00, 0xfe, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xd2, 0x00, 0x00, 0xfe, 0x8b, 0xfe, 0x71,
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xdf, 0xd3, 0x00, 0x00, 0xdf, 0xbf, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xdd, 0xd8, 0xdd, 0xbb, 0x00, 0x00, 0xdd, 0x11,
+ 0xda, 0x39, 0xcf, 0xfc, 0x00, 0x00, 0xb1, 0xfa, 0xb1, 0xd6, 0xb1, 0xa6,
+ 0xb1, 0x77, 0xb1, 0x6f, 0x00, 0x00, 0xac, 0xc2, 0xab, 0xdd, 0x00, 0x00,
+ 0xa8, 0xe4, 0x9a, 0x7c, 0x99, 0xd4, 0x00, 0x00, 0x94, 0xa0, 0x93, 0xcf,
+ 0x92, 0xb8, 0x8f, 0x98, 0x87, 0x95, 0x74, 0x2e, 0x6e, 0x32, 0x00, 0x00,
+ 0x01, 0x0e, 0x00, 0x01, 0x00, 0x64, 0x01, 0x20, 0x00, 0x00, 0x01, 0xda,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xd8, 0x01, 0xde, 0x00, 0x00, 0x01, 0xe6,
+ 0x01, 0xee, 0x01, 0xf6, 0x02, 0x06, 0x00, 0x00, 0x02, 0x2a, 0x00, 0x00,
+ 0x02, 0x2a, 0x02, 0x32, 0x02, 0x3a, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x48,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00,
+ 0x03, 0x03, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x18, 0xb8, 0x00, 0x00,
+ 0x4c, 0xb8, 0x00, 0xc0, 0x63, 0xb8, 0x00, 0x04, 0x62, 0x20, 0x67, 0x61,
+ 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26,
+ 0x00, 0x26, 0x00, 0x26, 0x00, 0x3c, 0x00, 0x54, 0x00, 0x6c, 0x00, 0x6c,
+ 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c,
+ 0x00, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x03, 0x80,
+ 0x03, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x22, 0x00, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16,
+ 0xb0, 0x00, 0x2f, 0xb0, 0x01, 0x2f, 0xb0, 0x02, 0x2f, 0xb0, 0x03, 0x2f,
+ 0xb0, 0x04, 0x2f, 0xb0, 0x07, 0x2f, 0x25, 0x21, 0x11, 0x21, 0x03, 0x11,
+ 0x21, 0x11, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x00, 0x80, 0x03, 0x00, 0x80,
+ 0x02, 0x00, 0xfd, 0x80, 0x03, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x11, 0x00, 0xb3,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15,
+ 0x36, 0x16, 0x00, 0x19, 0x01, 0x21, 0x11, 0x04, 0x00, 0xff, 0x00, 0x04,
+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00,
+ 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16, 0xb0, 0x01,
+ 0x2f, 0xb0, 0x02, 0x2f, 0x19, 0x01, 0x21, 0x11, 0x04, 0x00, 0xff, 0x00,
+ 0x01, 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x03, 0x00, 0x00, 0x03, 0x00, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00,
+ 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16, 0xb0, 0x00,
+ 0x2f, 0xb0, 0x03, 0x2f, 0x31, 0x11, 0x21, 0x11, 0x04, 0x00, 0x03, 0x00,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xae, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x3c, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x6a, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x82, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x00, 0xd8, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0b, 0x01, 0x17, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0f, 0x01, 0x43, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0b, 0x01, 0x6b, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x5a, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x72, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x8a, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x16, 0x00, 0xff, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x1e, 0x01, 0x23, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x16, 0x01, 0x53, 0x00, 0x43,
+ 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67,
+ 0x00, 0x68, 0x00, 0x74, 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29,
+ 0x00, 0x20, 0x00, 0x31, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x2c,
+ 0x00, 0x20, 0x00, 0x41, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x79,
+ 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x00, 0x43, 0x6f,
+ 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
+ 0x31, 0x39, 0x38, 0x30, 0x2c, 0x20, 0x41, 0x6e, 0x6f, 0x6e, 0x79, 0x6d,
+ 0x6f, 0x75, 0x73, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67,
+ 0x00, 0x4c, 0x00, 0x69, 0x00, 0x55, 0x00, 0x00, 0x4d, 0x69, 0x6e, 0x67,
+ 0x4c, 0x69, 0x55, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75,
+ 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, 0x52, 0x65, 0x67, 0x75,
+ 0x6c, 0x61, 0x72, 0x00, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74,
+ 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, 0x00, 0x20,
+ 0x00, 0x32, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20,
+ 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20,
+ 0x00, 0x3a, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x2d,
+ 0x00, 0x31, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x00, 0x46, 0x6f,
+ 0x6e, 0x74, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x20, 0x32, 0x2e, 0x30, 0x20,
+ 0x3a, 0x20, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73,
+ 0x74, 0x20, 0x3a, 0x20, 0x31, 0x2d, 0x31, 0x2d, 0x31, 0x39, 0x38, 0x30,
+ 0x00, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+ 0x00, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
+ 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00,
+ 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00,
+ 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x30, 0x30, 0x31, 0x2e, 0x30, 0x30, 0x30,
+ 0x00, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+ 0x00, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x7e, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x01, 0x03,
+ 0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09,
+ 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c, 0x06, 0x53, 0x71, 0x75, 0x61, 0x72,
+ 0x65, 0x0e, 0x41, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x46, 0x6c, 0x75,
+ 0x73, 0x68, 0x65, 0x64, 0x0f, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x74,
+ 0x20, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64, 0x0c, 0x46, 0x75, 0x6c,
+ 0x6c, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x32, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x33, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x34, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x36, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x35, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0c, 0x31, 0x2f,
+ 0x31, 0x30, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0c, 0x5a,
+ 0x65, 0x72, 0x6f, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x03, 0x68, 0x61,
+ 0x6e, 0x67, 0x69, 0x64, 0x65, 0x6f, 0x72, 0x6f, 0x6d, 0x6e, 0x00, 0x03,
+ 0x67, 0x72, 0x65, 0x6b, 0x00, 0x14, 0x68, 0x61, 0x6e, 0x69, 0x00, 0x30,
+ 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x01,
+ 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e,
+ 0x00, 0x12, 0x00, 0x01, 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03,
+ 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x01, 0x03, 0x00, 0x00, 0x01,
+ 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
-static const unsigned char kAhemFont[] = {};
-static const unsigned char kCoughFont[] = {};
-
-static const unsigned int kAhemFontLength = 0;
-static const unsigned int kCoughFontLength = 0;
+static const unsigned int kFlutterTestFontLength = 2984;
#endif // EMBED_TEST_FONT_DATA
namespace flutter {
-std::vector<std::unique_ptr<SkStreamAsset>> GetTestFontData() {
- std::vector<std::unique_ptr<SkStreamAsset>> data;
- if (kAhemFontLength == 0) {
- data.push_back(nullptr);
- } else {
- data.push_back(std::make_unique<SkMemoryStream>(kAhemFont, kAhemFontLength,
- false /* copy data */));
- }
-
- if (kCoughFontLength == 0) {
- data.push_back(nullptr);
- } else {
- data.push_back(std::make_unique<SkMemoryStream>(
- kCoughFont, kCoughFontLength, false /* copy data */));
- }
- return data;
+std::vector<sk_sp<SkTypeface>> GetTestFontData() {
+ std::vector<sk_sp<SkTypeface>> typefaces;
+#if EMBED_TEST_FONT_DATA
+ typefaces.push_back(SkTypeface::MakeFromStream(
+ SkMemoryStream::MakeDirect(kAhemFont, kAhemFontLength)));
+ typefaces.push_back(SkTypeface::MakeFromStream(
+ SkMemoryStream::MakeDirect(kCoughFont, kCoughFontLength)));
+ typefaces.push_back(SkTypeface::MakeFromStream(
+ SkMemoryStream::MakeDirect(kFlutterTestFont, kFlutterTestFontLength)));
+#endif // EMBED_TEST_FONT_DATA
+ return typefaces;
}
std::vector<std::string> GetTestFontFamilyNames() {
- std::vector<std::string> names = {"Ahem", "Cough"};
+#if EMBED_TEST_FONT_DATA
+ std::vector<std::string> names = {"Ahem", "Cough", "FlutterTest"};
+#else // EMBED_TEST_FONT_DATA
+ std::vector<std::string> names;
+#endif // EMBED_TEST_FONT_DATA
return names;
}
diff --git a/runtime/test_font_data.h b/runtime/test_font_data.h
index d1ba072..60df5aa 100644
--- a/runtime/test_font_data.h
+++ b/runtime/test_font_data.h
@@ -10,10 +10,11 @@
#include <vector>
#include "third_party/skia/include/core/SkStream.h"
+#include "third_party/skia/include/core/SkTypeface.h"
namespace flutter {
-std::vector<std::unique_ptr<SkStreamAsset>> GetTestFontData();
+std::vector<sk_sp<SkTypeface>> GetTestFontData();
std::vector<std::string> GetTestFontFamilyNames();
} // namespace flutter
diff --git a/testing/dart/paragraph_test.dart b/testing/dart/paragraph_test.dart
index b6f4898..8c8e865 100644
--- a/testing/dart/paragraph_test.dart
+++ b/testing/dart/paragraph_test.dart
@@ -10,7 +10,7 @@
// Ahem font uses a constant ideographic/alphabetic baseline ratio.
const double kAhemBaselineRatio = 1.25;
- test('predictably lays out a single-line paragraph', () {
+ test('predictably lays out a single-line paragraph - Ahem', () {
for (final double fontSize in <double>[10.0, 20.0, 30.0, 40.0]) {
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
fontFamily: 'Ahem',
@@ -34,6 +34,27 @@
}
});
+ test('predictably lays out a single-line paragraph - FlutterTest', () {
+ for (final double fontSize in <double>[10.0, 20.0, 30.0, 40.0]) {
+ final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
+ fontFamily: 'FlutterTest',
+ fontStyle: FontStyle.normal,
+ fontWeight: FontWeight.normal,
+ fontSize: fontSize,
+ ));
+ builder.addText('Test');
+ final Paragraph paragraph = builder.build();
+ paragraph.layout(const ParagraphConstraints(width: 400.0));
+
+ expect(paragraph.height, fontSize);
+ expect(paragraph.width, 400.0);
+ expect(paragraph.minIntrinsicWidth, fontSize * 4.0);
+ expect(paragraph.maxIntrinsicWidth, fontSize * 4.0);
+ expect(paragraph.alphabeticBaseline, fontSize * 0.75);
+ expect(paragraph.ideographicBaseline, fontSize);
+ }
+ });
+
test('predictably lays out a multi-line paragraph', () {
for (final double fontSize in <double>[10.0, 20.0, 30.0, 40.0]) {
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
diff --git a/third_party/web_test_fonts/lib/web_test_fonts.dart b/third_party/web_test_fonts/lib/web_test_fonts.dart
new file mode 100644
index 0000000..ae57f3b
--- /dev/null
+++ b/third_party/web_test_fonts/lib/web_test_fonts.dart
@@ -0,0 +1,7 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library web_test_fonts;
+
+export 'web_test_fonts/web_test_fonts.dart';
diff --git a/third_party/web_test_fonts/lib/web_test_fonts/web_test_fonts.dart b/third_party/web_test_fonts/lib/web_test_fonts/web_test_fonts.dart
new file mode 100644
index 0000000..a859b9c
--- /dev/null
+++ b/third_party/web_test_fonts/lib/web_test_fonts/web_test_fonts.dart
@@ -0,0 +1,269 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:typed_data';
+
+class EmbeddedTestFont {
+ const EmbeddedTestFont._({
+ required this.fontFamily,
+ required this.data,
+ });
+
+ static final EmbeddedTestFont flutterTest = EmbeddedTestFont._(fontFamily: 'FlutterTest', data: _flutterTestData);
+
+ final String fontFamily;
+ final Uint8List data;
+}
+
+final Uint8List _flutterTestData = Uint8List.fromList(<int>[
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x80, 0x00, 0x03, 0x00, 0x60,
+ 0x42, 0x41, 0x53, 0x45, 0x8a, 0x4b, 0x87, 0x01, 0x00, 0x00, 0x0b, 0x24,
+ 0x00, 0x00, 0x00, 0x82, 0x47, 0x44, 0x45, 0x46, 0x00, 0x29, 0x00, 0x14,
+ 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x4f, 0x53, 0x2f, 0x32,
+ 0x13, 0xfd, 0x90, 0xf2, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60,
+ 0x63, 0x6d, 0x61, 0x70, 0xec, 0x11, 0x06, 0x0f, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x05, 0x04, 0x63, 0x76, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x00, 0x02, 0x67, 0x6c, 0x79, 0x66,
+ 0x09, 0x85, 0x89, 0xf8, 0x00, 0x00, 0x07, 0x3c, 0x00, 0x00, 0x00, 0xd8,
+ 0x68, 0x65, 0x61, 0x64, 0x81, 0x1b, 0xef, 0xfd, 0x00, 0x00, 0x00, 0xec,
+ 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61, 0x07, 0x02, 0x03, 0x0f,
+ 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
+ 0x1b, 0x86, 0x00, 0x80, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x38,
+ 0x6c, 0x6f, 0x63, 0x61, 0x02, 0x7e, 0x02, 0x50, 0x00, 0x00, 0x07, 0x1c,
+ 0x00, 0x00, 0x00, 0x1e, 0x6d, 0x61, 0x78, 0x70, 0x00, 0x52, 0x00, 0x2d,
+ 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
+ 0x1a, 0xef, 0x7a, 0x5b, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x02, 0x25,
+ 0x70, 0x6f, 0x73, 0x74, 0x89, 0x84, 0x28, 0x37, 0x00, 0x00, 0x0a, 0x3c,
+ 0x00, 0x00, 0x00, 0xc7, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x48, 0x68, 0x25,
+ 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xab, 0xb4, 0x91, 0x15, 0x5f, 0x0f, 0x3c, 0xf5,
+ 0x00, 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xf4, 0x56, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x8e, 0xf4, 0x56, 0x80, 0x00, 0x00, 0xff, 0x00,
+ 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x02, 0x05, 0x01, 0x90, 0x00, 0x05, 0x00, 0x00, 0x02, 0x99,
+ 0x02, 0xcc, 0x00, 0x00, 0x00, 0x8f, 0x02, 0x99, 0x02, 0xcc, 0x00, 0x00,
+ 0x01, 0xeb, 0x00, 0x33, 0x01, 0x09, 0x00, 0x00, 0x02, 0x00, 0x05, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0xfe, 0xff, 0x03, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01,
+ 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00,
+ 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0xfe, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x04, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x64, 0x00, 0x40, 0x00, 0x05,
+ 0x00, 0x24, 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x01, 0x53, 0x01, 0x78,
+ 0x01, 0x92, 0x02, 0xc9, 0x02, 0xdd, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xc0,
+ 0x20, 0x0a, 0x20, 0x26, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x44, 0x21, 0x26,
+ 0x22, 0x06, 0x22, 0x12, 0x22, 0x1e, 0x22, 0x2b, 0x22, 0x48, 0x22, 0x65,
+ 0x22, 0xf2, 0x25, 0xca, 0x30, 0x07, 0x4e, 0x03, 0x4e, 0x09, 0x4e, 0x2d,
+ 0x4e, 0x5d, 0x4e, 0x8c, 0x4e, 0x94, 0x51, 0x6d, 0x53, 0x41, 0x54, 0x26,
+ 0x56, 0xdb, 0x57, 0x1f, 0x65, 0x87, 0x66, 0x2f, 0x67, 0x2c, 0x6b, 0x63,
+ 0x6c, 0x34, 0x6d, 0x4b, 0x70, 0x6b, 0x78, 0x6e, 0x8b, 0xd5, 0x91, 0xd1,
+ 0xf0, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa1,
+ 0x01, 0x31, 0x01, 0x52, 0x01, 0x78, 0x01, 0x92, 0x02, 0xc6, 0x02, 0xd8,
+ 0x03, 0x94, 0x03, 0xa5, 0x03, 0xbc, 0x20, 0x02, 0x20, 0x13, 0x20, 0x30,
+ 0x20, 0x39, 0x20, 0x44, 0x21, 0x22, 0x22, 0x02, 0x22, 0x0f, 0x22, 0x19,
+ 0x22, 0x2b, 0x22, 0x48, 0x22, 0x60, 0x22, 0xf2, 0x25, 0xca, 0x30, 0x07,
+ 0x4e, 0x00, 0x4e, 0x09, 0x4e, 0x2d, 0x4e, 0x5d, 0x4e, 0x8c, 0x4e, 0x94,
+ 0x51, 0x6b, 0x53, 0x41, 0x54, 0x26, 0x56, 0xd7, 0x57, 0x1f, 0x65, 0x87,
+ 0x66, 0x2f, 0x67, 0x28, 0x6b, 0x63, 0x6c, 0x34, 0x6d, 0x4b, 0x70, 0x6b,
+ 0x78, 0x6e, 0x8b, 0xd5, 0x91, 0xd1, 0xf0, 0x00, 0xfe, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xd2, 0x00, 0x00, 0xfe, 0x8b, 0xfe, 0x71,
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xdf, 0xd3, 0x00, 0x00, 0xdf, 0xbf, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xdd, 0xd8, 0xdd, 0xbb, 0x00, 0x00, 0xdd, 0x11,
+ 0xda, 0x39, 0xcf, 0xfc, 0x00, 0x00, 0xb1, 0xfa, 0xb1, 0xd6, 0xb1, 0xa6,
+ 0xb1, 0x77, 0xb1, 0x6f, 0x00, 0x00, 0xac, 0xc2, 0xab, 0xdd, 0x00, 0x00,
+ 0xa8, 0xe4, 0x9a, 0x7c, 0x99, 0xd4, 0x00, 0x00, 0x94, 0xa0, 0x93, 0xcf,
+ 0x92, 0xb8, 0x8f, 0x98, 0x87, 0x95, 0x74, 0x2e, 0x6e, 0x32, 0x00, 0x00,
+ 0x01, 0x0e, 0x00, 0x01, 0x00, 0x64, 0x01, 0x20, 0x00, 0x00, 0x01, 0xda,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xd8, 0x01, 0xde, 0x00, 0x00, 0x01, 0xe6,
+ 0x01, 0xee, 0x01, 0xf6, 0x02, 0x06, 0x00, 0x00, 0x02, 0x2a, 0x00, 0x00,
+ 0x02, 0x2a, 0x02, 0x32, 0x02, 0x3a, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x48,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+ 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00,
+ 0x03, 0x03, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x18, 0xb8, 0x00, 0x00,
+ 0x4c, 0xb8, 0x00, 0xc0, 0x63, 0xb8, 0x00, 0x04, 0x62, 0x20, 0x67, 0x61,
+ 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26,
+ 0x00, 0x26, 0x00, 0x26, 0x00, 0x3c, 0x00, 0x54, 0x00, 0x6c, 0x00, 0x6c,
+ 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c,
+ 0x00, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x03, 0x80,
+ 0x03, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x22, 0x00, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16,
+ 0xb0, 0x00, 0x2f, 0xb0, 0x01, 0x2f, 0xb0, 0x02, 0x2f, 0xb0, 0x03, 0x2f,
+ 0xb0, 0x04, 0x2f, 0xb0, 0x07, 0x2f, 0x25, 0x21, 0x11, 0x21, 0x03, 0x11,
+ 0x21, 0x11, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x00, 0x80, 0x03, 0x00, 0x80,
+ 0x02, 0x00, 0xfd, 0x80, 0x03, 0x00, 0xfd, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x11, 0x00, 0xb3,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15,
+ 0x36, 0x16, 0x00, 0x19, 0x01, 0x21, 0x11, 0x04, 0x00, 0xff, 0x00, 0x04,
+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00,
+ 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16, 0xb0, 0x01,
+ 0x2f, 0xb0, 0x02, 0x2f, 0x19, 0x01, 0x21, 0x11, 0x04, 0x00, 0xff, 0x00,
+ 0x01, 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x03, 0x00, 0x00, 0x03, 0x00, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00,
+ 0x16, 0xe0, 0x12, 0xb2, 0x01, 0x01, 0x01, 0x15, 0x36, 0x16, 0xb0, 0x00,
+ 0x2f, 0xb0, 0x03, 0x2f, 0x31, 0x11, 0x21, 0x11, 0x04, 0x00, 0x03, 0x00,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xae, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x3c, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x6a, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x82, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x00, 0xd8, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0b, 0x01, 0x17, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0f, 0x01, 0x43, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0b, 0x01, 0x6b, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x5a, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x72, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x8a, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x16, 0x00, 0xff, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x1e, 0x01, 0x23, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x16, 0x01, 0x53, 0x00, 0x43,
+ 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67,
+ 0x00, 0x68, 0x00, 0x74, 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29,
+ 0x00, 0x20, 0x00, 0x31, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x2c,
+ 0x00, 0x20, 0x00, 0x41, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x79,
+ 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x73, 0x00, 0x00, 0x43, 0x6f,
+ 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
+ 0x31, 0x39, 0x38, 0x30, 0x2c, 0x20, 0x41, 0x6e, 0x6f, 0x6e, 0x79, 0x6d,
+ 0x6f, 0x75, 0x73, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67,
+ 0x00, 0x4c, 0x00, 0x69, 0x00, 0x55, 0x00, 0x00, 0x4d, 0x69, 0x6e, 0x67,
+ 0x4c, 0x69, 0x55, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75,
+ 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, 0x52, 0x65, 0x67, 0x75,
+ 0x6c, 0x61, 0x72, 0x00, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74,
+ 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, 0x00, 0x20,
+ 0x00, 0x32, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20,
+ 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20,
+ 0x00, 0x3a, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x2d,
+ 0x00, 0x31, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x00, 0x46, 0x6f,
+ 0x6e, 0x74, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x20, 0x32, 0x2e, 0x30, 0x20,
+ 0x3a, 0x20, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73,
+ 0x74, 0x20, 0x3a, 0x20, 0x31, 0x2d, 0x31, 0x2d, 0x31, 0x39, 0x38, 0x30,
+ 0x00, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+ 0x00, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
+ 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00,
+ 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00,
+ 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x30, 0x30, 0x31, 0x2e, 0x30, 0x30, 0x30,
+ 0x00, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+ 0x00, 0x46, 0x6c, 0x75, 0x74, 0x74, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x7e, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x01, 0x03,
+ 0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09,
+ 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c, 0x06, 0x53, 0x71, 0x75, 0x61, 0x72,
+ 0x65, 0x0e, 0x41, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x46, 0x6c, 0x75,
+ 0x73, 0x68, 0x65, 0x64, 0x0f, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x74,
+ 0x20, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64, 0x0c, 0x46, 0x75, 0x6c,
+ 0x6c, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x32, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x33, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x34, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x36, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0b, 0x31, 0x2f,
+ 0x35, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0c, 0x31, 0x2f,
+ 0x31, 0x30, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x0c, 0x5a,
+ 0x65, 0x72, 0x6f, 0x20, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x03, 0x68, 0x61,
+ 0x6e, 0x67, 0x69, 0x64, 0x65, 0x6f, 0x72, 0x6f, 0x6d, 0x6e, 0x00, 0x03,
+ 0x67, 0x72, 0x65, 0x6b, 0x00, 0x14, 0x68, 0x61, 0x6e, 0x69, 0x00, 0x30,
+ 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x01,
+ 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e,
+ 0x00, 0x12, 0x00, 0x01, 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03,
+ 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x01, 0x03, 0x00, 0x00, 0x01,
+ 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ ]);
diff --git a/third_party/web_test_fonts/pubspec.yaml b/third_party/web_test_fonts/pubspec.yaml
new file mode 100644
index 0000000..427accd
--- /dev/null
+++ b/third_party/web_test_fonts/pubspec.yaml
@@ -0,0 +1,10 @@
+name: web_test_fonts
+
+publish_to: none
+
+environment:
+ sdk: ">=2.12.0-0 <3.0.0"
+
+dev_dependencies:
+ args: any
+ path: any
diff --git a/tools/gen_test_font.py b/tools/gen_test_font.py
new file mode 100755
index 0000000..2d5f0ee
--- /dev/null
+++ b/tools/gen_test_font.py
@@ -0,0 +1,329 @@
+#!/usr/bin/env python3
+#
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys, math
+from operator import itemgetter
+from itertools import groupby
+import unicodedata
+import fontforge
+
+NAME = "FlutterTest"
+# Turn off auto-hinting and enable manual hinting. FreeType skips auto-hinting
+# if the font's family name is in a hard-coded "tricky" font list.
+TRICKY_NAME = "MingLiU"
+EM = 1024
+DESCENT = -EM // 4
+ASCENT = EM + DESCENT
+# -143 and 20 are the underline location and width Ahem uses.
+UPOS = -143 * 1000 // EM
+UWIDTH = 20 * 1000 // EM
+
+### Font Metadata and Metrics
+
+font = fontforge.font()
+font.familyname = TRICKY_NAME
+font.fullname = NAME
+font.fontname = NAME
+
+# This sets the relevant fields in the os2 table and hhea table.
+font.ascent = ASCENT
+font.descent = -DESCENT
+font.upos = UPOS
+font.uwidth = UWIDTH
+font.hhea_linegap = 0
+font.os2_typolinegap = 0
+
+font.horizontalBaseline = (
+ ("hang", "ideo", "romn"),
+ (
+ ("latn", "romn", (ASCENT, DESCENT, 0), ()),
+ ("grek", "romn", (ASCENT, DESCENT, 0), ()),
+ ("hani", "ideo", (ASCENT, DESCENT, 0), ()),
+ ),
+)
+
+### TrueType Hinting
+
+# Hints are ignored on macOS.
+#
+# These hints only **vertically** adjust the outlines, for better vertical
+# alignment in golden tests. They don't affect the font or the glyphs' public
+# metrics available to the framework, so they typically don't affect non-golden
+# tests.
+#
+# The hinting goals are:
+#
+# 1. Aligning the key points on glyph outlines between glyphs, when different
+# types of glyphs are placed side by side. E.g., for a given point size, "p"
+# and "É" should never overlap vertically, and "p" and "x" should be
+# bottom-aligned.
+#
+# 2. Aligning the top and the bottom of the "x" glyph with the background. With
+# point size = 14, since the em square's y-extent is 3.5 px (256 * 14 / 1024)
+# below the baseline and 10.5 px above the baseline, the glyph's CBOX will be
+# "rounded out" (3.5 -> 4, 10.5 -> 11). So "x" is going to be misaligned with
+# the background by +0.5 px when rasterized without proper grid-fitting.
+
+# Allocate space in cvt.
+font.cvt = [0]
+# gcd is used to avoid overflowing, this works for the current ASCENT and EM value.
+gcd = math.gcd(ASCENT, EM)
+# The control value program is for computing the y-offset (in pixels) to move
+# the embox's top edge to grid. The end result will be stored to CVT entry 0.
+# CVT[0] = (pointSize * ASCENT / EM) - ceil(pointSize * ASCENT / EM)
+prep_program = f"""
+ RTG
+ PUSHW_1
+ 0
+ MPS
+ PUSHW_1
+ {(ASCENT << 6) // gcd}
+ MUL
+ PUSHW_1
+ {EM // gcd}
+ DIV
+ DUP
+ CEILING
+ SUB
+ WCVTP
+"""
+font.setTableData("prep", fontforge.parseTTInstrs(prep_program))
+
+
+def glyph_program(glyph):
+ # Shift Zone 1 by CVT[0]. In FreeType SHZ actually shifts the zone zp2
+ # points to, instead of top of the stack. That's probably a bug.
+ instructions = """
+ SVTCA[0]
+ PUSHB_4
+ 0
+ 0
+ 0
+ 0
+ SZPS
+ MIRP[0000]
+ SRP2
+ PUSHB_3
+ 1
+ 1
+ 1
+ SZP2
+ SHZ[0]
+ SZPS
+ """
+
+ # Round To Grid every on-curve point, but ignore those who are on the ASCENT
+ # or DESCENT line. This step keeps "p" (ascent flushed) and "É" (descent
+ # flushed)'s y extents from overlapping each other.
+ for index, point in enumerate(
+ [p for contour in glyph.foreground for p in contour]):
+ if point.y not in [ASCENT, DESCENT]:
+ instructions += f"""
+ PUSHB_1
+ {index}
+ MDAP[1]
+ """
+ return fontforge.parseTTInstrs(instructions)
+
+
+### Creating Glyphs Outlines
+
+
+def square_glyph(glyph):
+ pen = glyph.glyphPen()
+ # Counter Clockwise
+ pen.moveTo((0, DESCENT))
+ pen.lineTo((0, ASCENT))
+ pen.lineTo((EM, ASCENT))
+ pen.lineTo((EM, DESCENT))
+ pen.closePath()
+ glyph.ttinstrs = glyph_program(glyph)
+
+
+def ascent_flushed_glyph(glyph):
+ pen = glyph.glyphPen()
+ pen.moveTo((0, DESCENT))
+ pen.lineTo((0, 0))
+ pen.lineTo((EM, 0))
+ pen.lineTo((EM, DESCENT))
+ pen.closePath()
+ glyph.ttinstrs = glyph_program(glyph)
+
+
+def descent_flushed_glyph(glyph):
+ pen = glyph.glyphPen()
+ pen.moveTo((0, 0))
+ pen.lineTo((0, ASCENT))
+ pen.lineTo((EM, ASCENT))
+ pen.lineTo((EM, 0))
+ pen.closePath()
+ glyph.ttinstrs = glyph_program(glyph)
+
+
+def not_def_glyph(glyph):
+ pen = glyph.glyphPen()
+ # Counter Clockwise for the outer contour.
+ pen.moveTo((EM // 8, 0))
+ pen.lineTo((EM // 8, ASCENT))
+ pen.lineTo((EM - EM // 8, ASCENT))
+ pen.lineTo((EM - EM // 8, 0))
+ pen.closePath()
+ # Clockwise, inner contour.
+ pen.moveTo((EM // 4, EM // 8))
+ pen.lineTo((EM - EM // 4, EM // 8))
+ pen.lineTo((EM - EM // 4, ASCENT - EM // 8))
+ pen.lineTo((EM // 4, ASCENT - EM // 8))
+ pen.closePath()
+ glyph.ttinstrs = glyph_program(glyph)
+
+
+def unicode_range(fromUnicode, throughUnicode):
+ return range(fromUnicode, throughUnicode + 1)
+
+
+square_codepoints = [
+ codepoint for l in [
+ unicode_range(0x21, 0x26),
+ unicode_range(0x28, 0x6F),
+ unicode_range(0x71, 0x7E),
+ unicode_range(0xA1, 0xC8),
+ unicode_range(0xCA, 0xFF),
+ [0x131],
+ unicode_range(0x152, 0x153),
+ [0x178, 0x192],
+ unicode_range(0x2C6, 0x2C7),
+ [0x2C9],
+ unicode_range(0x2D8, 0x2DD),
+ [0x394, 0x3A5, 0x3A7, 0x3A9, 0x3BC, 0x3C0],
+ unicode_range(0x2013, 0x2014),
+ unicode_range(0x2018, 0x201A),
+ unicode_range(0x201C, 0x201E),
+ unicode_range(0x2020, 0x2022),
+ [0x2026, 0x2030],
+ unicode_range(0x2039, 0x203A),
+ [0x2044, 0x2122, 0x2126, 0x2202, 0x2206, 0x220F],
+ unicode_range(0x2211, 0x2212),
+ unicode_range(0x2219, 0x221A),
+ [0x221E, 0x222B, 0x2248, 0x2260],
+ unicode_range(0x2264, 0x2265),
+ [
+ 0x22F2, 0x25CA, 0x3007, 0x4E00, 0x4E03, 0x4E09, 0x4E5D, 0x4E8C,
+ 0x4E94, 0x516B, 0x516D, 0x5341, 0x56D7, 0x56DB, 0x571F, 0x6728,
+ 0x6C34, 0x706B, 0x91D1
+ ],
+ unicode_range(0xF000, 0xF002),
+ ] for codepoint in l
+] + [0x70] + [ord(c) for c in "中文测试文本是否正确"]
+
+no_path_codepoints = [
+ #(codepoint, advance %)
+ (0x0020, 1),
+ (0x00A0, 1),
+ (0x2003, 1),
+ (0x3000, 1),
+ (0x2002, 1 / 2),
+ (0x2004, 1 / 3),
+ (0x2005, 1 / 4),
+ (0x2006, 1 / 6),
+ (0x2009, 1 / 5),
+ (0x200A, 1 / 10),
+ (0xFEFF, 0),
+ (0x200B, 0),
+ (0x200C, 0),
+ (0x200D, 0),
+]
+
+
+def create_glyph(name, contour):
+ glyph = font.createChar(-1, name)
+ contour(glyph)
+ glyph.width = EM
+ return glyph
+
+
+if square_codepoints:
+ create_glyph("Square", square_glyph).altuni = square_codepoints
+create_glyph("Ascent Flushed", ascent_flushed_glyph).unicode = 0x70
+create_glyph("Descent Flushed", descent_flushed_glyph).unicode = 0xC9
+create_glyph(".notdef", not_def_glyph).unicode = -1
+
+
+def create_no_path_glyph(codepoint, advance_percentage):
+ name = "Zero Advance" if advance_percentage == 0 else (
+ "Full Advance"
+ if advance_percentage == 1 else f"1/{(int)(1/advance_percentage)} Advance"
+ )
+ no_path_glyph = font.createChar(codepoint, name)
+ no_path_glyph.width = (int)(EM * advance_percentage)
+ return no_path_glyph
+
+
+for (codepoint, advance_percentage) in no_path_codepoints:
+ if (codepoint in square_codepoints):
+ raise ValueError(f"{hex(codepoint)} is occupied.")
+ create_no_path_glyph(codepoint, advance_percentage)
+
+font.generate(sys.argv[1] if len(sys.argv) >= 2 else "test_font.ttf")
+
+### Printing Glyph Map Stats
+
+scripts = set()
+for glyph in font.glyphs():
+ if glyph.unicode >= 0:
+ scripts.add(fontforge.scriptFromUnicode(glyph.unicode))
+ for codepoint, _, _ in glyph.altuni or []:
+ scripts.add(fontforge.scriptFromUnicode(codepoint))
+script_list = list(scripts)
+script_list.sort()
+
+print(f"| \ Script <br />Glyph | {' | '.join(script_list)} |")
+print(" | :--- " + " | :----: " * len(script_list) + "|")
+
+for glyph in font.glyphs():
+ if glyph.unicode < 0 and not glyph.altuni:
+ continue
+ glyph_mapping = {}
+ if glyph.unicode >= 0:
+ glyph_mapping[fontforge.scriptFromUnicode(glyph.unicode)] = [glyph.unicode]
+ for codepoint, _, _ in glyph.altuni or []:
+ script = fontforge.scriptFromUnicode(codepoint)
+ if script in glyph_mapping:
+ glyph_mapping[script].append(codepoint)
+ else:
+ glyph_mapping[script] = [codepoint]
+
+ codepoints_by_script = [
+ glyph_mapping.get(script, []) for script in script_list
+ ]
+
+ def describe_codepoint_range(codepoints):
+ if not codepoints:
+ return ""
+ codepoints.sort()
+ codepoint_ranges = [
+ list(map(itemgetter(1), group))
+ for key, group in groupby(enumerate(codepoints), lambda x: x[0] - x[1])
+ ]
+ characters = [chr(c) for c in codepoints]
+
+ def map_char(c):
+ if c == "`":
+ return "`` ` ``"
+ if c == "|":
+ return "`\\|`"
+ if c.isprintable() and (not c.isspace()):
+ return f"`{c}`"
+ return "`<" + unicodedata.name(c, hex(ord(c))) + ">`"
+
+ full_list = " ".join([map_char(c) for c in characters])
+ return "**codepoint(s):** " + ", ".join([
+ f"{hex(r[0])}-{hex(r[-1])}" if len(r) > 1 else hex(r[0])
+ for r in codepoint_ranges
+ ]) + "<br />" + "**character(s):** " + full_list
+
+ print(
+ f"| {glyph.glyphname} | {' | '.join([describe_codepoint_range(l) for l in codepoints_by_script])} |"
+ )
diff --git a/web_sdk/BUILD.gn b/web_sdk/BUILD.gn
index e36947b..a147d67 100644
--- a/web_sdk/BUILD.gn
+++ b/web_sdk/BUILD.gn
@@ -22,6 +22,7 @@
":web_ui_library",
":web_ui_library_sources",
":web_unicode_library",
+ ":web_test_fonts_library",
":web_locale_keymap_library",
]
@@ -135,6 +136,13 @@
output_dir = "$root_out_dir/flutter_web_sdk/lib/_web_unicode/"
}
+sdk_rewriter("web_test_fonts_library") {
+ library_name = "web_test_fonts"
+ api_file = "//flutter/third_party/web_test_fonts/lib/web_test_fonts.dart"
+ input_dir = "//flutter/third_party/web_test_fonts/lib/web_test_fonts/"
+ output_dir = "$root_out_dir/flutter_web_sdk/lib/_web_test_fonts/"
+}
+
sdk_rewriter("web_locale_keymap_library") {
library_name = "web_locale_keymap"
api_file =
diff --git a/web_sdk/libraries.json b/web_sdk/libraries.json
index c4dd531..b55cd2b 100644
--- a/web_sdk/libraries.json
+++ b/web_sdk/libraries.json
@@ -23,6 +23,9 @@
},
"_web_locale_keymap": {
"uri": "lib/_web_locale_keymap/web_locale_keymap.dart"
+ },
+ "_web_test_fonts": {
+ "uri": "lib/_web_test_fonts/web_test_fonts.dart"
}
}
},
@@ -48,6 +51,9 @@
},
"_web_locale_keymap": {
"uri": "lib/_web_locale_keymap/web_locale_keymap.dart"
+ },
+ "_web_test_fonts": {
+ "uri": "lib/_web_test_fonts/web_test_fonts.dart"
}
}
},
@@ -73,7 +79,10 @@
},
"_web_locale_keymap": {
"uri": "lib/_web_locale_keymap/web_locale_keymap.dart"
+ },
+ "_web_test_fonts": {
+ "uri": "lib/_web_test_fonts/web_test_fonts.dart"
}
}
}
-}
+}
\ No newline at end of file
diff --git a/web_sdk/libraries.yaml b/web_sdk/libraries.yaml
index c55ddfb..d447436 100644
--- a/web_sdk/libraries.yaml
+++ b/web_sdk/libraries.yaml
@@ -33,6 +33,9 @@
_web_locale_keymap:
uri: "lib/_web_locale_keymap/web_locale_keymap.dart"
+ _web_test_fonts:
+ uri: "lib/_web_test_fonts/web_test_fonts.dart"
+
dart2js:
include:
- {path: "../dart-sdk/lib/libraries.json", target: dart2js}
@@ -53,6 +56,9 @@
_web_locale_keymap:
uri: "lib/_web_locale_keymap/web_locale_keymap.dart"
+ _web_test_fonts:
+ uri: "lib/_web_test_fonts/web_test_fonts.dart"
+
wasm:
include:
- {path: "../dart-sdk/lib/libraries.json", target: wasm}
@@ -72,3 +78,6 @@
_web_locale_keymap:
uri: "lib/_web_locale_keymap/web_locale_keymap.dart"
+
+ _web_test_fonts:
+ uri: "lib/_web_test_fonts/web_test_fonts.dart"
diff --git a/web_sdk/sdk_rewriter.dart b/web_sdk/sdk_rewriter.dart
index dd25ce9..77339f9 100644
--- a/web_sdk/sdk_rewriter.dart
+++ b/web_sdk/sdk_rewriter.dart
@@ -94,6 +94,7 @@
RegExp('skwasm_(stub|impl)'): "import 'dart:_skwasm_stub' if (dart.library.ffi) 'dart:_skwasm_impl';",
'engine': "import 'dart:_engine';",
'web_unicode': "import 'dart:_web_unicode';",
+ 'web_test_fonts': "import 'dart:_web_test_fonts';",
'web_locale_keymap': "import 'dart:_web_locale_keymap' as locale_keymap;",
};
diff --git a/web_sdk/test/sdk_rewriter_test.dart b/web_sdk/test/sdk_rewriter_test.dart
index 0c6a6f6..5602bb5 100644
--- a/web_sdk/test/sdk_rewriter_test.dart
+++ b/web_sdk/test/sdk_rewriter_test.dart
@@ -130,22 +130,26 @@
expect(getExtraImportsForLibrary('engine'), <String>[
"import 'dart:_skwasm_stub' if (dart.library.ffi) 'dart:_skwasm_impl';",
"import 'dart:_web_unicode';",
+ "import 'dart:_web_test_fonts';",
"import 'dart:_web_locale_keymap' as locale_keymap;",
]);
expect(getExtraImportsForLibrary('skwasm_stub'), <String>[
"import 'dart:_engine';",
"import 'dart:_web_unicode';",
+ "import 'dart:_web_test_fonts';",
"import 'dart:_web_locale_keymap' as locale_keymap;",
]);
expect(getExtraImportsForLibrary('skwasm_impl'), <String>[
"import 'dart:_engine';",
"import 'dart:_web_unicode';",
+ "import 'dart:_web_test_fonts';",
"import 'dart:_web_locale_keymap' as locale_keymap;",
"import 'dart:ffi';",
]);
// Other libraries (should not have extra imports).
expect(getExtraImportsForLibrary('web_unicode'), isEmpty);
+ expect(getExtraImportsForLibrary('web_test_fonts'), isEmpty);
expect(getExtraImportsForLibrary('web_locale_keymap'), isEmpty);
});
}