Skip to content

Commit 44e440a

Browse files
Add missing TextPainter.strutStyle to paragraph style (#143771)
Fixes an issue where if the `TextSpan` doesn't have a text style, the specified strutStyle is not applied. Additionally, adds a migration flag for flutter/engine#50385, for internal golden changes. It's only going to exist for a week.
1 parent d13bc10 commit 44e440a

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

packages/flutter/lib/src/painting/text_painter.dart

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import 'placeholder_span.dart';
2424
import 'strut_style.dart';
2525
import 'text_scaler.dart';
2626
import 'text_span.dart';
27+
import 'text_style.dart';
2728

2829
export 'dart:ui' show LineMetrics;
2930
export 'package:flutter/services.dart' show TextRange, TextSelection;
@@ -632,6 +633,12 @@ class TextPainter {
632633
}
633634
}
634635

636+
@Deprecated( // flutter_ignore: deprecation_syntax (see analyze.dart)
637+
'The disableStrutHalfLeading flag is for internal migration purposes only and should not be used.'
638+
)
639+
/// Migration only flag, do not use.
640+
static bool disableStrutHalfLeading = true;
641+
635642
// Whether textWidthBasis has changed after the most recent `layout` call.
636643
bool _debugNeedsRelayout = true;
637644
// The result of the most recent `layout` call.
@@ -968,26 +975,35 @@ class TextPainter {
968975
// The defaultTextDirection argument is used for preferredLineHeight in case
969976
// textDirection hasn't yet been set.
970977
assert(textDirection != null || defaultTextDirection != null, 'TextPainter.textDirection must be set to a non-null value before using the TextPainter.');
971-
return _text!.style?.getParagraphStyle(
978+
final TextStyle baseStyle = _text?.style ?? const TextStyle();
979+
final StrutStyle? strutStyle = _strutStyle;
980+
981+
final bool applyMigration = !kIsWeb && TextPainter.disableStrutHalfLeading
982+
&& strutStyle != null && (strutStyle.forceStrutHeight ?? false)
983+
&& strutStyle.leadingDistribution == TextLeadingDistribution.even;
984+
final StrutStyle? strutStyleForMigration = !applyMigration
985+
? strutStyle
986+
: StrutStyle(
987+
fontFamily: strutStyle.fontFamily,
988+
fontFamilyFallback: strutStyle.fontFamilyFallback,
989+
fontSize: strutStyle.fontSize,
990+
height: strutStyle.height,
991+
leadingDistribution: TextLeadingDistribution.proportional,
992+
leading: strutStyle.leading,
993+
fontWeight: strutStyle.fontWeight,
994+
fontStyle: strutStyle.fontStyle,
995+
forceStrutHeight: strutStyle.forceStrutHeight,
996+
);
997+
998+
return baseStyle.getParagraphStyle(
972999
textAlign: textAlign,
9731000
textDirection: textDirection ?? defaultTextDirection,
9741001
textScaler: textScaler,
9751002
maxLines: _maxLines,
9761003
textHeightBehavior: _textHeightBehavior,
9771004
ellipsis: _ellipsis,
9781005
locale: _locale,
979-
strutStyle: _strutStyle,
980-
) ?? ui.ParagraphStyle(
981-
textAlign: textAlign,
982-
textDirection: textDirection ?? defaultTextDirection,
983-
// Use the default font size to multiply by as RichText does not
984-
// perform inheriting [TextStyle]s and would otherwise
985-
// fail to apply textScaler.
986-
fontSize: textScaler.scale(kDefaultFontSize),
987-
maxLines: maxLines,
988-
textHeightBehavior: _textHeightBehavior,
989-
ellipsis: ellipsis,
990-
locale: locale,
1006+
strutStyle: strutStyleForMigration,
9911007
);
9921008
}
9931009

packages/flutter/lib/src/painting/text_style.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,7 @@ class TextStyle with Diagnosticable {
13881388
},
13891389
height: strutStyle.height,
13901390
leading: strutStyle.leading,
1391+
leadingDistribution: strutStyle.leadingDistribution,
13911392
fontWeight: strutStyle.fontWeight,
13921393
fontStyle: strutStyle.fontStyle,
13931394
forceStrutHeight: strutStyle.forceStrutHeight,

packages/flutter/test/painting/text_painter_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,45 @@ void main() {
15461546
}
15471547
}, skip: kIsWeb && !isCanvasKit); // [intended] Browsers seem to always round font/glyph metrics.
15481548

1549+
group('strut style', () {
1550+
test('strut style applies when the span has no style', () {
1551+
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10);
1552+
final TextPainter painter = TextPainter(
1553+
textDirection: TextDirection.ltr,
1554+
text: const TextSpan(),
1555+
strutStyle: strut,
1556+
)..layout();
1557+
expect(painter.height, 100);
1558+
});
1559+
1560+
test('strut style leading is a fontSize multiplier', () {
1561+
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, leading: 2);
1562+
final TextPainter painter = TextPainter(
1563+
textDirection: TextDirection.ltr,
1564+
text: const TextSpan(),
1565+
strutStyle: strut,
1566+
)..layout();
1567+
expect(painter.height, 100 + 20);
1568+
// Top leading + scaled ascent.
1569+
expect(painter.computeDistanceToActualBaseline(TextBaseline.alphabetic), 10 + 10 * 7.5);
1570+
});
1571+
1572+
test('force strut height', () {
1573+
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, forceStrutHeight: true);
1574+
final TextPainter painter = TextPainter(
1575+
textDirection: TextDirection.ltr,
1576+
text: const TextSpan(text: 'A', style: TextStyle(fontSize: 20)),
1577+
strutStyle: strut,
1578+
)..layout();
1579+
expect(painter.height, 100);
1580+
const double baseline = 75;
1581+
expect(
1582+
painter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1)),
1583+
const <ui.TextBox>[TextBox.fromLTRBD(0, baseline - 15, 20, baseline + 5, TextDirection.ltr)],
1584+
);
1585+
});
1586+
}, skip: kIsWeb && !isCanvasKit); // [intended] strut spport for HTML renderer https://github.com/flutter/flutter/issues/32243.
1587+
15491588
test('TextPainter dispatches memory events', () async {
15501589
await expectLater(
15511590
await memoryEvents(() => TextPainter().dispose(), TextPainter),

0 commit comments

Comments
 (0)