Skip to content

Commit

Permalink
Fix the RenderFlex.computeDryBaseline implementation to match compute…
Browse files Browse the repository at this point in the history
…DistanceToActualBaseline (#149062)

Per Hixie's comment [here](#145739 (comment)), keep the current behavior
  • Loading branch information
LongCatIsLooong committed May 28, 2024
1 parent c109b3c commit 0214afb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
16 changes: 11 additions & 5 deletions packages/flutter/lib/src/rendering/flex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 308,8 @@ enum CrossAxisAlignment {
/// See also:
///
/// * [RenderBox.getDistanceToBaseline], which defines the baseline of a box.
/// * [IgnoreBaseline], which can be used to ignore a child for the purpose of
/// baseline alignment.
baseline;

double _getChildCrossAxisOffset(double freeSpace, bool flipped) {
Expand Down Expand Up @@ -821,13 823,17 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
final double freeSpace = math.max(0.0, sizes.mainAxisFreeSpace);
final bool flipMainAxis = _flipMainAxis;
final (double leadingSpaceY, double spaceBetween) = mainAxisAlignment._distributeSpace(freeSpace, childCount, flipMainAxis);
double y = leadingSpaceY;
final (_NextChild nextChild, RenderBox? topLeftChild) = flipMainAxis ? (childBefore, lastChild) : (childAfter, firstChild);
for (RenderBox? child = topLeftChild; child != null; child = nextChild(child)) {
double y = flipMainAxis
? leadingSpaceY (childCount - 1) * spaceBetween (sizes.axisSize.mainAxisExtent - sizes.mainAxisFreeSpace)
: leadingSpaceY;
final double directionUnit = flipMainAxis ? -1.0 : 1.0;
for (RenderBox? child = firstChild; baselineOffset == BaselineOffset.noBaseline && child != null; child = childAfter(child)) {
final BoxConstraints childConstraints = constraintsForChild(child);
final Size childSize = child.getDryLayout(childConstraints);
baselineOffset = baselineOffset.minOf(BaselineOffset(child.getDryBaseline(childConstraints, baseline)) y);
y = spaceBetween childSize.height;
final double? childBaselineOffset = child.getDryBaseline(childConstraints, baseline);
final double additionalY = flipMainAxis ? - childSize.height : 0.0;
baselineOffset = BaselineOffset(childBaselineOffset) y additionalY;
y = directionUnit * (spaceBetween childSize.height);
}
case Axis.horizontal:
final bool flipCrossAxis = _flipCrossAxis;
Expand Down
47 changes: 47 additions & 0 deletions packages/flutter/test/rendering/flex_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 648,53 @@ void main() {
expect(box2.localToGlobal(Offset.zero).dy, 0.0);
});

test('Vertical Flex Baseline', () {
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);
final RenderConstrainedBox box1 = RenderConstrainedBox(
additionalConstraints: square,
child: RenderFlowBaselineTestBox()
..gridCount = 1
..baselinePlacer = (double height) => 10,
);
final RenderConstrainedBox box2 = RenderConstrainedBox(
additionalConstraints: square,
child: RenderFlowBaselineTestBox()
..gridCount = 1
..baselinePlacer = (double height) => 10,
);
RenderConstrainedBox filler() => RenderConstrainedBox(additionalConstraints: square);
final RenderFlex flex = RenderFlex(
textDirection: TextDirection.ltr,
children: <RenderBox>[
filler(),
box1,
filler(),
box2,
filler(),
],
direction: Axis.vertical,
);
layout(flex, phase: EnginePhase.paint);
final double flexHeight = flex.size.height;

// We can't call the getDistanceToBaseline method directly. Check the dry
// baseline instead, and in debug mode there are asserts that verify
// the two methods return the same results.
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), 100 10);

flex.mainAxisAlignment = MainAxisAlignment.end;
pumpFrame(phase: EnginePhase.paint);
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), flexHeight - 400 10);

flex.verticalDirection = VerticalDirection.up;
pumpFrame(phase: EnginePhase.paint);
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), 300 10);

flex.mainAxisAlignment = MainAxisAlignment.start;
pumpFrame(phase: EnginePhase.paint);
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), flexHeight - 200 10);
});

group('Intrinsics', () {
test('main axis intrinsics with RenderAspectRatio 1', () {
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);
Expand Down

0 comments on commit 0214afb

Please sign in to comment.