mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Intrinsic Width fixes for RenderParagraph (#70236)
This commit is contained in:
parent
3fce16c329
commit
b5a4d08962
@ -395,42 +395,36 @@ class RenderParagraph extends RenderBox
|
||||
RenderBox? child = firstChild;
|
||||
final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false);
|
||||
int childIndex = 0;
|
||||
// Takes textScaleFactor into account because the content of the placeholder
|
||||
// span will be scale up when it paints.
|
||||
height = height / textScaleFactor;
|
||||
while (child != null) {
|
||||
// Height and baseline is irrelevant as all text will be laid
|
||||
// out in a single line.
|
||||
// out in a single line. Therefore, using 0.0 as a dummy for the height.
|
||||
placeholderDimensions[childIndex] = PlaceholderDimensions(
|
||||
size: Size(child.getMaxIntrinsicWidth(height), height),
|
||||
size: Size(child.getMaxIntrinsicWidth(double.infinity), 0.0),
|
||||
alignment: _placeholderSpans[childIndex].alignment,
|
||||
baseline: _placeholderSpans[childIndex].baseline,
|
||||
);
|
||||
child = childAfter(child);
|
||||
childIndex += 1;
|
||||
}
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>());
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions);
|
||||
}
|
||||
|
||||
void _computeChildrenWidthWithMinIntrinsics(double height) {
|
||||
RenderBox? child = firstChild;
|
||||
final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false);
|
||||
int childIndex = 0;
|
||||
// Takes textScaleFactor into account because the content of the placeholder
|
||||
// span will be scale up when it paints.
|
||||
height = height / textScaleFactor;
|
||||
while (child != null) {
|
||||
final double intrinsicWidth = child.getMinIntrinsicWidth(height);
|
||||
final double intrinsicHeight = child.getMinIntrinsicHeight(intrinsicWidth);
|
||||
// Height and baseline is irrelevant; only looking for the widest word or
|
||||
// placeholder. Therefore, using 0.0 as a dummy for height.
|
||||
placeholderDimensions[childIndex] = PlaceholderDimensions(
|
||||
size: Size(intrinsicWidth, intrinsicHeight),
|
||||
size: Size(child.getMinIntrinsicWidth(double.infinity), 0.0),
|
||||
alignment: _placeholderSpans[childIndex].alignment,
|
||||
baseline: _placeholderSpans[childIndex].baseline,
|
||||
);
|
||||
child = childAfter(child);
|
||||
childIndex += 1;
|
||||
}
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>());
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions);
|
||||
}
|
||||
|
||||
void _computeChildrenHeightWithMinIntrinsics(double width) {
|
||||
@ -451,7 +445,7 @@ class RenderParagraph extends RenderBox
|
||||
child = childAfter(child);
|
||||
childIndex += 1;
|
||||
}
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>());
|
||||
_textPainter.setPlaceholderDimensions(placeholderDimensions);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -593,7 +587,7 @@ class RenderParagraph extends RenderBox
|
||||
child = childAfter(child);
|
||||
childIndex += 1;
|
||||
}
|
||||
_placeholderDimensions = placeholderDimensions.cast<PlaceholderDimensions>();
|
||||
_placeholderDimensions = placeholderDimensions;
|
||||
}
|
||||
|
||||
// Iterate through the laid-out children and set the parentData offsets based
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@ -1209,6 +1210,47 @@ void main() {
|
||||
ignoreTransform: true,
|
||||
));
|
||||
}, semanticsEnabled: true, skip: isBrowser); // Browser does not support widget span
|
||||
|
||||
testWidgets('RenderParagraph intrinsic width', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Center(
|
||||
child: Container(
|
||||
height: 100,
|
||||
child: IntrinsicWidth(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: const TextStyle(fontSize: 16, height: 1),
|
||||
children: <InlineSpan>[
|
||||
const TextSpan(text: 'S '),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.top,
|
||||
child: Wrap(
|
||||
direction: Axis.vertical,
|
||||
children: <Widget>[
|
||||
Container(width: 200, height: 100),
|
||||
Container(width: 200, height: 30),
|
||||
],
|
||||
),
|
||||
),
|
||||
const TextSpan(text: ' E'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.getSize(find.byType(RichText)).width, 200 + 4 * 16.0);
|
||||
final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.byType(RichText));
|
||||
// The inline spans are rendered on one (horizontal) line, the sum of the widths is the max intrinsic width.
|
||||
expect(paragraph.getMaxIntrinsicWidth(0.0), 200 + 4 * 16.0);
|
||||
// The inline spans are rendered in one vertical run, the widest one determines the min intrinsic width.
|
||||
expect(paragraph.getMinIntrinsicWidth(0.0), 200, skip: 'https://github.com/flutter/flutter/issues/70230');
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _pumpTextWidget({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user