@@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
3
3
import 'package:flutter/foundation.dart' ;
4
4
import 'package:flutter/material.dart' ;
5
5
import 'package:flutter/rendering.dart' ;
6
+ import 'package:flutter/services.dart' ;
6
7
import 'package:flutter_checks/flutter_checks.dart' ;
7
8
import 'package:flutter_test/flutter_test.dart' ;
8
9
import 'package:url_launcher/url_launcher.dart' ;
@@ -572,98 +573,65 @@ void main() {
572
573
tester.widget (find.text ('λ' , findRichText: true ));
573
574
});
574
575
575
- void checkKatexText (
576
- WidgetTester tester,
577
- String text, {
578
- required String fontFamily,
579
- required double fontSize,
580
- required double fontHeight,
581
- }) {
582
- check (mergedStyleOf (tester, text)).isNotNull ()
583
- ..fontFamily.equals (fontFamily)
584
- ..fontSize.equals (fontSize);
585
- check (tester.getSize (find.text (text)))
586
- .height.isCloseTo (fontSize * fontHeight, 0.5 );
587
- }
588
-
589
- testWidgets ('displays KaTeX content with different sizing' , (tester) async {
590
- addTearDown (testBinding.reset);
591
- final globalSettings = testBinding.globalStore.settings;
592
- await globalSettings.setBool (BoolGlobalSetting .renderKatex, true );
593
- check (globalSettings).getBool (BoolGlobalSetting .renderKatex).isTrue ();
594
-
595
- final content = ContentExample .mathBlockKatexSizing;
596
- await prepareContent (tester, plainContent (content.html));
597
-
598
- final mathBlockNode = content.expectedNodes.single as MathBlockNode ;
599
- final baseNode = mathBlockNode.nodes! .single as KatexSpanNode ;
600
- final nodes = baseNode.nodes! .skip (1 ); // Skip .strut node.
601
- for (var katexNode in nodes) {
602
- katexNode = katexNode as KatexSpanNode ;
603
- final fontSize = katexNode.styles.fontSizeEm! * kBaseKatexTextStyle.fontSize! ;
604
- checkKatexText (tester, katexNode.text! ,
605
- fontFamily: 'KaTeX_Main' ,
606
- fontSize: fontSize,
607
- fontHeight: kBaseKatexTextStyle.height! );
576
+ group ('characters render at specific offsets with specific size' , () {
577
+ const testCases = < (ContentExample , List <(String , Offset , Size )>, {bool ? skip})> [
578
+ (ContentExample .mathBlockKatexSizing, skip: false , [
579
+ ('1' , Offset (0.00 , 2.24 ), Size (25.59 , 61.00 )),
580
+ ('2' , Offset (25.59 , 9.90 ), Size (21.33 , 51.00 )),
581
+ ('3' , Offset (46.91 , 16.30 ), Size (17.77 , 43.00 )),
582
+ ('4' , Offset (64.68 , 21.63 ), Size (14.80 , 36.00 )),
583
+ ('5' , Offset (79.48 , 26.07 ), Size (12.34 , 30.00 )),
584
+ ('6' , Offset (91.82 , 29.77 ), Size (10.28 , 25.00 )),
585
+ ('7' , Offset (102.10 , 31.62 ), Size (9.25 , 22.00 )),
586
+ ('8' , Offset (111.35 , 33.47 ), Size (8.23 , 20.00 )),
587
+ ('9' , Offset (119.58 , 35.32 ), Size (7.20 , 17.00 )),
588
+ ('0' , Offset (126.77 , 39.02 ), Size (5.14 , 12.00 )),
589
+ ]),
590
+ (ContentExample .mathBlockKatexNestedSizing, skip: false , [
591
+ ('1' , Offset (0.00 , 39.58 ), Size (5.14 , 12.00 )),
592
+ ('2' , Offset (5.14 , 2.80 ), Size (25.59 , 61.00 )),
593
+ ]),
594
+ // TODO: Re-enable this test after adding support for parsing
595
+ // `vertical-align` in inline styles. Currently it fails
596
+ // because `strut` span has `vertical-align`.
597
+ (ContentExample .mathBlockKatexDelimSizing, skip: true , [
598
+ ('(' , Offset (8.00 , 46.36 ), Size (9.42 , 25.00 )),
599
+ ('[' , Offset (17.42 , 48.36 ), Size (9.71 , 25.00 )),
600
+ ('⌈' , Offset (27.12 , 49.36 ), Size (11.99 , 25.00 )),
601
+ ('⌊' , Offset (39.11 , 49.36 ), Size (13.14 , 25.00 )),
602
+ ]),
603
+ ];
604
+
605
+ for (final testCase in testCases) {
606
+ testWidgets (testCase.$1.description, (tester) async {
607
+ await _loadKatexFonts ();
608
+
609
+ addTearDown (testBinding.reset);
610
+ final globalSettings = testBinding.globalStore.settings;
611
+ await globalSettings.setBool (BoolGlobalSetting .renderKatex, true );
612
+ check (globalSettings).getBool (BoolGlobalSetting .renderKatex).isTrue ();
613
+
614
+ await prepareContent (tester, plainContent (testCase.$1.html));
615
+
616
+ final baseRect = tester.getRect (find.byType (KatexWidget ));
617
+
618
+ for (final characterData in testCase.$2) {
619
+ final character = characterData.$1;
620
+ final expectedTopLeftOffset = characterData.$2;
621
+ final expectedSize = characterData.$3;
622
+
623
+ final rect = tester.getRect (find.text (character));
624
+ final topLeftOffset = rect.topLeft - baseRect.topLeft;
625
+ final size = rect.size;
626
+
627
+ check (topLeftOffset)
628
+ .within (distance: 0.05 , from: expectedTopLeftOffset);
629
+ check (size)
630
+ .within (distance: 0.05 , from: expectedSize);
631
+ }
632
+ }, skip: testCase.skip);
608
633
}
609
634
});
610
-
611
- testWidgets ('displays KaTeX content with nested sizing' , (tester) async {
612
- addTearDown (testBinding.reset);
613
- final globalSettings = testBinding.globalStore.settings;
614
- await globalSettings.setBool (BoolGlobalSetting .renderKatex, true );
615
- check (globalSettings).getBool (BoolGlobalSetting .renderKatex).isTrue ();
616
-
617
- final content = ContentExample .mathBlockKatexNestedSizing;
618
- await prepareContent (tester, plainContent (content.html));
619
-
620
- var fontSize = 0.5 * kBaseKatexTextStyle.fontSize! ;
621
- checkKatexText (tester, '1' ,
622
- fontFamily: 'KaTeX_Main' ,
623
- fontSize: fontSize,
624
- fontHeight: kBaseKatexTextStyle.height! );
625
-
626
- fontSize = 4.976 * fontSize;
627
- checkKatexText (tester, '2' ,
628
- fontFamily: 'KaTeX_Main' ,
629
- fontSize: fontSize,
630
- fontHeight: kBaseKatexTextStyle.height! );
631
- });
632
-
633
- testWidgets ('displays KaTeX content with different delimiter sizing' , (tester) async {
634
- addTearDown (testBinding.reset);
635
- final globalSettings = testBinding.globalStore.settings;
636
- await globalSettings.setBool (BoolGlobalSetting .renderKatex, true );
637
- check (globalSettings).getBool (BoolGlobalSetting .renderKatex).isTrue ();
638
-
639
- final content = ContentExample .mathBlockKatexDelimSizing;
640
- await prepareContent (tester, plainContent (content.html));
641
-
642
- final mathBlockNode = content.expectedNodes.single as MathBlockNode ;
643
- final baseNode = mathBlockNode.nodes! .single as KatexSpanNode ;
644
- var nodes = baseNode.nodes! .skip (1 ); // Skip .strut node.
645
-
646
- final fontSize = kBaseKatexTextStyle.fontSize! ;
647
-
648
- final firstNode = nodes.first as KatexSpanNode ;
649
- checkKatexText (tester, firstNode.text! ,
650
- fontFamily: 'KaTeX_Main' ,
651
- fontSize: fontSize,
652
- fontHeight: kBaseKatexTextStyle.height! );
653
- nodes = nodes.skip (1 );
654
-
655
- for (var katexNode in nodes) {
656
- katexNode = katexNode as KatexSpanNode ;
657
- katexNode = katexNode.nodes! .single as KatexSpanNode ; // Skip empty .mord parent.
658
- final fontFamily = katexNode.styles.fontFamily! ;
659
- checkKatexText (tester, katexNode.text! ,
660
- fontFamily: fontFamily,
661
- fontSize: fontSize,
662
- fontHeight: kBaseKatexTextStyle.height! );
663
- }
664
- }, skip: true ); // TODO: Re-enable this test after adding support for parsing
665
- // `vertical-align` in inline styles. Currently it fails
666
- // because `strut` span has `vertical-align`.
667
635
});
668
636
669
637
/// Make a [TargetFontSizeFinder] to pass to [checkFontSizeRatio] ,
@@ -1432,3 +1400,45 @@ void main() {
1432
1400
});
1433
1401
});
1434
1402
}
1403
+
1404
+ Future <void > _loadKatexFonts () async {
1405
+ const fonts = {
1406
+ 'KaTeX_AMS' : ['KaTeX_AMS-Regular.ttf' ],
1407
+ 'KaTeX_Caligraphic' : [
1408
+ 'KaTeX_Caligraphic-Regular.ttf' ,
1409
+ 'KaTeX_Caligraphic-Bold.ttf' ,
1410
+ ],
1411
+ 'KaTeX_Fraktur' : [
1412
+ 'KaTeX_Fraktur-Regular.ttf' ,
1413
+ 'KaTeX_Fraktur-Bold.ttf' ,
1414
+ ],
1415
+ 'KaTeX_Main' : [
1416
+ 'KaTeX_Main-Regular.ttf' ,
1417
+ 'KaTeX_Main-Bold.ttf' ,
1418
+ 'KaTeX_Main-Italic.ttf' ,
1419
+ 'KaTeX_Main-BoldItalic.ttf' ,
1420
+ ],
1421
+ 'KaTeX_Math' : [
1422
+ 'KaTeX_Math-Italic.ttf' ,
1423
+ 'KaTeX_Math-BoldItalic.ttf' ,
1424
+ ],
1425
+ 'KaTeX_SansSerif' : [
1426
+ 'KaTeX_SansSerif-Regular.ttf' ,
1427
+ 'KaTeX_SansSerif-Bold.ttf' ,
1428
+ 'KaTeX_SansSerif-Italic.ttf' ,
1429
+ ],
1430
+ 'KaTeX_Script' : ['KaTeX_Script-Regular.ttf' ],
1431
+ 'KaTeX_Size1' : ['KaTeX_Size1-Regular.ttf' ],
1432
+ 'KaTeX_Size2' : ['KaTeX_Size2-Regular.ttf' ],
1433
+ 'KaTeX_Size3' : ['KaTeX_Size3-Regular.ttf' ],
1434
+ 'KaTeX_Size4' : ['KaTeX_Size4-Regular.ttf' ],
1435
+ 'KaTeX_Typewriter' : ['KaTeX_Typewriter-Regular.ttf' ],
1436
+ };
1437
+ for (final MapEntry (key: fontFamily, value: fontFiles) in fonts.entries) {
1438
+ final fontLoader = FontLoader (fontFamily);
1439
+ for (final fontFile in fontFiles) {
1440
+ fontLoader.addFont (rootBundle.load ('assets/KaTeX/$fontFile ' ));
1441
+ }
1442
+ await fontLoader.load ();
1443
+ }
1444
+ }
0 commit comments