Unverified Commit b5a4d089 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Intrinsic Width fixes for RenderParagraph (#70236)

parent 3fce16c3
...@@ -395,42 +395,36 @@ class RenderParagraph extends RenderBox ...@@ -395,42 +395,36 @@ class RenderParagraph extends RenderBox
RenderBox? child = firstChild; RenderBox? child = firstChild;
final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false); final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false);
int childIndex = 0; 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) { while (child != null) {
// Height and baseline is irrelevant as all text will be laid // 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( placeholderDimensions[childIndex] = PlaceholderDimensions(
size: Size(child.getMaxIntrinsicWidth(height), height), size: Size(child.getMaxIntrinsicWidth(double.infinity), 0.0),
alignment: _placeholderSpans[childIndex].alignment, alignment: _placeholderSpans[childIndex].alignment,
baseline: _placeholderSpans[childIndex].baseline, baseline: _placeholderSpans[childIndex].baseline,
); );
child = childAfter(child); child = childAfter(child);
childIndex += 1; childIndex += 1;
} }
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>()); _textPainter.setPlaceholderDimensions(placeholderDimensions);
} }
void _computeChildrenWidthWithMinIntrinsics(double height) { void _computeChildrenWidthWithMinIntrinsics(double height) {
RenderBox? child = firstChild; RenderBox? child = firstChild;
final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false); final List<PlaceholderDimensions> placeholderDimensions = List<PlaceholderDimensions>.filled(childCount, PlaceholderDimensions.empty, growable: false);
int childIndex = 0; 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) { while (child != null) {
final double intrinsicWidth = child.getMinIntrinsicWidth(height); // Height and baseline is irrelevant; only looking for the widest word or
final double intrinsicHeight = child.getMinIntrinsicHeight(intrinsicWidth); // placeholder. Therefore, using 0.0 as a dummy for height.
placeholderDimensions[childIndex] = PlaceholderDimensions( placeholderDimensions[childIndex] = PlaceholderDimensions(
size: Size(intrinsicWidth, intrinsicHeight), size: Size(child.getMinIntrinsicWidth(double.infinity), 0.0),
alignment: _placeholderSpans[childIndex].alignment, alignment: _placeholderSpans[childIndex].alignment,
baseline: _placeholderSpans[childIndex].baseline, baseline: _placeholderSpans[childIndex].baseline,
); );
child = childAfter(child); child = childAfter(child);
childIndex += 1; childIndex += 1;
} }
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>()); _textPainter.setPlaceholderDimensions(placeholderDimensions);
} }
void _computeChildrenHeightWithMinIntrinsics(double width) { void _computeChildrenHeightWithMinIntrinsics(double width) {
...@@ -451,7 +445,7 @@ class RenderParagraph extends RenderBox ...@@ -451,7 +445,7 @@ class RenderParagraph extends RenderBox
child = childAfter(child); child = childAfter(child);
childIndex += 1; childIndex += 1;
} }
_textPainter.setPlaceholderDimensions(placeholderDimensions.cast<PlaceholderDimensions>()); _textPainter.setPlaceholderDimensions(placeholderDimensions);
} }
@override @override
...@@ -593,7 +587,7 @@ class RenderParagraph extends RenderBox ...@@ -593,7 +587,7 @@ class RenderParagraph extends RenderBox
child = childAfter(child); child = childAfter(child);
childIndex += 1; childIndex += 1;
} }
_placeholderDimensions = placeholderDimensions.cast<PlaceholderDimensions>(); _placeholderDimensions = placeholderDimensions;
} }
// Iterate through the laid-out children and set the parentData offsets based // Iterate through the laid-out children and set the parentData offsets based
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
...@@ -1209,6 +1210,47 @@ void main() { ...@@ -1209,6 +1210,47 @@ void main() {
ignoreTransform: true, ignoreTransform: true,
)); ));
}, semanticsEnabled: true, skip: isBrowser); // Browser does not support widget span }, 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({ Future<void> _pumpTextWidget({
......
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