Unverified Commit 3a15841d authored by chunhtai's avatar chunhtai Committed by GitHub

reland "fix the widget span layout when text scale factor != 1" and h… (#60021)

parent ca32668b
......@@ -79,6 +79,13 @@ class RenderParagraph extends RenderBox
StrutStyle strutStyle,
TextWidthBasis textWidthBasis = TextWidthBasis.parent,
ui.TextHeightBehavior textHeightBehavior,
@Deprecated(
'This parameter is a temporary flag to migrate the internal tests and '
'should not be used in other contexts. For more details, please check '
'https://github.com/flutter/flutter/issues/59316. '
'This feature was deprecated after v1.19.0.'
)
bool applyTextScaleFactorToWidgetSpan = false,
List<RenderBox> children,
}) : assert(text != null),
assert(text.debugAssertIsValid()),
......@@ -91,6 +98,7 @@ class RenderParagraph extends RenderBox
assert(textWidthBasis != null),
_softWrap = softWrap,
_overflow = overflow,
_applyTextScaleFactorToWidgetSpan = applyTextScaleFactorToWidgetSpan,
_textPainter = TextPainter(
text: text,
textAlign: textAlign,
......@@ -290,6 +298,8 @@ class RenderParagraph extends RenderBox
markNeedsLayout();
}
final bool _applyTextScaleFactorToWidgetSpan;
@override
double computeMinIntrinsicWidth(double height) {
if (!_canComputeIntrinsics()) {
......@@ -526,13 +536,17 @@ class RenderParagraph extends RenderBox
RenderBox child = firstChild;
_placeholderDimensions = List<PlaceholderDimensions>(childCount);
int childIndex = 0;
BoxConstraints boxConstraints = BoxConstraints(maxWidth: constraints.maxWidth);
// The content will be enlarged by textScaleFactor during painting phase.
// We reduce constraint by textScaleFactor so that the content will fit
// into the box once it is enlarged.
if (_applyTextScaleFactorToWidgetSpan)
boxConstraints = boxConstraints / textScaleFactor;
while (child != null) {
// Only constrain the width to the maximum width of the paragraph.
// Leave height unconstrained, which will overflow if expanded past.
child.layout(
BoxConstraints(
maxWidth: constraints.maxWidth,
),
boxConstraints,
parentUsesSize: true,
);
double baselineOffset;
......
......@@ -5144,6 +5144,13 @@ class RichText extends MultiChildRenderObjectWidget {
this.strutStyle,
this.textWidthBasis = TextWidthBasis.parent,
this.textHeightBehavior,
@Deprecated(
'This parameter is a temporary flag to migrate the internal tests and '
'should not be used in other contexts. For more details, see '
'https://github.com/flutter/flutter/issues/59316. '
'This feature was deprecated after v1.19.0.'
)
bool applyTextScaleFactorToWidgetSpan = false,
}) : assert(text != null),
assert(textAlign != null),
assert(softWrap != null),
......@@ -5151,6 +5158,7 @@ class RichText extends MultiChildRenderObjectWidget {
assert(textScaleFactor != null),
assert(maxLines == null || maxLines > 0),
assert(textWidthBasis != null),
_applyTextScaleFactorToWidgetSpan = applyTextScaleFactorToWidgetSpan,
super(key: key, children: _extractChildren(text));
// Traverses the InlineSpan tree and depth-first collects the list of
......@@ -5228,6 +5236,8 @@ class RichText extends MultiChildRenderObjectWidget {
/// {@macro flutter.dart:ui.textHeightBehavior}
final ui.TextHeightBehavior textHeightBehavior;
final bool _applyTextScaleFactorToWidgetSpan;
@override
RenderParagraph createRenderObject(BuildContext context) {
assert(textDirection != null || debugCheckHasDirectionality(context));
......@@ -5241,6 +5251,7 @@ class RichText extends MultiChildRenderObjectWidget {
strutStyle: strutStyle,
textWidthBasis: textWidthBasis,
textHeightBehavior: textHeightBehavior,
applyTextScaleFactorToWidgetSpan: _applyTextScaleFactorToWidgetSpan,
locale: locale ?? Localizations.localeOf(context, nullOk: true),
);
}
......
......@@ -361,6 +361,7 @@ class Text extends StatelessWidget {
'A non-null String must be provided to a Text widget.',
),
textSpan = null,
_applyTextScaleFactorToWidgetSpan = true,
super(key: key);
/// Creates a text widget with a [InlineSpan].
......@@ -388,11 +389,19 @@ class Text extends StatelessWidget {
this.semanticsLabel,
this.textWidthBasis,
this.textHeightBehavior,
@Deprecated(
'This parameter is a temporary flag to migrate the internal tests and '
'should not be used in other contexts. For more details, please check '
'https://github.com/flutter/flutter/issues/59316. '
'This feature was deprecated after v1.19.0.'
)
bool applyTextScaleFactorToWidgetSpan = false,
}) : assert(
textSpan != null,
'A non-null TextSpan must be provided to a Text.rich widget.',
),
data = null,
_applyTextScaleFactorToWidgetSpan = applyTextScaleFactorToWidgetSpan,
super(key: key);
/// The text to display.
......@@ -493,6 +502,8 @@ class Text extends StatelessWidget {
/// {@macro flutter.dart:ui.textHeightBehavior}
final ui.TextHeightBehavior textHeightBehavior;
final bool _applyTextScaleFactorToWidgetSpan;
@override
Widget build(BuildContext context) {
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
......@@ -512,6 +523,7 @@ class Text extends StatelessWidget {
strutStyle: strutStyle,
textWidthBasis: textWidthBasis ?? defaultTextStyle.textWidthBasis,
textHeightBehavior: textHeightBehavior ?? defaultTextStyle.textHeightBehavior ?? DefaultTextHeightBehavior.of(context),
applyTextScaleFactorToWidgetSpan: _applyTextScaleFactorToWidgetSpan,
text: TextSpan(
style: effectiveTextStyle,
text: data,
......
......@@ -163,6 +163,70 @@ void main() {
expect(tester.takeException(), null);
}, skip: isBrowser); // TODO(yjbanov): https://github.com/flutter/flutter/issues/42086
testWidgets('inline widgets works with textScaleFactor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/59316
final UniqueKey key = UniqueKey();
double textScaleFactor = 1.0;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('title')),
body: Center(
child: Text.rich(
TextSpan(
children: <InlineSpan>[
WidgetSpan(
child: RichText(
text: const TextSpan(text: 'widget should be truncated'),
textDirection: TextDirection.ltr,
),
),
],
),
key: key,
textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor,
applyTextScaleFactorToWidgetSpan: true,
),
),
),
),
);
RenderBox renderText = tester.renderObject(find.byKey(key));
final double singleLineHeight = renderText.size.height;
// Now, increases the text scale factor by 5 times.
textScaleFactor = textScaleFactor * 5;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('title')),
body: Center(
child: Text.rich(
TextSpan(
children: <InlineSpan>[
WidgetSpan(
child: RichText(
text: const TextSpan(text: 'widget should be truncated'),
textDirection: TextDirection.ltr,
),
),
],
),
key: key,
textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor,
applyTextScaleFactorToWidgetSpan: true,
),
),
),
),
);
renderText = tester.renderObject(find.byKey(key));
// The RichText in the widget span should wrap into three lines.
expect(renderText.size.height, singleLineHeight * textScaleFactor * 3);
}, skip: isBrowser); // TODO(yjbanov): https://github.com/flutter/flutter/issues/42086
testWidgets('semanticsLabel can override text label', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment