From 37ebf792993c2168a42b6503e36d3b1266a05df2 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 12:46:46 +0700 Subject: [PATCH 1/8] Copy from flutter/flutter --- packages/core/lib/src/widgets/html_flex.dart | 1243 ++++++++++++------ packages/core/pubspec.yaml | 4 +- 2 files changed, 810 insertions(+), 437 deletions(-) diff --git a/packages/core/lib/src/widgets/html_flex.dart b/packages/core/lib/src/widgets/html_flex.dart index 12a66302c..9f1d015b0 100644 --- a/packages/core/lib/src/widgets/html_flex.dart +++ b/packages/core/lib/src/widgets/html_flex.dart @@ -2,18 +2,18 @@ set -euo pipefail -_widgetHash=$( curl -s https://raw.githubusercontent.com/flutter/flutter/1a0dc8f/packages/flutter/lib/src/widgets/basic.dart | openssl md5 ) +_widgetHash=$( curl -s https://github.com/flutter/flutter/raw/35c388a/packages/flutter/lib/src/widgets/basic.dart | openssl md5 ) echo "_widgetHash=$_widgetHash" -_widgetStableHash=$( curl -s https://raw.githubusercontent.com/flutter/flutter/stable/packages/flutter/lib/src/widgets/basic.dart | openssl md5 ) +_widgetStableHash=$( curl -s https://github.com/flutter/flutter/raw/refs/heads/stable/packages/flutter/lib/src/widgets/basic.dart | openssl md5 ) echo "_widgetStableHash=$_widgetStableHash" if [ "$_widgetHash" != "$_widgetStableHash" ]; then echo "Widget hashes are different" exit 1 fi -_renderObjectHash=$( curl -s https://raw.githubusercontent.com/flutter/flutter/60d28ad/packages/flutter/lib/src/rendering/flex.dart | openssl md5 ) +_renderObjectHash=$( curl -s https://github.com/flutter/flutter/raw/35c388a/packages/flutter/lib/src/rendering/flex.dart | openssl md5 ) echo "_renderObjectHash=$_renderObjectHash" -_renderObjectStableHash=$( curl -s https://raw.githubusercontent.com/flutter/flutter/stable/packages/flutter/lib/src/rendering/flex.dart | openssl md5 ) +_renderObjectStableHash=$( curl -s https://github.com/flutter/flutter/raw/refs/heads/stable/packages/flutter/lib/src/rendering/flex.dart | openssl md5 ) echo "_renderObjectStableHash=$_renderObjectStableHash" if [ "$_renderObjectHash" != "$_renderObjectStableHash" ]; then echo "RenderObject hashes are different" @@ -32,6 +32,18 @@ import 'package:flutter/widgets.dart' show BuildContext, Directionality, MultiChildRenderObjectWidget; class HtmlFlex extends MultiChildRenderObjectWidget { + /// Creates a flex layout. + /// + /// The [direction] is required. + /// + /// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then + /// [textBaseline] must not be null. + /// + /// The [textDirection] argument defaults to the ambient [Directionality], if + /// any. If there is no ambient directionality, and a text direction is going + /// to be necessary to decide which direction to lay the children in or to + /// disambiguate `start` or `end` values for the main or cross axis + /// directions, the [textDirection] must not be null. const HtmlFlex({ super.key, required this.direction, @@ -42,6 +54,7 @@ class HtmlFlex extends MultiChildRenderObjectWidget { this.verticalDirection = VerticalDirection.down, this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be this.clipBehavior = Clip.none, + this.spacing = 0.0, super.children, }) : assert( !identical(crossAxisAlignment, CrossAxisAlignment.baseline) || @@ -50,22 +63,111 @@ class HtmlFlex extends MultiChildRenderObjectWidget { ); // Cannot use == in the assert above instead of identical because of https://github.com/dart-lang/language/issues/1811. + /// The direction to use as the main axis. + /// + /// If you know the axis in advance, then consider using a [Row] (if it's + /// horizontal) or [Column] (if it's vertical) instead of a [Flex], since that + /// will be less verbose. (For [Row] and [Column] this property is fixed to + /// the appropriate axis.) final Axis direction; + /// How the children should be placed along the main axis. + /// + /// For example, [MainAxisAlignment.start], the default, places the children + /// at the start (i.e., the left for a [Row] or the top for a [Column]) of the + /// main axis. final MainAxisAlignment mainAxisAlignment; + /// How much space should be occupied in the main axis. + /// + /// After allocating space to children, there might be some remaining free + /// space. This value controls whether to maximize or minimize the amount of + /// free space, subject to the incoming layout constraints. + /// + /// If some children have a non-zero flex factors (and none have a fit of + /// [FlexFit.loose]), they will expand to consume all the available space and + /// there will be no remaining free space to maximize or minimize, making this + /// value irrelevant to the final layout. final MainAxisSize mainAxisSize; + /// How the children should be placed along the cross axis. + /// + /// For example, [CrossAxisAlignment.center], the default, centers the + /// children in the cross axis (e.g., horizontally for a [Column]). + /// + /// When the cross axis is vertical (as for a [Row]) and the children + /// contain text, consider using [CrossAxisAlignment.baseline] instead. + /// This typically produces better visual results if the different children + /// have text with different font metrics, for example because they differ in + /// [TextStyle.fontSize] or other [TextStyle] properties, or because + /// they use different fonts due to being written in different scripts. final CrossAxisAlignment crossAxisAlignment; + /// Determines the order to lay children out horizontally and how to interpret + /// `start` and `end` in the horizontal direction. + /// + /// Defaults to the ambient [Directionality]. + /// + /// If [textDirection] is [TextDirection.rtl], then the direction in which + /// text flows starts from right to left. Otherwise, if [textDirection] is + /// [TextDirection.ltr], then the direction in which text flows starts from + /// left to right. + /// + /// If the [direction] is [Axis.horizontal], this controls the order in which + /// the children are positioned (left-to-right or right-to-left), and the + /// meaning of the [mainAxisAlignment] property's [MainAxisAlignment.start] and + /// [MainAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.horizontal], and either the + /// [mainAxisAlignment] is either [MainAxisAlignment.start] or + /// [MainAxisAlignment.end], or there's more than one child, then the + /// [textDirection] (or the ambient [Directionality]) must not be null. + /// + /// If the [direction] is [Axis.vertical], this controls the meaning of the + /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and + /// [CrossAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [textDirection] (or the ambient [Directionality]) must not be null. final TextDirection? textDirection; + /// Determines the order to lay children out vertically and how to interpret + /// `start` and `end` in the vertical direction. + /// + /// Defaults to [VerticalDirection.down]. + /// + /// If the [direction] is [Axis.vertical], this controls which order children + /// are painted in (down or up), the meaning of the [mainAxisAlignment] + /// property's [MainAxisAlignment.start] and [MainAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.vertical], and either the [mainAxisAlignment] + /// is either [MainAxisAlignment.start] or [MainAxisAlignment.end], or there's + /// more than one child, then the [verticalDirection] must not be null. + /// + /// If the [direction] is [Axis.horizontal], this controls the meaning of the + /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and + /// [CrossAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [verticalDirection] must not be null. final VerticalDirection verticalDirection; + /// If aligning items according to their baseline, which baseline to use. + /// + /// This must be set if using baseline alignment. There is no default because there is no + /// way for the framework to know the correct baseline _a priori_. final TextBaseline? textBaseline; + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.none]. final Clip clipBehavior; + /// {@macro flutter.rendering.RenderFlex.spacing} + final double spacing; + bool get _needTextDirection { switch (direction) { case Axis.horizontal: @@ -76,14 +178,30 @@ class HtmlFlex extends MultiChildRenderObjectWidget { } } + /// The value to pass to [RenderFlex.textDirection]. + /// + /// This value is derived from the [textDirection] property and the ambient + /// [Directionality]. The value is null if there is no need to specify the + /// text direction. In practice there's always a need to specify the direction + /// except for vertical flexes (e.g. [Column]s) whose [crossAxisAlignment] is + /// not dependent on the text direction (not `start` or `end`). In particular, + /// a [Row] always needs a text direction because the text direction controls + /// its layout order. (For [Column]s, the layout order is controlled by + /// [verticalDirection], which is always specified as it does not depend on an + /// inherited widget and defaults to [VerticalDirection.down].) + /// + /// This method exists so that subclasses of [Flex] that create their own + /// render objects that are derived from [RenderFlex] can do so and still use + /// the logic for providing a text direction only when it is necessary. + @protected TextDirection? getEffectiveTextDirection(BuildContext context) { return textDirection ?? (_needTextDirection ? Directionality.maybeOf(context) : null); } @override - RenderObject createRenderObject(BuildContext context) { - return _HtmlFlexRenderObject( + RenderHtmlFlex createRenderObject(BuildContext context) { + return RenderHtmlFlex( direction: direction, mainAxisAlignment: mainAxisAlignment, mainAxisSize: mainAxisSize, @@ -92,15 +210,14 @@ class HtmlFlex extends MultiChildRenderObjectWidget { verticalDirection: verticalDirection, textBaseline: textBaseline, clipBehavior: clipBehavior, + spacing: spacing, ); } @override void updateRenderObject( BuildContext context, - // TODO: rewrite HtmlFlex and get rid of this render object - // ignore: library_private_types_in_public_api - covariant _HtmlFlexRenderObject renderObject, + covariant RenderHtmlFlex renderObject, ) { renderObject ..direction = direction @@ -110,7 +227,8 @@ class HtmlFlex extends MultiChildRenderObjectWidget { ..textDirection = getEffectiveTextDirection(context) ..verticalDirection = verticalDirection ..textBaseline = textBaseline - ..clipBehavior = clipBehavior; + ..clipBehavior = clipBehavior + ..spacing = spacing; } @override @@ -157,38 +275,168 @@ class HtmlFlex extends MultiChildRenderObjectWidget { defaultValue: null, ), ); + properties.add( + EnumProperty( + 'clipBehavior', + clipBehavior, + defaultValue: Clip.none, + ), + ); + properties.add(DoubleProperty('spacing', spacing, defaultValue: 0.0)); } } -bool? _startIsTopLeft( - Axis direction, - TextDirection? textDirection, - VerticalDirection? verticalDirection, -) { - // If the relevant value of textDirection or verticalDirection is null, this returns null too. - switch (direction) { - case Axis.horizontal: - switch (textDirection) { - case TextDirection.ltr: - return true; - case TextDirection.rtl: - return false; - case null: - return null; - } - case Axis.vertical: - switch (verticalDirection) { - case VerticalDirection.down: - return true; - case VerticalDirection.up: - return false; - case null: - return null; - } +extension type const _AxisSize._(Size _size) { + _AxisSize({required double mainAxisExtent, required double crossAxisExtent}) + : this._(Size(mainAxisExtent, crossAxisExtent)); + _AxisSize.fromSize({required Size size, required Axis direction}) + : this._(_convert(size, direction)); + + static const _AxisSize empty = _AxisSize._(Size.zero); + + static Size _convert(Size size, Axis direction) { + return switch (direction) { + Axis.horizontal => size, + Axis.vertical => size.flipped, + }; + } + + double get mainAxisExtent => _size.width; + double get crossAxisExtent => _size.height; + + Size toSize(Axis direction) => _convert(_size, direction); + + _AxisSize applyConstraints(BoxConstraints constraints, Axis direction) { + final BoxConstraints effectiveConstraints = switch (direction) { + Axis.horizontal => constraints, + Axis.vertical => constraints.flipped, + }; + return _AxisSize._(effectiveConstraints.constrain(_size)); + } + + _AxisSize operator +(_AxisSize other) => _AxisSize._( + Size( + _size.width + other._size.width, + math.max(_size.height, other._size.height), + ), + ); +} + +extension type const _AscentDescent._( + (double ascent, double descent)? ascentDescent) { + factory _AscentDescent({ + required double? baselineOffset, + required double crossSize, + }) { + return baselineOffset == null + ? none + : _AscentDescent._((baselineOffset, crossSize - baselineOffset)); + } + static const _AscentDescent none = _AscentDescent._(null); + + double? get baselineOffset => ascentDescent?.$1; + + _AscentDescent operator +(_AscentDescent other) => switch ((this, other)) { + (null, final _AscentDescent v) || (final _AscentDescent v, null) => v, + ( + (final double xAscent, final double xDescent), + (final double yAscent, final double yDescent), + ) => + _AscentDescent._( + (math.max(xAscent, yAscent), math.max(xDescent, yDescent)), + ), + }; +} + +class _LayoutSizes { + _LayoutSizes({ + required this.axisSize, + required this.baselineOffset, + required this.mainAxisFreeSpace, + required this.spacePerFlex, + }) : assert(spacePerFlex?.isFinite ?? true); + + // The final constrained _AxisSize of the RenderFlex. + final _AxisSize axisSize; + + // The free space along the main axis. If the value is positive, the free space + // will be distributed according to the [MainAxisAlignment] specified. A + // negative value indicates the RenderFlex overflows along the main axis. + final double mainAxisFreeSpace; + + // Null if the RenderFlex is not baseline aligned, or none of its children has + // a valid baseline of the given [TextBaseline] type. + final double? baselineOffset; + + // The allocated space for flex children. + final double? spacePerFlex; +} + +extension on MainAxisAlignment { + (double leadingSpace, double betweenSpace) _distributeSpace( + double freeSpace, + int itemCount, + bool flipped, + double spacing, + ) { + assert(itemCount >= 0); + return switch (this) { + MainAxisAlignment.start => + flipped ? (freeSpace, spacing) : (0.0, spacing), + MainAxisAlignment.end => MainAxisAlignment.start._distributeSpace( + freeSpace, + itemCount, + !flipped, + spacing, + ), + MainAxisAlignment.spaceBetween when itemCount < 2 => + MainAxisAlignment.start._distributeSpace( + freeSpace, + itemCount, + flipped, + spacing, + ), + MainAxisAlignment.spaceAround when itemCount == 0 => + MainAxisAlignment.start._distributeSpace( + freeSpace, + itemCount, + flipped, + spacing, + ), + MainAxisAlignment.center => (freeSpace / 2.0, spacing), + MainAxisAlignment.spaceBetween => ( + 0.0, + freeSpace / (itemCount - 1) + spacing + ), + MainAxisAlignment.spaceAround => ( + freeSpace / itemCount / 2, + freeSpace / itemCount + spacing + ), + MainAxisAlignment.spaceEvenly => ( + freeSpace / (itemCount + 1), + freeSpace / (itemCount + 1) + spacing, + ), + }; + } +} + +extension on CrossAxisAlignment { + double _getChildCrossAxisOffset(double freeSpace, bool flipped) { + // This method should not be used to position baseline-aligned children. + return switch (this) { + CrossAxisAlignment.stretch || CrossAxisAlignment.baseline => 0.0, + CrossAxisAlignment.start => flipped ? freeSpace : 0.0, + CrossAxisAlignment.center => freeSpace / 2, + CrossAxisAlignment.end => + CrossAxisAlignment.start._getChildCrossAxisOffset( + freeSpace, + !flipped, + ), + }; } } -class _HtmlFlexRenderObject extends RenderBox +class RenderHtmlFlex extends RenderBox with ContainerRenderObjectMixin, RenderBoxContainerDefaultsMixin, @@ -197,7 +445,7 @@ class _HtmlFlexRenderObject extends RenderBox /// /// By default, the flex layout is horizontal and children are aligned to the /// start of the main axis and the center of the cross axis. - _HtmlFlexRenderObject({ + RenderHtmlFlex({ List? children, Axis direction = Axis.horizontal, MainAxisSize mainAxisSize = MainAxisSize.max, @@ -207,6 +455,7 @@ class _HtmlFlexRenderObject extends RenderBox VerticalDirection verticalDirection = VerticalDirection.down, TextBaseline? textBaseline, Clip clipBehavior = Clip.none, + double spacing = 0.0, }) : _direction = direction, _mainAxisAlignment = mainAxisAlignment, _mainAxisSize = mainAxisSize, @@ -214,10 +463,13 @@ class _HtmlFlexRenderObject extends RenderBox _textDirection = textDirection, _verticalDirection = verticalDirection, _textBaseline = textBaseline, - _clipBehavior = clipBehavior { + _clipBehavior = clipBehavior, + _spacing = spacing, + assert(spacing >= 0.0) { addAll(children); } + /// The direction to use as the main axis. Axis get direction => _direction; Axis _direction; set direction(Axis value) { @@ -227,6 +479,15 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// How the children should be placed along the main axis. + /// + /// If the [direction] is [Axis.horizontal], and the [mainAxisAlignment] is + /// either [MainAxisAlignment.start] or [MainAxisAlignment.end], then the + /// [textDirection] must not be null. + /// + /// If the [direction] is [Axis.vertical], and the [mainAxisAlignment] is + /// either [MainAxisAlignment.start] or [MainAxisAlignment.end], then the + /// [verticalDirection] must not be null. MainAxisAlignment get mainAxisAlignment => _mainAxisAlignment; MainAxisAlignment _mainAxisAlignment; set mainAxisAlignment(MainAxisAlignment value) { @@ -236,6 +497,16 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// How much space should be occupied in the main axis. + /// + /// After allocating space to children, there might be some remaining free + /// space. This value controls whether to maximize or minimize the amount of + /// free space, subject to the incoming layout constraints. + /// + /// If some children have a non-zero flex factors (and none have a fit of + /// [FlexFit.loose]), they will expand to consume all the available space and + /// there will be no remaining free space to maximize or minimize, making this + /// value irrelevant to the final layout. MainAxisSize get mainAxisSize => _mainAxisSize; MainAxisSize _mainAxisSize; set mainAxisSize(MainAxisSize value) { @@ -245,6 +516,15 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// How the children should be placed along the cross axis. + /// + /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [verticalDirection] must not be null. + /// + /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [textDirection] must not be null. CrossAxisAlignment get crossAxisAlignment => _crossAxisAlignment; CrossAxisAlignment _crossAxisAlignment; set crossAxisAlignment(CrossAxisAlignment value) { @@ -254,6 +534,26 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// Determines the order to lay children out horizontally and how to interpret + /// `start` and `end` in the horizontal direction. + /// + /// If the [direction] is [Axis.horizontal], this controls the order in which + /// children are positioned (left-to-right or right-to-left), and the meaning + /// of the [mainAxisAlignment] property's [MainAxisAlignment.start] and + /// [MainAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.horizontal], and either the + /// [mainAxisAlignment] is either [MainAxisAlignment.start] or + /// [MainAxisAlignment.end], or there's more than one child, then the + /// [textDirection] must not be null. + /// + /// If the [direction] is [Axis.vertical], this controls the meaning of the + /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and + /// [CrossAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [textDirection] must not be null. TextDirection? get textDirection => _textDirection; TextDirection? _textDirection; set textDirection(TextDirection? value) { @@ -263,6 +563,24 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// Determines the order to lay children out vertically and how to interpret + /// `start` and `end` in the vertical direction. + /// + /// If the [direction] is [Axis.vertical], this controls which order children + /// are painted in (down or up), the meaning of the [mainAxisAlignment] + /// property's [MainAxisAlignment.start] and [MainAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.vertical], and either the [mainAxisAlignment] + /// is either [MainAxisAlignment.start] or [MainAxisAlignment.end], or there's + /// more than one child, then the [verticalDirection] must not be null. + /// + /// If the [direction] is [Axis.horizontal], this controls the meaning of the + /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and + /// [CrossAxisAlignment.end] values. + /// + /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is + /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the + /// [verticalDirection] must not be null. VerticalDirection get verticalDirection => _verticalDirection; VerticalDirection _verticalDirection; set verticalDirection(VerticalDirection value) { @@ -272,6 +590,9 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// If aligning items according to their baseline, which baseline to use. + /// + /// Must not be null if [crossAxisAlignment] is [CrossAxisAlignment.baseline]. TextBaseline? get textBaseline => _textBaseline; TextBaseline? _textBaseline; set textBaseline(TextBaseline? value) { @@ -283,6 +604,9 @@ class _HtmlFlexRenderObject extends RenderBox } bool get _debugHasNecessaryDirections { + if (RenderObject.debugCheckingIntrinsics) { + return true; + } if (firstChild != null && lastChild != firstChild) { // i.e. there's more than one child switch (direction) { @@ -328,6 +652,9 @@ class _HtmlFlexRenderObject extends RenderBox // are treated as not overflowing. bool get _hasOverflow => _overflow > precisionErrorTolerance; + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.none]. Clip get clipBehavior => _clipBehavior; Clip _clipBehavior = Clip.none; set clipBehavior(Clip value) { @@ -338,6 +665,69 @@ class _HtmlFlexRenderObject extends RenderBox } } + /// {@template flutter.rendering.RenderFlex.spacing} + /// How much space to place between children in the main axis. + /// + /// The spacing is only applied between children in the main axis. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is + /// [MainAxisAlignment.start], then the first child will be placed at the start + /// of the main axis, and the second child will be placed 10.0 pixels after + /// the first child in the main axis, and so on. The [spacing] is not applied + /// before the first child or after the last child. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.end], + /// then the last child will be placed at the end of the main axis, and the + /// second-to-last child will be placed 10.0 pixels before the last child in + /// the main axis, and so on. The [spacing] is not applied before the first + /// child or after the last child. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.center], + /// then the children will be placed in the center of the main axis with 10.0 + /// pixels of space between the children. The [spacing] is not applied before the first + /// child or after the last child. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], + /// then there will be a minimum of 10.0 pixels of space between each child in the + /// main axis. If the free space is 100.0 pixels between the two children, + /// then the minimum space between the children will be 10.0 pixels and the + /// remaining 90.0 pixels will be the free space between the children. The + /// [spacing] is not applied before the first child or after the last child. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceAround], + /// then there will be a minimum of 10.0 pixels of space between each child in the + /// main axis, and the remaining free space will be placed between the children as + /// well as before the first child and after the last child. The [spacing] is + /// not applied before the first child or after the last child. + /// + /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceEvenly], + /// then there will be a minimum of 10.0 pixels of space between each child in the + /// main axis, and the remaining free space will be evenly placed between the + /// children as well as before the first child and after the last child. The + /// [spacing] is not applied before the first child or after the last child. + /// + /// When the [spacing] is non-zero, the layout size will be larger than + /// the sum of the children's layout sizes in the main axis. + /// + /// When the total children's layout sizes and total spacing between the + /// children is greater than the maximum constraints in the main axis, then + /// the children will overflow. For example, if there are two children and the + /// maximum constraint is 100.0 pixels, the children's layout sizes are 50.0 + /// pixels each, and the spacing is 10.0 pixels, then the children will + /// overflow by 10.0 pixels. + /// + /// Defaults to 0.0. + /// {@endtemplate} + double get spacing => _spacing; + double _spacing; + set spacing(double value) { + if (_spacing == value) { + return; + } + _spacing = value; + markNeedsLayout(); + } + @override void setupParentData(RenderBox child) { if (child.parentData is! FlexParentData) { @@ -345,47 +735,31 @@ class _HtmlFlexRenderObject extends RenderBox } } - bool get _canComputeIntrinsics => - crossAxisAlignment != CrossAxisAlignment.baseline; - double _getIntrinsicSize({ required Axis sizingDirection, required double - extent, // the extent in the direction that isn't the sizing direction + extent, // The extent in the direction that isn't the sizing direction. required double Function(RenderBox, double) - childSize, // a method to find the size in the sizing direction + childSize, // A method to find the size in the sizing direction. }) { - if (!_canComputeIntrinsics) { - // Intrinsics cannot be calculated without a full layout for - // baseline alignment. Throw an assertion and return 0.0 as documented - // on [RenderBox.computeMinIntrinsicWidth]. - assert( - RenderObject.debugCheckingIntrinsics, - 'Intrinsics are not available for CrossAxisAlignment.baseline.', - ); - return 0.0; - } if (_direction == sizingDirection) { // INTRINSIC MAIN SIZE // Intrinsic main size is the smallest size the flex container can take // while maintaining the min/max-content contributions of its flex items. double totalFlex = 0.0; - double inflexibleSpace = 0.0; + double inflexibleSpace = spacing * (childCount - 1); double maxFlexFractionSoFar = 0.0; - RenderBox? child = firstChild; - while (child != null) { + for (RenderBox? child = firstChild; + child != null; + child = childAfter(child)) { final int flex = _getFlex(child); totalFlex += flex; if (flex > 0) { - final double flexFraction = - childSize(child, extent) / _getFlex(child); + final double flexFraction = childSize(child, extent) / flex; maxFlexFractionSoFar = math.max(maxFlexFractionSoFar, flexFraction); } else { inflexibleSpace += childSize(child, extent); } - final FlexParentData childParentData = - child.parentData! as FlexParentData; - child = childParentData.nextSibling; } return maxFlexFractionSoFar * totalFlex + inflexibleSpace; } else { @@ -393,54 +767,36 @@ class _HtmlFlexRenderObject extends RenderBox // Intrinsic cross size is the max of the intrinsic cross sizes of the // children, after the flexible children are fit into the available space, // with the children sized using their max intrinsic dimensions. - - // Get inflexible space using the max intrinsic dimensions of fixed children in the main direction. - final double availableMainSpace = extent; - int totalFlex = 0; - double inflexibleSpace = 0.0; - double maxCrossSize = 0.0; - RenderBox? child = firstChild; - while (child != null) { - final int flex = _getFlex(child); - totalFlex += flex; - late final double mainSize; - late final double crossSize; - if (flex == 0) { - switch (_direction) { - case Axis.horizontal: - mainSize = child.getMaxIntrinsicWidth(double.infinity); - crossSize = childSize(child, mainSize); - case Axis.vertical: - mainSize = child.getMaxIntrinsicHeight(double.infinity); - crossSize = childSize(child, mainSize); - } - inflexibleSpace += mainSize; - maxCrossSize = math.max(maxCrossSize, crossSize); - } - final FlexParentData childParentData = - child.parentData! as FlexParentData; - child = childParentData.nextSibling; - } - - // Determine the spacePerFlex by allocating the remaining available space. - // When you're overconstrained spacePerFlex can be negative. - final double spacePerFlex = - math.max(0.0, (availableMainSpace - inflexibleSpace) / totalFlex); - - // Size remaining (flexible) items, find the maximum cross size. - child = firstChild; - while (child != null) { - final int flex = _getFlex(child); - if (flex > 0) { - maxCrossSize = - math.max(maxCrossSize, childSize(child, spacePerFlex * flex)); - } - final FlexParentData childParentData = - child.parentData! as FlexParentData; - child = childParentData.nextSibling; + final bool isHorizontal = switch (direction) { + Axis.horizontal => true, + Axis.vertical => false, + }; + + Size layoutChild(RenderBox child, BoxConstraints constraints) { + final double mainAxisSizeFromConstraints = + isHorizontal ? constraints.maxWidth : constraints.maxHeight; + // A infinite mainAxisSizeFromConstraints means this child is flexible (or extent is double.infinity). + assert( + (_getFlex(child) != 0 && extent.isFinite) == + mainAxisSizeFromConstraints.isFinite, + ); + final double maxMainAxisSize = mainAxisSizeFromConstraints.isFinite + ? mainAxisSizeFromConstraints + : (isHorizontal + ? child.getMaxIntrinsicWidth(double.infinity) + : child.getMaxIntrinsicHeight(double.infinity)); + return isHorizontal + ? Size(maxMainAxisSize, childSize(child, maxMainAxisSize)) + : Size(childSize(child, maxMainAxisSize), maxMainAxisSize); } - return maxCrossSize; + return _computeSizes( + constraints: isHorizontal + ? BoxConstraints(maxWidth: extent) + : BoxConstraints(maxHeight: extent), + layoutChild: layoutChild, + getBaseline: ChildLayoutHelper.getDryBaseline, + ).axisSize.crossAxisExtent; } } @@ -486,52 +842,215 @@ class _HtmlFlexRenderObject extends RenderBox @override double? computeDistanceToActualBaseline(TextBaseline baseline) { - if (_direction == Axis.horizontal) { - return defaultComputeDistanceToHighestActualBaseline(baseline); - } - return defaultComputeDistanceToFirstActualBaseline(baseline); + return switch (_direction) { + Axis.horizontal => + defaultComputeDistanceToHighestActualBaseline(baseline), + Axis.vertical => defaultComputeDistanceToFirstActualBaseline(baseline), + }; } - int _getFlex(RenderBox child) { + static int _getFlex(RenderBox child) { final FlexParentData childParentData = child.parentData! as FlexParentData; return childParentData.flex ?? 0; } - FlexFit _getFit(RenderBox child) { + static FlexFit _getFit(RenderBox child) { final FlexParentData childParentData = child.parentData! as FlexParentData; return childParentData.fit ?? FlexFit.tight; } + bool get _isBaselineAligned { + return switch (crossAxisAlignment) { + CrossAxisAlignment.baseline => switch (direction) { + Axis.horizontal => true, + Axis.vertical => false, + }, + CrossAxisAlignment.start || + CrossAxisAlignment.center || + CrossAxisAlignment.end || + CrossAxisAlignment.stretch => + false, + }; + } + double _getCrossSize(Size size) { - switch (_direction) { - case Axis.horizontal: - return size.height; - case Axis.vertical: - return size.width; - } + return switch (_direction) { + Axis.horizontal => size.height, + Axis.vertical => size.width, + }; } double _getMainSize(Size size) { - switch (_direction) { - case Axis.horizontal: - return size.width; + return switch (_direction) { + Axis.horizontal => size.width, + Axis.vertical => size.height, + }; + } + + // flipMainAxis is used to decide whether to lay out + // left-to-right/top-to-bottom (false), or right-to-left/bottom-to-top + // (true). Returns false in cases when the layout direction does not matter + // (for instance, there is no child). + bool get _flipMainAxis => + firstChild != null && + switch (direction) { + Axis.horizontal => switch (textDirection) { + null || TextDirection.ltr => false, + TextDirection.rtl => true, + }, + Axis.vertical => switch (verticalDirection) { + VerticalDirection.down => false, + VerticalDirection.up => true, + }, + }; + + bool get _flipCrossAxis => + firstChild != null && + switch (direction) { + Axis.vertical => switch (textDirection) { + null || TextDirection.ltr => false, + TextDirection.rtl => true, + }, + Axis.horizontal => switch (verticalDirection) { + VerticalDirection.down => false, + VerticalDirection.up => true, + }, + }; + + BoxConstraints _constraintsForNonFlexChild(BoxConstraints constraints) { + final bool fillCrossAxis = switch (crossAxisAlignment) { + CrossAxisAlignment.stretch => true, + CrossAxisAlignment.start || + CrossAxisAlignment.center || + CrossAxisAlignment.end || + CrossAxisAlignment.baseline => + false, + }; + return switch (_direction) { + Axis.horizontal => fillCrossAxis + ? BoxConstraints.tightFor(height: constraints.maxHeight) + : BoxConstraints(maxHeight: constraints.maxHeight), + Axis.vertical => fillCrossAxis + ? BoxConstraints.tightFor(width: constraints.maxWidth) + : BoxConstraints(maxWidth: constraints.maxWidth), + }; + } + + BoxConstraints _constraintsForFlexChild( + RenderBox child, + BoxConstraints constraints, + double maxChildExtent, + ) { + assert(_getFlex(child) > 0.0); + assert(maxChildExtent >= 0.0); + final double minChildExtent = switch (_getFit(child)) { + FlexFit.tight => maxChildExtent, + FlexFit.loose => 0.0, + }; + final bool fillCrossAxis = switch (crossAxisAlignment) { + CrossAxisAlignment.stretch => true, + CrossAxisAlignment.start || + CrossAxisAlignment.center || + CrossAxisAlignment.end || + CrossAxisAlignment.baseline => + false, + }; + return switch (_direction) { + Axis.horizontal => BoxConstraints( + minWidth: minChildExtent, + maxWidth: maxChildExtent, + minHeight: fillCrossAxis ? constraints.maxHeight : 0.0, + maxHeight: constraints.maxHeight, + ), + Axis.vertical => BoxConstraints( + minWidth: fillCrossAxis ? constraints.maxWidth : 0.0, + maxWidth: constraints.maxWidth, + minHeight: minChildExtent, + maxHeight: maxChildExtent, + ), + }; + } + + @override + double? computeDryBaseline( + BoxConstraints constraints, + TextBaseline baseline, + ) { + final _LayoutSizes sizes = _computeSizes( + constraints: constraints, + layoutChild: ChildLayoutHelper.dryLayoutChild, + getBaseline: ChildLayoutHelper.getDryBaseline, + ); + + if (_isBaselineAligned) { + return sizes.baselineOffset; + } + + final BoxConstraints nonFlexConstraints = + _constraintsForNonFlexChild(constraints); + BoxConstraints constraintsForChild(RenderBox child) { + final double? spacePerFlex = sizes.spacePerFlex; + final int flex; + return spacePerFlex != null && (flex = _getFlex(child)) > 0 + ? _constraintsForFlexChild(child, constraints, flex * spacePerFlex) + : nonFlexConstraints; + } + + BaselineOffset baselineOffset = BaselineOffset.noBaseline; + switch (direction) { case Axis.vertical: - return size.height; + final double freeSpace = math.max(0.0, sizes.mainAxisFreeSpace); + final bool flipMainAxis = _flipMainAxis; + final (double leadingSpaceY, double spaceBetween) = + mainAxisAlignment._distributeSpace( + freeSpace, + childCount, + flipMainAxis, + spacing, + ); + 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); + 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; + for (RenderBox? child = firstChild; + child != null; + child = childAfter(child)) { + final BoxConstraints childConstraints = constraintsForChild(child); + final BaselineOffset distance = BaselineOffset( + child.getDryBaseline(childConstraints, baseline), + ); + final double freeCrossAxisSpace = sizes.axisSize.crossAxisExtent - + child.getDryLayout(childConstraints).height; + final BaselineOffset childBaseline = distance + + crossAxisAlignment._getChildCrossAxisOffset( + freeCrossAxisSpace, + flipCrossAxis, + ); + baselineOffset = baselineOffset.minOf(childBaseline); + } } + return baselineOffset.offset; } @override @protected Size computeDryLayout(covariant BoxConstraints constraints) { - if (!_canComputeIntrinsics) { - assert( - debugCannotComputeDryLayout( - reason: - 'Dry layout cannot be computed for CrossAxisAlignment.baseline, which requires a full layout.', - ), - ); - return Size.zero; - } FlutterError? constraintsError; assert(() { constraintsError = _debugCheckConstraints( @@ -545,17 +1064,11 @@ class _HtmlFlexRenderObject extends RenderBox return Size.zero; } - final _LayoutSizes sizes = _computeSizes( - layoutChild: ChildLayoutHelper.dryLayoutChild, + return _computeSizes( constraints: constraints, - ); - - switch (_direction) { - case Axis.horizontal: - return constraints.constrain(Size(sizes.mainSize, sizes.crossSize)); - case Axis.vertical: - return constraints.constrain(Size(sizes.crossSize, sizes.mainSize)); - } + layoutChild: ChildLayoutHelper.dryLayoutChild, + getBaseline: ChildLayoutHelper.getDryBaseline, + ).axisSize.toSize(direction); } FlutterError? _debugCheckConstraints({ @@ -646,8 +1159,8 @@ class _HtmlFlexRenderObject extends RenderBox ), ErrorDescription( 'If this message did not help you determine the problem, consider using debugDumpRenderTree():\n' - ' https://flutter.dev/debugging/#rendering-layer\n' - ' http://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html', + ' https://flutter.dev/to/debug-render-layer\n' + ' https://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html', ), describeForError( 'The affected RenderFlex is', @@ -676,143 +1189,125 @@ class _HtmlFlexRenderObject extends RenderBox _LayoutSizes _computeSizes({ required BoxConstraints constraints, required ChildLayouter layoutChild, + required ChildBaselineGetter getBaseline, }) { assert(_debugHasNecessaryDirections); // Determine used flex factor, size inflexible items, calculate free space. - int totalFlex = 0; final double maxMainSize = _getMainSize(constraints.biggest); final bool canFlex = maxMainSize.isFinite; + final BoxConstraints nonFlexChildConstraints = + _constraintsForNonFlexChild(constraints); + // Null indicates the children are not baseline aligned. + final TextBaseline? textBaseline = _isBaselineAligned + ? (this.textBaseline ?? + (throw FlutterError( + 'To use CrossAxisAlignment.baseline, you must also specify which baseline to use using the "textBaseline" argument.', + ))) + : null; - double crossSize = 0.0; - double allocatedSize = - 0.0; // Sum of the sizes of the non-flexible children. - RenderBox? child = firstChild; - RenderBox? lastFlexChild; - final fwfhFlex = Expando(); - final bool stretched; - switch (crossAxisAlignment) { - case CrossAxisAlignment.start: - stretched = false; - case CrossAxisAlignment.center: - stretched = false; - case CrossAxisAlignment.end: - stretched = false; - case CrossAxisAlignment.baseline: - stretched = false; - case CrossAxisAlignment.stretch: - stretched = true; - } - while (child != null) { - final FlexParentData childParentData = - child.parentData! as FlexParentData; - final int flex = _getFlex(child); - if (flex > 0) { + // The first pass lays out non-flex children and computes total flex. + int totalFlex = 0; + RenderBox? firstFlexChild; + _AscentDescent accumulatedAscentDescent = _AscentDescent.none; + // Initially, accumulatedSize is the sum of the spaces between children in the main axis. + _AxisSize accumulatedSize = + _AxisSize._(Size(spacing * (childCount - 1), 0.0)); + for (RenderBox? child = firstChild; + child != null; + child = childAfter(child)) { + final int flex; + if (canFlex && (flex = _getFlex(child)) > 0) { totalFlex += flex; - lastFlexChild = child; + firstFlexChild ??= child; } else { - final BoxConstraints innerConstraints; - if (stretched) { - switch (_direction) { - case Axis.horizontal: - innerConstraints = - BoxConstraints.tightFor(height: constraints.maxHeight); - case Axis.vertical: - innerConstraints = - BoxConstraints.tightFor(width: constraints.maxWidth); - } - } else { - switch (_direction) { - case Axis.horizontal: - innerConstraints = - BoxConstraints(maxHeight: constraints.maxHeight); - case Axis.vertical: - innerConstraints = BoxConstraints(maxWidth: constraints.maxWidth); - } - } - final Size childSize = layoutChild(child, innerConstraints); - final childMainSize = _getMainSize(childSize); - if (canFlex && childMainSize > maxMainSize) { - final newFlex = (childMainSize - maxMainSize).toInt(); - fwfhFlex[child] = newFlex; - totalFlex += newFlex; - lastFlexChild = child; - } else { - allocatedSize += childMainSize; - crossSize = math.max(crossSize, _getCrossSize(childSize)); - } + final _AxisSize childSize = _AxisSize.fromSize( + size: layoutChild(child, nonFlexChildConstraints), + direction: direction, + ); + accumulatedSize += childSize; + // Baseline-aligned children contributes to the cross axis extent separately. + final double? baselineOffset = textBaseline == null + ? null + : getBaseline(child, nonFlexChildConstraints, textBaseline); + accumulatedAscentDescent += _AscentDescent( + baselineOffset: baselineOffset, + crossSize: childSize.crossAxisExtent, + ); } - assert(child.parentData == childParentData); - child = childParentData.nextSibling; } - // Distribute free space to flexible children. - final double freeSpace = - math.max(0.0, (canFlex ? maxMainSize : 0.0) - allocatedSize); - double allocatedFlexSpace = 0.0; - if (totalFlex > 0) { - final double spacePerFlex = - canFlex ? (freeSpace / totalFlex) : double.nan; - child = firstChild; - while (child != null) { - final int flex = fwfhFlex[child] ?? _getFlex(child); - if (flex > 0) { - final double maxChildExtent = canFlex - ? (child == lastFlexChild - ? (freeSpace - allocatedFlexSpace) - : spacePerFlex * flex) - : double.infinity; - late final double minChildExtent; - switch (_getFit(child)) { - case FlexFit.tight: - minChildExtent = maxChildExtent; - case FlexFit.loose: - minChildExtent = 0.0; - } - assert(minChildExtent.isFinite); - final double minCrossSize = - stretched ? _getCrossSize(constraints.biggest) : 0.0; - final BoxConstraints innerConstraints; - switch (_direction) { - case Axis.horizontal: - innerConstraints = constraints.copyWith( - minHeight: minCrossSize, - minWidth: minChildExtent, - maxWidth: maxChildExtent, - ); - case Axis.vertical: - innerConstraints = constraints.copyWith( - minWidth: minCrossSize, - minHeight: minChildExtent, - maxHeight: maxChildExtent, - ); - } - final Size childSize = layoutChild(child, innerConstraints); - final double childMainSize = _getMainSize(childSize); - assert(childMainSize <= maxChildExtent); - allocatedSize += childMainSize; - allocatedFlexSpace += maxChildExtent; - crossSize = math.max(crossSize, _getCrossSize(childSize)); - } - final FlexParentData childParentData = - child.parentData! as FlexParentData; - child = childParentData.nextSibling; + assert((totalFlex == 0) == (firstFlexChild == null)); + assert( + firstFlexChild == null || canFlex, + ); // If we are given infinite space there's no need for this extra step. + + // The second pass distributes free space to flexible children. + final double flexSpace = + math.max(0.0, maxMainSize - accumulatedSize.mainAxisExtent); + final double spacePerFlex = flexSpace / totalFlex; + for (RenderBox? child = firstFlexChild; + child != null && totalFlex > 0; + child = childAfter(child)) { + final int flex = _getFlex(child); + if (flex == 0) { + continue; } + totalFlex -= flex; + assert(spacePerFlex.isFinite); + final double maxChildExtent = spacePerFlex * flex; + assert( + _getFit(child) == FlexFit.loose || maxChildExtent < double.infinity, + ); + final BoxConstraints childConstraints = _constraintsForFlexChild( + child, + constraints, + maxChildExtent, + ); + final _AxisSize childSize = _AxisSize.fromSize( + size: layoutChild(child, childConstraints), + direction: direction, + ); + accumulatedSize += childSize; + final double? baselineOffset = textBaseline == null + ? null + : getBaseline(child, childConstraints, textBaseline); + accumulatedAscentDescent += _AscentDescent( + baselineOffset: baselineOffset, + crossSize: childSize.crossAxisExtent, + ); } + assert(totalFlex == 0); + + // The overall height of baseline-aligned children contributes to the cross axis extent. + accumulatedSize += switch (accumulatedAscentDescent) { + null => _AxisSize.empty, + (final double ascent, final double descent) => _AxisSize( + mainAxisExtent: 0, + crossAxisExtent: ascent + descent, + ), + }; + + final double idealMainSize = switch (mainAxisSize) { + MainAxisSize.max when maxMainSize.isFinite => maxMainSize, + MainAxisSize.max || MainAxisSize.min => accumulatedSize.mainAxisExtent, + }; - final double idealSize = canFlex && mainAxisSize == MainAxisSize.max - ? maxMainSize - : allocatedSize; + final _AxisSize constrainedSize = _AxisSize( + mainAxisExtent: idealMainSize, + crossAxisExtent: accumulatedSize.crossAxisExtent, + ).applyConstraints(constraints, direction); return _LayoutSizes( - mainSize: idealSize, - crossSize: crossSize, - allocatedSize: allocatedSize, + axisSize: constrainedSize, + mainAxisFreeSpace: + constrainedSize.mainAxisExtent - accumulatedSize.mainAxisExtent, + baselineOffset: accumulatedAscentDescent.baselineOffset, + spacePerFlex: firstFlexChild == null ? null : spacePerFlex, ); } @override void performLayout() { - assert(_debugHasNecessaryDirections); final BoxConstraints constraints = this.constraints; assert(() { final FlutterError? constraintsError = _debugCheckConstraints( @@ -826,166 +1321,60 @@ class _HtmlFlexRenderObject extends RenderBox }()); final _LayoutSizes sizes = _computeSizes( - layoutChild: ChildLayoutHelper.layoutChild, constraints: constraints, + layoutChild: ChildLayoutHelper.layoutChild, + getBaseline: ChildLayoutHelper.getBaseline, ); - final double allocatedSize = sizes.allocatedSize; - double actualSize = sizes.mainSize; - double crossSize = sizes.crossSize; - double maxBaselineDistance = 0.0; - if (crossAxisAlignment == CrossAxisAlignment.baseline) { - RenderBox? child = firstChild; - double maxSizeAboveBaseline = 0; - double maxSizeBelowBaseline = 0; - while (child != null) { - assert(() { - if (textBaseline == null) { - throw FlutterError( - 'To use CrossAxisAlignment.baseline, you must also specify which baseline to use using the "textBaseline" argument.', - ); - } - return true; - }()); - final double? distance = - child.getDistanceToBaseline(textBaseline!, onlyReal: true); - if (distance != null) { - maxBaselineDistance = math.max(maxBaselineDistance, distance); - maxSizeAboveBaseline = math.max( - distance, - maxSizeAboveBaseline, - ); - maxSizeBelowBaseline = math.max( - child.size.height - distance, - maxSizeBelowBaseline, - ); - crossSize = - math.max(maxSizeAboveBaseline + maxSizeBelowBaseline, crossSize); - } - final FlexParentData childParentData = - child.parentData! as FlexParentData; - child = childParentData.nextSibling; - } - } - - // Align items along the main axis. - switch (_direction) { - case Axis.horizontal: - size = constraints.constrain(Size(actualSize, crossSize)); - actualSize = size.width; - crossSize = size.height; - case Axis.vertical: - size = constraints.constrain(Size(crossSize, actualSize)); - actualSize = size.height; - crossSize = size.width; - } - final double actualSizeDelta = actualSize - allocatedSize; - _overflow = math.max(0.0, -actualSizeDelta); - final double remainingSpace = math.max(0.0, actualSizeDelta); - final double betweenSpace; - switch (_mainAxisAlignment) { - case MainAxisAlignment.start: - case MainAxisAlignment.end: - case MainAxisAlignment.center: - betweenSpace = 0.0; - case MainAxisAlignment.spaceBetween: - if (childCount > 1) { - betweenSpace = remainingSpace / (childCount - 1); - } else { - betweenSpace = 0.0; - } - case MainAxisAlignment.spaceAround: - if (childCount > 0) { - betweenSpace = remainingSpace / childCount; - } else { - betweenSpace = 0.0; - } - case MainAxisAlignment.spaceEvenly: - if (childCount > 0) { - betweenSpace = remainingSpace / (childCount + 1); - } else { - betweenSpace = 0.0; - } - } - final double leadingSpace; - switch (_mainAxisAlignment) { - case MainAxisAlignment.start: - leadingSpace = 0.0; - case MainAxisAlignment.end: - leadingSpace = remainingSpace; - case MainAxisAlignment.center: - leadingSpace = remainingSpace / 2.0; - case MainAxisAlignment.spaceBetween: - leadingSpace = 0.0; - case MainAxisAlignment.spaceAround: - leadingSpace = betweenSpace / 2.0; - case MainAxisAlignment.spaceEvenly: - leadingSpace = betweenSpace; - } + final double crossAxisExtent = sizes.axisSize.crossAxisExtent; + size = sizes.axisSize.toSize(direction); + _overflow = math.max(0.0, -sizes.mainAxisFreeSpace); + + final double remainingSpace = math.max(0.0, sizes.mainAxisFreeSpace); + final bool flipMainAxis = _flipMainAxis; + final bool flipCrossAxis = _flipCrossAxis; + final (double leadingSpace, double betweenSpace) = + mainAxisAlignment._distributeSpace( + remainingSpace, + childCount, + flipMainAxis, + spacing, + ); + final ( + RenderBox? Function(RenderBox child) nextChild, + RenderBox? topLeftChild + ) = flipMainAxis ? (childBefore, lastChild) : (childAfter, firstChild); + final double? baselineOffset = sizes.baselineOffset; + assert( + baselineOffset == null || + (crossAxisAlignment == CrossAxisAlignment.baseline && + direction == Axis.horizontal), + ); - // flipMainAxis is used to decide whether to lay out - // left-to-right/top-to-bottom (false), or right-to-left/bottom-to-top - // (true). The _startIsTopLeft will return null if there's only one child - // and the relevant direction is null, in which case we arbitrarily decide - // to flip, but that doesn't have any detectable effect. - final bool flipMainAxis = - !(_startIsTopLeft(direction, textDirection, verticalDirection) ?? true); - - // Position elements - double childMainPosition = - flipMainAxis ? actualSize - leadingSpace : leadingSpace; - RenderBox? child = firstChild; - while (child != null) { + // Position all children in visual order: starting from the top-left child and + // work towards the child that's farthest away from the origin. + double childMainPosition = leadingSpace; + for (RenderBox? child = topLeftChild; + child != null; + child = nextChild(child)) { + final double? childBaselineOffset; + final bool baselineAlign = baselineOffset != null && + (childBaselineOffset = + child.getDistanceToBaseline(textBaseline!, onlyReal: true)) != + null; + final double childCrossPosition = baselineAlign + ? baselineOffset - childBaselineOffset! + : crossAxisAlignment._getChildCrossAxisOffset( + crossAxisExtent - _getCrossSize(child.size), + flipCrossAxis, + ); final FlexParentData childParentData = child.parentData! as FlexParentData; - final double childCrossPosition; - switch (_crossAxisAlignment) { - case CrossAxisAlignment.start: - case CrossAxisAlignment.end: - childCrossPosition = _startIsTopLeft( - flipAxis(direction), - textDirection, - verticalDirection, - ) == - (_crossAxisAlignment == CrossAxisAlignment.start) - ? 0.0 - : crossSize - _getCrossSize(child.size); - case CrossAxisAlignment.center: - childCrossPosition = - crossSize / 2.0 - _getCrossSize(child.size) / 2.0; - case CrossAxisAlignment.stretch: - childCrossPosition = 0.0; - case CrossAxisAlignment.baseline: - if (_direction == Axis.horizontal) { - assert(textBaseline != null); - final double? distance = - child.getDistanceToBaseline(textBaseline!, onlyReal: true); - if (distance != null) { - childCrossPosition = maxBaselineDistance - distance; - } else { - childCrossPosition = 0.0; - } - } else { - childCrossPosition = 0.0; - } - } - if (flipMainAxis) { - childMainPosition -= _getMainSize(child.size); - } - switch (_direction) { - case Axis.horizontal: - childParentData.offset = - Offset(childMainPosition, childCrossPosition); - case Axis.vertical: - childParentData.offset = - Offset(childCrossPosition, childMainPosition); - } - if (flipMainAxis) { - childMainPosition -= betweenSpace; - } else { - childMainPosition += _getMainSize(child.size) + betweenSpace; - } - child = childParentData.nextSibling; + childParentData.offset = switch (direction) { + Axis.horizontal => Offset(childMainPosition, childCrossPosition), + Axis.vertical => Offset(childCrossPosition, childMainPosition), + }; + childMainPosition += _getMainSize(child.size) + betweenSpace; } } @@ -1042,15 +1431,10 @@ class _HtmlFlexRenderObject extends RenderBox // Simulate a child rect that overflows by the right amount. This child // rect is never used for drawing, just for determining the overflow // location and amount. - final Rect overflowChildRect; - switch (_direction) { - case Axis.horizontal: - overflowChildRect = - Rect.fromLTWH(0.0, 0.0, size.width + _overflow, 0.0); - case Axis.vertical: - overflowChildRect = - Rect.fromLTWH(0.0, 0.0, 0.0, size.height + _overflow); - } + final Rect overflowChildRect = switch (_direction) { + Axis.horizontal => Rect.fromLTWH(0.0, 0.0, size.width + _overflow, 0.0), + Axis.vertical => Rect.fromLTWH(0.0, 0.0, 0.0, size.height + _overflow), + }; paintOverflowIndicator( context, offset, @@ -1132,17 +1516,6 @@ class _HtmlFlexRenderObject extends RenderBox defaultValue: null, ), ); + properties.add(DoubleProperty('spacing', spacing, defaultValue: null)); } } - -class _LayoutSizes { - const _LayoutSizes({ - required this.mainSize, - required this.crossSize, - required this.allocatedSize, - }); - - final double mainSize; - final double crossSize; - final double allocatedSize; -} diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index b885e05ae..5967828bd 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -4,8 +4,8 @@ description: Flutter package to render html as widgets that focuses on correctne homepage: https://github.com/daohoangson/flutter_widget_from_html/tree/master/packages/core environment: - flutter: ">=3.10.0" - sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.19.0" + sdk: ">=3.3.0 <4.0.0" dependencies: csslib: ">=0.17.0 <2.0.0" From 6c6cd1959cbdf23c2595f17de21b807326c14de2 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 12:47:36 +0700 Subject: [PATCH 2/8] Remove comment by replacing regex ` //.*` with empty string --- packages/core/lib/src/widgets/html_flex.dart | 302 +------------------ 1 file changed, 11 insertions(+), 291 deletions(-) diff --git a/packages/core/lib/src/widgets/html_flex.dart b/packages/core/lib/src/widgets/html_flex.dart index 9f1d015b0..52bd8ccc6 100644 --- a/packages/core/lib/src/widgets/html_flex.dart +++ b/packages/core/lib/src/widgets/html_flex.dart @@ -32,18 +32,6 @@ import 'package:flutter/widgets.dart' show BuildContext, Directionality, MultiChildRenderObjectWidget; class HtmlFlex extends MultiChildRenderObjectWidget { - /// Creates a flex layout. - /// - /// The [direction] is required. - /// - /// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then - /// [textBaseline] must not be null. - /// - /// The [textDirection] argument defaults to the ambient [Directionality], if - /// any. If there is no ambient directionality, and a text direction is going - /// to be necessary to decide which direction to lay the children in or to - /// disambiguate `start` or `end` values for the main or cross axis - /// directions, the [textDirection] must not be null. const HtmlFlex({ super.key, required this.direction, @@ -52,7 +40,7 @@ class HtmlFlex extends MultiChildRenderObjectWidget { this.crossAxisAlignment = CrossAxisAlignment.center, this.textDirection, this.verticalDirection = VerticalDirection.down, - this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be + this.textBaseline, this.clipBehavior = Clip.none, this.spacing = 0.0, super.children, @@ -61,138 +49,35 @@ class HtmlFlex extends MultiChildRenderObjectWidget { textBaseline != null, 'textBaseline is required if you specify the crossAxisAlignment with CrossAxisAlignment.baseline', ); - // Cannot use == in the assert above instead of identical because of https://github.com/dart-lang/language/issues/1811. - - /// The direction to use as the main axis. - /// - /// If you know the axis in advance, then consider using a [Row] (if it's - /// horizontal) or [Column] (if it's vertical) instead of a [Flex], since that - /// will be less verbose. (For [Row] and [Column] this property is fixed to - /// the appropriate axis.) + final Axis direction; - /// How the children should be placed along the main axis. - /// - /// For example, [MainAxisAlignment.start], the default, places the children - /// at the start (i.e., the left for a [Row] or the top for a [Column]) of the - /// main axis. final MainAxisAlignment mainAxisAlignment; - /// How much space should be occupied in the main axis. - /// - /// After allocating space to children, there might be some remaining free - /// space. This value controls whether to maximize or minimize the amount of - /// free space, subject to the incoming layout constraints. - /// - /// If some children have a non-zero flex factors (and none have a fit of - /// [FlexFit.loose]), they will expand to consume all the available space and - /// there will be no remaining free space to maximize or minimize, making this - /// value irrelevant to the final layout. final MainAxisSize mainAxisSize; - /// How the children should be placed along the cross axis. - /// - /// For example, [CrossAxisAlignment.center], the default, centers the - /// children in the cross axis (e.g., horizontally for a [Column]). - /// - /// When the cross axis is vertical (as for a [Row]) and the children - /// contain text, consider using [CrossAxisAlignment.baseline] instead. - /// This typically produces better visual results if the different children - /// have text with different font metrics, for example because they differ in - /// [TextStyle.fontSize] or other [TextStyle] properties, or because - /// they use different fonts due to being written in different scripts. final CrossAxisAlignment crossAxisAlignment; - /// Determines the order to lay children out horizontally and how to interpret - /// `start` and `end` in the horizontal direction. - /// - /// Defaults to the ambient [Directionality]. - /// - /// If [textDirection] is [TextDirection.rtl], then the direction in which - /// text flows starts from right to left. Otherwise, if [textDirection] is - /// [TextDirection.ltr], then the direction in which text flows starts from - /// left to right. - /// - /// If the [direction] is [Axis.horizontal], this controls the order in which - /// the children are positioned (left-to-right or right-to-left), and the - /// meaning of the [mainAxisAlignment] property's [MainAxisAlignment.start] and - /// [MainAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.horizontal], and either the - /// [mainAxisAlignment] is either [MainAxisAlignment.start] or - /// [MainAxisAlignment.end], or there's more than one child, then the - /// [textDirection] (or the ambient [Directionality]) must not be null. - /// - /// If the [direction] is [Axis.vertical], this controls the meaning of the - /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and - /// [CrossAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [textDirection] (or the ambient [Directionality]) must not be null. final TextDirection? textDirection; - /// Determines the order to lay children out vertically and how to interpret - /// `start` and `end` in the vertical direction. - /// - /// Defaults to [VerticalDirection.down]. - /// - /// If the [direction] is [Axis.vertical], this controls which order children - /// are painted in (down or up), the meaning of the [mainAxisAlignment] - /// property's [MainAxisAlignment.start] and [MainAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.vertical], and either the [mainAxisAlignment] - /// is either [MainAxisAlignment.start] or [MainAxisAlignment.end], or there's - /// more than one child, then the [verticalDirection] must not be null. - /// - /// If the [direction] is [Axis.horizontal], this controls the meaning of the - /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and - /// [CrossAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [verticalDirection] must not be null. final VerticalDirection verticalDirection; - /// If aligning items according to their baseline, which baseline to use. - /// - /// This must be set if using baseline alignment. There is no default because there is no - /// way for the framework to know the correct baseline _a priori_. final TextBaseline? textBaseline; - /// {@macro flutter.material.Material.clipBehavior} - /// - /// Defaults to [Clip.none]. final Clip clipBehavior; - /// {@macro flutter.rendering.RenderFlex.spacing} final double spacing; bool get _needTextDirection { switch (direction) { case Axis.horizontal: - return true; // because it affects the layout order. + return true; case Axis.vertical: return crossAxisAlignment == CrossAxisAlignment.start || crossAxisAlignment == CrossAxisAlignment.end; } } - /// The value to pass to [RenderFlex.textDirection]. - /// - /// This value is derived from the [textDirection] property and the ambient - /// [Directionality]. The value is null if there is no need to specify the - /// text direction. In practice there's always a need to specify the direction - /// except for vertical flexes (e.g. [Column]s) whose [crossAxisAlignment] is - /// not dependent on the text direction (not `start` or `end`). In particular, - /// a [Row] always needs a text direction because the text direction controls - /// its layout order. (For [Column]s, the layout order is controlled by - /// [verticalDirection], which is always specified as it does not depend on an - /// inherited widget and defaults to [VerticalDirection.down].) - /// - /// This method exists so that subclasses of [Flex] that create their own - /// render objects that are derived from [RenderFlex] can do so and still use - /// the logic for providing a text direction only when it is necessary. @protected TextDirection? getEffectiveTextDirection(BuildContext context) { return textDirection ?? @@ -356,19 +241,12 @@ class _LayoutSizes { required this.spacePerFlex, }) : assert(spacePerFlex?.isFinite ?? true); - // The final constrained _AxisSize of the RenderFlex. final _AxisSize axisSize; - // The free space along the main axis. If the value is positive, the free space - // will be distributed according to the [MainAxisAlignment] specified. A - // negative value indicates the RenderFlex overflows along the main axis. final double mainAxisFreeSpace; - // Null if the RenderFlex is not baseline aligned, or none of its children has - // a valid baseline of the given [TextBaseline] type. final double? baselineOffset; - // The allocated space for flex children. final double? spacePerFlex; } @@ -422,7 +300,6 @@ extension on MainAxisAlignment { extension on CrossAxisAlignment { double _getChildCrossAxisOffset(double freeSpace, bool flipped) { - // This method should not be used to position baseline-aligned children. return switch (this) { CrossAxisAlignment.stretch || CrossAxisAlignment.baseline => 0.0, CrossAxisAlignment.start => flipped ? freeSpace : 0.0, @@ -441,10 +318,6 @@ class RenderHtmlFlex extends RenderBox ContainerRenderObjectMixin, RenderBoxContainerDefaultsMixin, DebugOverflowIndicatorMixin { - /// Creates a flex render object. - /// - /// By default, the flex layout is horizontal and children are aligned to the - /// start of the main axis and the center of the cross axis. RenderHtmlFlex({ List? children, Axis direction = Axis.horizontal, @@ -469,7 +342,6 @@ class RenderHtmlFlex extends RenderBox addAll(children); } - /// The direction to use as the main axis. Axis get direction => _direction; Axis _direction; set direction(Axis value) { @@ -479,15 +351,6 @@ class RenderHtmlFlex extends RenderBox } } - /// How the children should be placed along the main axis. - /// - /// If the [direction] is [Axis.horizontal], and the [mainAxisAlignment] is - /// either [MainAxisAlignment.start] or [MainAxisAlignment.end], then the - /// [textDirection] must not be null. - /// - /// If the [direction] is [Axis.vertical], and the [mainAxisAlignment] is - /// either [MainAxisAlignment.start] or [MainAxisAlignment.end], then the - /// [verticalDirection] must not be null. MainAxisAlignment get mainAxisAlignment => _mainAxisAlignment; MainAxisAlignment _mainAxisAlignment; set mainAxisAlignment(MainAxisAlignment value) { @@ -497,16 +360,6 @@ class RenderHtmlFlex extends RenderBox } } - /// How much space should be occupied in the main axis. - /// - /// After allocating space to children, there might be some remaining free - /// space. This value controls whether to maximize or minimize the amount of - /// free space, subject to the incoming layout constraints. - /// - /// If some children have a non-zero flex factors (and none have a fit of - /// [FlexFit.loose]), they will expand to consume all the available space and - /// there will be no remaining free space to maximize or minimize, making this - /// value irrelevant to the final layout. MainAxisSize get mainAxisSize => _mainAxisSize; MainAxisSize _mainAxisSize; set mainAxisSize(MainAxisSize value) { @@ -516,15 +369,6 @@ class RenderHtmlFlex extends RenderBox } } - /// How the children should be placed along the cross axis. - /// - /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [verticalDirection] must not be null. - /// - /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [textDirection] must not be null. CrossAxisAlignment get crossAxisAlignment => _crossAxisAlignment; CrossAxisAlignment _crossAxisAlignment; set crossAxisAlignment(CrossAxisAlignment value) { @@ -534,26 +378,6 @@ class RenderHtmlFlex extends RenderBox } } - /// Determines the order to lay children out horizontally and how to interpret - /// `start` and `end` in the horizontal direction. - /// - /// If the [direction] is [Axis.horizontal], this controls the order in which - /// children are positioned (left-to-right or right-to-left), and the meaning - /// of the [mainAxisAlignment] property's [MainAxisAlignment.start] and - /// [MainAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.horizontal], and either the - /// [mainAxisAlignment] is either [MainAxisAlignment.start] or - /// [MainAxisAlignment.end], or there's more than one child, then the - /// [textDirection] must not be null. - /// - /// If the [direction] is [Axis.vertical], this controls the meaning of the - /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and - /// [CrossAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [textDirection] must not be null. TextDirection? get textDirection => _textDirection; TextDirection? _textDirection; set textDirection(TextDirection? value) { @@ -563,24 +387,6 @@ class RenderHtmlFlex extends RenderBox } } - /// Determines the order to lay children out vertically and how to interpret - /// `start` and `end` in the vertical direction. - /// - /// If the [direction] is [Axis.vertical], this controls which order children - /// are painted in (down or up), the meaning of the [mainAxisAlignment] - /// property's [MainAxisAlignment.start] and [MainAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.vertical], and either the [mainAxisAlignment] - /// is either [MainAxisAlignment.start] or [MainAxisAlignment.end], or there's - /// more than one child, then the [verticalDirection] must not be null. - /// - /// If the [direction] is [Axis.horizontal], this controls the meaning of the - /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and - /// [CrossAxisAlignment.end] values. - /// - /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is - /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the - /// [verticalDirection] must not be null. VerticalDirection get verticalDirection => _verticalDirection; VerticalDirection _verticalDirection; set verticalDirection(VerticalDirection value) { @@ -590,9 +396,6 @@ class RenderHtmlFlex extends RenderBox } } - /// If aligning items according to their baseline, which baseline to use. - /// - /// Must not be null if [crossAxisAlignment] is [CrossAxisAlignment.baseline]. TextBaseline? get textBaseline => _textBaseline; TextBaseline? _textBaseline; set textBaseline(TextBaseline? value) { @@ -608,7 +411,6 @@ class RenderHtmlFlex extends RenderBox return true; } if (firstChild != null && lastChild != firstChild) { - // i.e. there's more than one child switch (direction) { case Axis.horizontal: assert( @@ -646,15 +448,10 @@ class RenderHtmlFlex extends RenderBox return true; } - // Set during layout if overflow occurred on the main axis. double _overflow = 0; - // Check whether any meaningful overflow is present. Values below an epsilon - // are treated as not overflowing. + bool get _hasOverflow => _overflow > precisionErrorTolerance; - /// {@macro flutter.material.Material.clipBehavior} - /// - /// Defaults to [Clip.none]. Clip get clipBehavior => _clipBehavior; Clip _clipBehavior = Clip.none; set clipBehavior(Clip value) { @@ -665,59 +462,6 @@ class RenderHtmlFlex extends RenderBox } } - /// {@template flutter.rendering.RenderFlex.spacing} - /// How much space to place between children in the main axis. - /// - /// The spacing is only applied between children in the main axis. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is - /// [MainAxisAlignment.start], then the first child will be placed at the start - /// of the main axis, and the second child will be placed 10.0 pixels after - /// the first child in the main axis, and so on. The [spacing] is not applied - /// before the first child or after the last child. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.end], - /// then the last child will be placed at the end of the main axis, and the - /// second-to-last child will be placed 10.0 pixels before the last child in - /// the main axis, and so on. The [spacing] is not applied before the first - /// child or after the last child. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.center], - /// then the children will be placed in the center of the main axis with 10.0 - /// pixels of space between the children. The [spacing] is not applied before the first - /// child or after the last child. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], - /// then there will be a minimum of 10.0 pixels of space between each child in the - /// main axis. If the free space is 100.0 pixels between the two children, - /// then the minimum space between the children will be 10.0 pixels and the - /// remaining 90.0 pixels will be the free space between the children. The - /// [spacing] is not applied before the first child or after the last child. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceAround], - /// then there will be a minimum of 10.0 pixels of space between each child in the - /// main axis, and the remaining free space will be placed between the children as - /// well as before the first child and after the last child. The [spacing] is - /// not applied before the first child or after the last child. - /// - /// If the [spacing] is 10.0 and the [mainAxisAlignment] is [MainAxisAlignment.spaceEvenly], - /// then there will be a minimum of 10.0 pixels of space between each child in the - /// main axis, and the remaining free space will be evenly placed between the - /// children as well as before the first child and after the last child. The - /// [spacing] is not applied before the first child or after the last child. - /// - /// When the [spacing] is non-zero, the layout size will be larger than - /// the sum of the children's layout sizes in the main axis. - /// - /// When the total children's layout sizes and total spacing between the - /// children is greater than the maximum constraints in the main axis, then - /// the children will overflow. For example, if there are two children and the - /// maximum constraint is 100.0 pixels, the children's layout sizes are 50.0 - /// pixels each, and the spacing is 10.0 pixels, then the children will - /// overflow by 10.0 pixels. - /// - /// Defaults to 0.0. - /// {@endtemplate} double get spacing => _spacing; double _spacing; set spacing(double value) { @@ -737,15 +481,10 @@ class RenderHtmlFlex extends RenderBox double _getIntrinsicSize({ required Axis sizingDirection, - required double - extent, // The extent in the direction that isn't the sizing direction. - required double Function(RenderBox, double) - childSize, // A method to find the size in the sizing direction. + required double extent, + required double Function(RenderBox, double) childSize, }) { if (_direction == sizingDirection) { - // INTRINSIC MAIN SIZE - // Intrinsic main size is the smallest size the flex container can take - // while maintaining the min/max-content contributions of its flex items. double totalFlex = 0.0; double inflexibleSpace = spacing * (childCount - 1); double maxFlexFractionSoFar = 0.0; @@ -763,10 +502,6 @@ class RenderHtmlFlex extends RenderBox } return maxFlexFractionSoFar * totalFlex + inflexibleSpace; } else { - // INTRINSIC CROSS SIZE - // Intrinsic cross size is the max of the intrinsic cross sizes of the - // children, after the flexible children are fit into the available space, - // with the children sized using their max intrinsic dimensions. final bool isHorizontal = switch (direction) { Axis.horizontal => true, Axis.vertical => false, @@ -775,7 +510,7 @@ class RenderHtmlFlex extends RenderBox Size layoutChild(RenderBox child, BoxConstraints constraints) { final double mainAxisSizeFromConstraints = isHorizontal ? constraints.maxWidth : constraints.maxHeight; - // A infinite mainAxisSizeFromConstraints means this child is flexible (or extent is double.infinity). + assert( (_getFlex(child) != 0 && extent.isFinite) == mainAxisSizeFromConstraints.isFinite, @@ -887,10 +622,6 @@ class RenderHtmlFlex extends RenderBox }; } - // flipMainAxis is used to decide whether to lay out - // left-to-right/top-to-bottom (false), or right-to-left/bottom-to-top - // (true). Returns false in cases when the layout direction does not matter - // (for instance, there is no child). bool get _flipMainAxis => firstChild != null && switch (direction) { @@ -1107,7 +838,6 @@ class RenderHtmlFlex extends RenderBox 'expand to fill the remaining space in the $axis direction.', ); if (reportParentConstraints) { - // Constraints of parents are unavailable in dry layout. RenderBox? node = this; switch (_direction) { case Axis.horizontal: @@ -1193,12 +923,11 @@ class RenderHtmlFlex extends RenderBox }) { assert(_debugHasNecessaryDirections); - // Determine used flex factor, size inflexible items, calculate free space. final double maxMainSize = _getMainSize(constraints.biggest); final bool canFlex = maxMainSize.isFinite; final BoxConstraints nonFlexChildConstraints = _constraintsForNonFlexChild(constraints); - // Null indicates the children are not baseline aligned. + final TextBaseline? textBaseline = _isBaselineAligned ? (this.textBaseline ?? (throw FlutterError( @@ -1206,11 +935,10 @@ class RenderHtmlFlex extends RenderBox ))) : null; - // The first pass lays out non-flex children and computes total flex. int totalFlex = 0; RenderBox? firstFlexChild; _AscentDescent accumulatedAscentDescent = _AscentDescent.none; - // Initially, accumulatedSize is the sum of the spaces between children in the main axis. + _AxisSize accumulatedSize = _AxisSize._(Size(spacing * (childCount - 1), 0.0)); for (RenderBox? child = firstChild; @@ -1226,7 +954,7 @@ class RenderHtmlFlex extends RenderBox direction: direction, ); accumulatedSize += childSize; - // Baseline-aligned children contributes to the cross axis extent separately. + final double? baselineOffset = textBaseline == null ? null : getBaseline(child, nonFlexChildConstraints, textBaseline); @@ -1240,9 +968,8 @@ class RenderHtmlFlex extends RenderBox assert((totalFlex == 0) == (firstFlexChild == null)); assert( firstFlexChild == null || canFlex, - ); // If we are given infinite space there's no need for this extra step. + ); - // The second pass distributes free space to flexible children. final double flexSpace = math.max(0.0, maxMainSize - accumulatedSize.mainAxisExtent); final double spacePerFlex = flexSpace / totalFlex; @@ -1279,7 +1006,6 @@ class RenderHtmlFlex extends RenderBox } assert(totalFlex == 0); - // The overall height of baseline-aligned children contributes to the cross axis extent. accumulatedSize += switch (accumulatedAscentDescent) { null => _AxisSize.empty, (final double ascent, final double descent) => _AxisSize( @@ -1351,8 +1077,6 @@ class RenderHtmlFlex extends RenderBox direction == Axis.horizontal), ); - // Position all children in visual order: starting from the top-left child and - // work towards the child that's farthest away from the origin. double childMainPosition = leadingSpace; for (RenderBox? child = topLeftChild; child != null; @@ -1390,7 +1114,6 @@ class RenderHtmlFlex extends RenderBox return; } - // There's no point in drawing the children if we're empty. if (size.isEmpty) { return; } @@ -1428,9 +1151,6 @@ class RenderHtmlFlex extends RenderBox ), ]; - // Simulate a child rect that overflows by the right amount. This child - // rect is never used for drawing, just for determining the overflow - // location and amount. final Rect overflowChildRect = switch (_direction) { Axis.horizontal => Rect.fromLTWH(0.0, 0.0, size.width + _overflow, 0.0), Axis.vertical => Rect.fromLTWH(0.0, 0.0, 0.0, size.height + _overflow), From 6b73b9e0d5ebf9c76266d6293ca5c90a413724f0 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 13:13:37 +0700 Subject: [PATCH 3/8] Convert extension type to regular class --- packages/core/lib/src/widgets/html_flex.dart | 34 ++++++++++++++------ packages/core/pubspec.yaml | 4 +-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/core/lib/src/widgets/html_flex.dart b/packages/core/lib/src/widgets/html_flex.dart index 52bd8ccc6..d26ee015e 100644 --- a/packages/core/lib/src/widgets/html_flex.dart +++ b/packages/core/lib/src/widgets/html_flex.dart @@ -171,11 +171,17 @@ class HtmlFlex extends MultiChildRenderObjectWidget { } } -extension type const _AxisSize._(Size _size) { +class _AxisSize { + final Size _size; + _AxisSize({required double mainAxisExtent, required double crossAxisExtent}) - : this._(Size(mainAxisExtent, crossAxisExtent)); - _AxisSize.fromSize({required Size size, required Axis direction}) - : this._(_convert(size, direction)); + : _size = Size(mainAxisExtent, crossAxisExtent); + + const _AxisSize._(this._size); + + factory _AxisSize.fromSize({required Size size, required Axis direction}) { + return _AxisSize._(_convert(size, direction)); + } static const _AxisSize empty = _AxisSize._(Size.zero); @@ -207,8 +213,11 @@ extension type const _AxisSize._(Size _size) { ); } -extension type const _AscentDescent._( - (double ascent, double descent)? ascentDescent) { +typedef _AscentDescentValue = (double ascent, double descent); + +class _AscentDescent { + final _AscentDescentValue? _value; + factory _AscentDescent({ required double? baselineOffset, required double crossSize, @@ -217,12 +226,17 @@ extension type const _AscentDescent._( ? none : _AscentDescent._((baselineOffset, crossSize - baselineOffset)); } + + const _AscentDescent._(this._value); + static const _AscentDescent none = _AscentDescent._(null); - double? get baselineOffset => ascentDescent?.$1; + double? get baselineOffset => _value?.$1; - _AscentDescent operator +(_AscentDescent other) => switch ((this, other)) { - (null, final _AscentDescent v) || (final _AscentDescent v, null) => v, + _AscentDescent operator +(_AscentDescent other) => + switch ((_value, other._value)) { + (final _AscentDescentValue? _, null) => this, + (null, final _AscentDescentValue? _) => other, ( (final double xAscent, final double xDescent), (final double yAscent, final double yDescent), @@ -1006,7 +1020,7 @@ class RenderHtmlFlex extends RenderBox } assert(totalFlex == 0); - accumulatedSize += switch (accumulatedAscentDescent) { + accumulatedSize += switch (accumulatedAscentDescent._value) { null => _AxisSize.empty, (final double ascent, final double descent) => _AxisSize( mainAxisExtent: 0, diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index 5967828bd..b885e05ae 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -4,8 +4,8 @@ description: Flutter package to render html as widgets that focuses on correctne homepage: https://github.com/daohoangson/flutter_widget_from_html/tree/master/packages/core environment: - flutter: ">=3.19.0" - sdk: ">=3.3.0 <4.0.0" + flutter: ">=3.10.0" + sdk: ">=3.0.0 <4.0.0" dependencies: csslib: ">=0.17.0 <2.0.0" From 3332bbb79db443af5f06f6ac4968fe62373bebb3 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 13:33:23 +0700 Subject: [PATCH 4/8] Flex a child widget if it's too wide (or tall) --- packages/core/lib/src/widgets/html_flex.dart | 34 ++++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/core/lib/src/widgets/html_flex.dart b/packages/core/lib/src/widgets/html_flex.dart index d26ee015e..b9f9294dd 100644 --- a/packages/core/lib/src/widgets/html_flex.dart +++ b/packages/core/lib/src/widgets/html_flex.dart @@ -598,9 +598,13 @@ class RenderHtmlFlex extends RenderBox }; } + static final _fwfhFlexByRenderBox = Expando(); + static int _getFlex(RenderBox child) { final FlexParentData childParentData = child.parentData! as FlexParentData; - return childParentData.flex ?? 0; + final fwfhFlex = _fwfhFlexByRenderBox[child] ?? 0; + final fwfhFlexOrNull = fwfhFlex > 0 ? fwfhFlex : null; + return fwfhFlexOrNull ?? childParentData.flex ?? 0; } static FlexFit _getFit(RenderBox child) { @@ -967,15 +971,25 @@ class RenderHtmlFlex extends RenderBox size: layoutChild(child, nonFlexChildConstraints), direction: direction, ); - accumulatedSize += childSize; - - final double? baselineOffset = textBaseline == null - ? null - : getBaseline(child, nonFlexChildConstraints, textBaseline); - accumulatedAscentDescent += _AscentDescent( - baselineOffset: baselineOffset, - crossSize: childSize.crossAxisExtent, - ); + + if (canFlex && childSize.mainAxisExtent > maxMainSize) { + // e.g. child is wider than available width -> flex it + final newFlex = (childSize.mainAxisExtent - maxMainSize).toInt(); + _fwfhFlexByRenderBox[child] = newFlex; + totalFlex += newFlex; + firstFlexChild ??= child; + } else { + _fwfhFlexByRenderBox[child] = -1; + accumulatedSize += childSize; + + final double? baselineOffset = textBaseline == null + ? null + : getBaseline(child, nonFlexChildConstraints, textBaseline); + accumulatedAscentDescent += _AscentDescent( + baselineOffset: baselineOffset, + crossSize: childSize.crossAxisExtent, + ); + } } } From 473f559739a7a8bd895c5788bba5e863ddecf4eb Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 13:53:00 +0700 Subject: [PATCH 5/8] Requires Flutter@3.22 --- packages/core/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index b885e05ae..f8d401159 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -4,8 +4,8 @@ description: Flutter package to render html as widgets that focuses on correctne homepage: https://github.com/daohoangson/flutter_widget_from_html/tree/master/packages/core environment: - flutter: ">=3.10.0" - sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.22.0" + sdk: ">=3.4.0 <4.0.0" dependencies: csslib: ">=0.17.0 <2.0.0" From ba99bd0e91aae79d5a20272f856c00cfc7076675 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 14:05:28 +0700 Subject: [PATCH 6/8] Avoid `ChildLayoutHelper.getBaseline` and friends (flutter@24) --- packages/core/lib/src/widgets/html_flex.dart | 60 ++++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/packages/core/lib/src/widgets/html_flex.dart b/packages/core/lib/src/widgets/html_flex.dart index b9f9294dd..1919c4f04 100644 --- a/packages/core/lib/src/widgets/html_flex.dart +++ b/packages/core/lib/src/widgets/html_flex.dart @@ -264,6 +264,21 @@ class _LayoutSizes { final double? spacePerFlex; } +extension on CrossAxisAlignment { + double _getChildCrossAxisOffset(double freeSpace, bool flipped) { + return switch (this) { + CrossAxisAlignment.stretch || CrossAxisAlignment.baseline => 0.0, + CrossAxisAlignment.start => flipped ? freeSpace : 0.0, + CrossAxisAlignment.center => freeSpace / 2, + CrossAxisAlignment.end => + CrossAxisAlignment.start._getChildCrossAxisOffset( + freeSpace, + !flipped, + ), + }; + } +} + extension on MainAxisAlignment { (double leadingSpace, double betweenSpace) _distributeSpace( double freeSpace, @@ -312,19 +327,24 @@ extension on MainAxisAlignment { } } -extension on CrossAxisAlignment { - double _getChildCrossAxisOffset(double freeSpace, bool flipped) { - return switch (this) { - CrossAxisAlignment.stretch || CrossAxisAlignment.baseline => 0.0, - CrossAxisAlignment.start => flipped ? freeSpace : 0.0, - CrossAxisAlignment.center => freeSpace / 2, - CrossAxisAlignment.end => - CrossAxisAlignment.start._getChildCrossAxisOffset( - freeSpace, - !flipped, - ), - }; - } +double? _getChildBaseline( + RenderBox child, + BoxConstraints constraints, + TextBaseline baseline, +) { + // TODO: use ChildLayoutHelper.getBaseline when minimum Flutter version >= 3.24 + assert(!child.debugNeedsLayout); + assert(child.constraints == constraints); + return child.getDistanceToBaseline(baseline, onlyReal: true); +} + +double? _getChildBaselineDry( + RenderBox child, + BoxConstraints constraints, + TextBaseline baseline, +) { + // TODO: use ChildLayoutHelper.getDryBaseline when minimum Flutter version >= 3.24 + return child.getDryBaseline(constraints, baseline); } class RenderHtmlFlex extends RenderBox @@ -544,7 +564,7 @@ class RenderHtmlFlex extends RenderBox ? BoxConstraints(maxWidth: extent) : BoxConstraints(maxHeight: extent), layoutChild: layoutChild, - getBaseline: ChildLayoutHelper.getDryBaseline, + getBaseline: _getChildBaselineDry, ).axisSize.crossAxisExtent; } } @@ -728,7 +748,7 @@ class RenderHtmlFlex extends RenderBox final _LayoutSizes sizes = _computeSizes( constraints: constraints, layoutChild: ChildLayoutHelper.dryLayoutChild, - getBaseline: ChildLayoutHelper.getDryBaseline, + getBaseline: _getChildBaselineDry, ); if (_isBaselineAligned) { @@ -816,7 +836,7 @@ class RenderHtmlFlex extends RenderBox return _computeSizes( constraints: constraints, layoutChild: ChildLayoutHelper.dryLayoutChild, - getBaseline: ChildLayoutHelper.getDryBaseline, + getBaseline: _getChildBaselineDry, ).axisSize.toSize(direction); } @@ -937,7 +957,11 @@ class RenderHtmlFlex extends RenderBox _LayoutSizes _computeSizes({ required BoxConstraints constraints, required ChildLayouter layoutChild, - required ChildBaselineGetter getBaseline, + required double? Function( + RenderBox child, + BoxConstraints constraints, + TextBaseline baseline, + ) getBaseline, }) { assert(_debugHasNecessaryDirections); @@ -1077,7 +1101,7 @@ class RenderHtmlFlex extends RenderBox final _LayoutSizes sizes = _computeSizes( constraints: constraints, layoutChild: ChildLayoutHelper.layoutChild, - getBaseline: ChildLayoutHelper.getBaseline, + getBaseline: _getChildBaseline, ); final double crossAxisExtent = sizes.axisSize.crossAxisExtent; From 30a44c7bc012b4b73b15a4442199626aee9a4187 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 18 Feb 2025 14:47:30 +0700 Subject: [PATCH 7/8] [skip ci] Add support for CSS `gap` --- .../core/lib/src/core_widget_factory.dart | 2 + .../src/internal/ops/style_display_flex.dart | 26 ++++--- packages/core/test/_.dart | 17 +++-- .../core/test/style_display_flex_test.dart | 75 +++++++++++++------ 4 files changed, 84 insertions(+), 36 deletions(-) diff --git a/packages/core/lib/src/core_widget_factory.dart b/packages/core/lib/src/core_widget_factory.dart index f311d0516..8a8628d88 100644 --- a/packages/core/lib/src/core_widget_factory.dart +++ b/packages/core/lib/src/core_widget_factory.dart @@ -229,6 +229,7 @@ class WidgetFactory extends WidgetFactoryResetter with AnchorWidgetFactory { CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, required Axis direction, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, + double spacing = 0.0, TextBaseline textBaseline = TextBaseline.alphabetic, TextDirection textDirection = TextDirection.ltr, }) { @@ -238,6 +239,7 @@ class WidgetFactory extends WidgetFactoryResetter with AnchorWidgetFactory { crossAxisAlignment: crossAxisAlignment, direction: direction, mainAxisAlignment: mainAxisAlignment, + spacing: spacing, textBaseline: textBaseline, textDirection: textDirection, children: children, diff --git a/packages/core/lib/src/internal/ops/style_display_flex.dart b/packages/core/lib/src/internal/ops/style_display_flex.dart index 8d7dcde87..423c71506 100644 --- a/packages/core/lib/src/internal/ops/style_display_flex.dart +++ b/packages/core/lib/src/internal/ops/style_display_flex.dart @@ -1,8 +1,18 @@ part of '../core_ops.dart'; +const kCssAlignItems = 'align-items'; +const kCssAlignItemsFlexStart = 'flex-start'; +const kCssAlignItemsFlexEnd = 'flex-end'; +const kCssAlignItemsCenter = 'center'; +const kCssAlignItemsBaseline = 'baseline'; +const kCssAlignItemsStretch = 'stretch'; + const kCssFlexDirection = 'flex-direction'; const kCssFlexDirectionColumn = 'column'; const kCssFlexDirectionRow = 'row'; + +const kCssGap = 'gap'; + const kCssJustifyContent = 'justify-content'; const kCssJustifyContentFlexStart = 'flex-start'; const kCssJustifyContentFlexEnd = 'flex-end'; @@ -10,12 +20,6 @@ const kCssJustifyContentCenter = 'center'; const kCssJustifyContentSpaceBetween = 'space-between'; const kCssJustifyContentSpaceAround = 'space-around'; const kCssJustifyContentSpaceEvenly = 'space-evenly'; -const kCssAlignItems = 'align-items'; -const kCssAlignItemsFlexStart = 'flex-start'; -const kCssAlignItemsFlexEnd = 'flex-end'; -const kCssAlignItemsCenter = 'center'; -const kCssAlignItemsBaseline = 'baseline'; -const kCssAlignItemsStretch = 'stretch'; class StyleDisplayFlex { final WidgetFactory wf; @@ -30,21 +34,24 @@ class StyleDisplayFlex { return null; } + String alignItems = kCssAlignItemsFlexStart; String flexDirection = kCssFlexDirectionRow; + CssLength? gap; String justifyContent = kCssJustifyContentFlexStart; - String alignItems = kCssAlignItemsFlexStart; for (final element in tree.element.styles) { final String? value = element.term; if (value != null) { switch (element.property) { + case kCssAlignItems: + alignItems = value; case kCssFlexDirection: flexDirection = value; + case kCssGap: + gap = tryParseCssLength(element.value); case kCssJustifyContent: justifyContent = value; - case kCssAlignItems: - alignItems = value; } } } @@ -65,6 +72,7 @@ class StyleDisplayFlex { ? Axis.horizontal : Axis.vertical, mainAxisAlignment: _toMainAxisAlignment(justifyContent), + spacing: gap?.getValue(resolved) ?? 0.0, textDirection: resolved.directionOrLtr, ); }, diff --git a/packages/core/test/_.dart b/packages/core/test/_.dart index c350182ec..9b62eff9a 100644 --- a/packages/core/test/_.dart +++ b/packages/core/test/_.dart @@ -778,20 +778,27 @@ class Explainer { attr.add( // TODO: remove ignore when our minimum core version >= 1.0 // ignore: avoid_dynamic_calls - 'direction=${dynamicWidget.direction}'.replaceAll('Axis.', ''), + 'crossAxisAlignment=${dynamicWidget.crossAxisAlignment}' + .replaceAll('CrossAxisAlignment.', ''), ); attr.add( // TODO: remove ignore when our minimum core version >= 1.0 // ignore: avoid_dynamic_calls - 'mainAxisAlignment=${dynamicWidget.mainAxisAlignment}' - .replaceAll('MainAxisAlignment.', ''), + 'direction=${dynamicWidget.direction}'.replaceAll('Axis.', ''), ); attr.add( // TODO: remove ignore when our minimum core version >= 1.0 // ignore: avoid_dynamic_calls - 'crossAxisAlignment=${dynamicWidget.crossAxisAlignment}' - .replaceAll('CrossAxisAlignment.', ''), + 'mainAxisAlignment=${dynamicWidget.mainAxisAlignment}' + .replaceAll('MainAxisAlignment.', ''), ); + + // TODO: remove ignore when our minimum core version >= 1.0 + // ignore: avoid_dynamic_calls + final spacing = dynamicWidget.spacing as double; + if (spacing != 0.0) { + attr.add('spacing=$spacing'); + } } } diff --git a/packages/core/test/style_display_flex_test.dart b/packages/core/test/style_display_flex_test.dart index c2995d5ac..229e52dc0 100644 --- a/packages/core/test/style_display_flex_test.dart +++ b/packages/core/test/style_display_flex_test.dart @@ -18,8 +18,8 @@ Future main() async { expect( explained, equals( - '[HtmlFlex:direction=horizontal,mainAxisAlignment=start,' - 'crossAxisAlignment=start,children=[RichText:(:Foo)]]', + '[HtmlFlex:crossAxisAlignment=start,direction=horizontal,' + 'mainAxisAlignment=start,children=[RichText:(:Foo)]]', ), ); }); @@ -31,7 +31,7 @@ Future main() async { expect( explained, equals( - '[HtmlFlex:direction=horizontal,mainAxisAlignment=start,crossAxisAlignment=start,children=' + '[HtmlFlex:crossAxisAlignment=start,direction=horizontal,mainAxisAlignment=start,children=' '[CssBlock:child=[RichText:(:Foo)]],' '[CssBlock:child=[RichText:(:Bar)]]' ']', @@ -46,7 +46,7 @@ Future main() async { expect( explained, equals( - '[HtmlFlex:direction=horizontal,mainAxisAlignment=start,crossAxisAlignment=start,children=' + '[HtmlFlex:crossAxisAlignment=start,direction=horizontal,mainAxisAlignment=start,children=' '[CssBlock:child=[RichText:(:Foo)]],' '[CssBlock:child=[RichText:(:Bar)]]' ']', @@ -194,6 +194,27 @@ Future main() async { expect(barRightAfter, equals(tester.windowWidth)); }); + testWidgets('updates spacing', (WidgetTester tester) async { + await explain( + tester, + '
' + '
Foo
Bar
' + '
', + ); + final barBefore = tester.bar; + final barLeftBefore = barBefore.left; + + await explain( + tester, + '
' + '
Foo
Bar
' + '
', + ); + final barAfter = tester.bar; + final barLeftAfter = barAfter.left; + expect(barLeftAfter, greaterThan(barLeftBefore)); + }); + testWidgets('updates textDirection', (WidgetTester tester) async { await explain( tester, @@ -445,6 +466,8 @@ Future main() async { kCssAlignItemsStretch, ]; + const List gaps = [null, 10]; + const justifyContents = [ kCssJustifyContentFlexStart, kCssJustifyContentFlexEnd, @@ -457,24 +480,28 @@ Future main() async { for (final flexDirection in flexDirections) { for (final alignItem in alignItems) { for (final justifyContent in justifyContents) { - final key = '$flexDirection/$alignItem/$justifyContent'; - testGoldens( - key, - (tester) async { - await tester.pumpWidgetBuilder( - _Golden( - flexDirection: flexDirection, - alignItem: alignItem, - justifyContent: justifyContent, - ), - wrapper: materialAppWrapper(theme: ThemeData.light()), - surfaceSize: const Size(316, 166), - ); - - await screenMatchesGolden(tester, key); - }, - skip: goldenSkip != null, - ); + for (final gap in gaps) { + final key = + '$flexDirection/$alignItem/${gap != null ? 'gap-${gap}px' : ''}$justifyContent'; + testGoldens( + key, + (tester) async { + await tester.pumpWidgetBuilder( + _Golden( + flexDirection: flexDirection, + alignItem: alignItem, + gap: gap, + justifyContent: justifyContent, + ), + wrapper: materialAppWrapper(theme: ThemeData.light()), + surfaceSize: const Size(316, 166), + ); + + await screenMatchesGolden(tester, key); + }, + skip: goldenSkip != null, + ); + } } } } @@ -497,11 +524,13 @@ extension on WidgetTester { class _Golden extends StatelessWidget { final String flexDirection; final String alignItem; + final double? gap; final String justifyContent; const _Golden({ required this.flexDirection, required this.alignItem, + this.gap, required this.justifyContent, }); @@ -510,6 +539,7 @@ class _Golden extends StatelessWidget { final inlineStyle = '$kCssDisplay: $kCssDisplayFlex; ' '$kCssFlexDirection: $flexDirection; ' '$kCssAlignItems: $alignItem; ' + '${gap != null ? '$kCssGap: ${gap}px' : ''}' '$kCssJustifyContent: $justifyContent'; return Scaffold( body: Padding( @@ -518,6 +548,7 @@ class _Golden extends StatelessWidget {
$flexDirection
$alignItem
+ ${gap != null ? '
gap-${gap}px
' : ''}
$justifyContent
'''), ), From 0031e0662a652b92ff195be6355c66f6373cb092 Mon Sep 17 00:00:00 2001 From: Cirrus CI Date: Tue, 18 Feb 2025 08:24:47 +0000 Subject: [PATCH 8/8] Update golden images --- .../test/flex/column/baseline/gap-2/center.png | Bin 0 -> 3229 bytes .../test/flex/column/baseline/gap-2/flex-end.png | Bin 0 -> 3224 bytes .../flex/column/baseline/gap-2/flex-start.png | Bin 0 -> 3371 bytes .../flex/column/baseline/gap-2/space-around.png | Bin 0 -> 3908 bytes .../flex/column/baseline/gap-2/space-between.png | Bin 0 -> 3899 bytes .../flex/column/baseline/gap-2/space-evenly.png | Bin 0 -> 3931 bytes .../test/flex/column/center/gap-2/center.png | Bin 0 -> 3119 bytes .../test/flex/column/center/gap-2/flex-end.png | Bin 0 -> 3125 bytes .../test/flex/column/center/gap-2/flex-start.png | Bin 0 -> 3268 bytes .../flex/column/center/gap-2/space-around.png | Bin 0 -> 3805 bytes .../flex/column/center/gap-2/space-between.png | Bin 0 -> 3793 bytes .../flex/column/center/gap-2/space-evenly.png | Bin 0 -> 3830 bytes .../test/flex/column/flex-end/gap-2/center.png | Bin 0 -> 3253 bytes .../test/flex/column/flex-end/gap-2/flex-end.png | Bin 0 -> 3251 bytes .../flex/column/flex-end/gap-2/flex-start.png | Bin 0 -> 3394 bytes .../flex/column/flex-end/gap-2/space-around.png | Bin 0 -> 3932 bytes .../flex/column/flex-end/gap-2/space-between.png | Bin 0 -> 3920 bytes .../flex/column/flex-end/gap-2/space-evenly.png | Bin 0 -> 3957 bytes .../test/flex/column/flex-start/gap-2/center.png | Bin 0 -> 3365 bytes .../flex/column/flex-start/gap-2/flex-end.png | Bin 0 -> 3363 bytes .../flex/column/flex-start/gap-2/flex-start.png | Bin 0 -> 3508 bytes .../column/flex-start/gap-2/space-around.png | Bin 0 -> 4039 bytes .../column/flex-start/gap-2/space-between.png | Bin 0 -> 4024 bytes .../column/flex-start/gap-2/space-evenly.png | Bin 0 -> 4064 bytes .../test/flex/column/stretch/gap-2/center.png | Bin 0 -> 3215 bytes .../test/flex/column/stretch/gap-2/flex-end.png | Bin 0 -> 3210 bytes .../flex/column/stretch/gap-2/flex-start.png | Bin 0 -> 3354 bytes .../flex/column/stretch/gap-2/space-around.png | Bin 0 -> 3892 bytes .../flex/column/stretch/gap-2/space-between.png | Bin 0 -> 3882 bytes .../flex/column/stretch/gap-2/space-evenly.png | Bin 0 -> 3915 bytes demo_app/test/flex/row/baseline/gap-2/center.png | Bin 0 -> 2889 bytes .../test/flex/row/baseline/gap-2/flex-end.png | Bin 0 -> 2867 bytes .../test/flex/row/baseline/gap-2/flex-start.png | Bin 0 -> 3271 bytes .../flex/row/baseline/gap-2/space-around.png | Bin 0 -> 3555 bytes .../flex/row/baseline/gap-2/space-between.png | Bin 0 -> 3636 bytes .../flex/row/baseline/gap-2/space-evenly.png | Bin 0 -> 3664 bytes demo_app/test/flex/row/center/gap-2/center.png | Bin 0 -> 2970 bytes demo_app/test/flex/row/center/gap-2/flex-end.png | Bin 0 -> 3022 bytes .../test/flex/row/center/gap-2/flex-start.png | Bin 0 -> 3288 bytes .../test/flex/row/center/gap-2/space-around.png | Bin 0 -> 3678 bytes .../test/flex/row/center/gap-2/space-between.png | Bin 0 -> 3739 bytes .../test/flex/row/center/gap-2/space-evenly.png | Bin 0 -> 3727 bytes demo_app/test/flex/row/flex-end/gap-2/center.png | Bin 0 -> 2761 bytes .../test/flex/row/flex-end/gap-2/flex-end.png | Bin 0 -> 2766 bytes .../test/flex/row/flex-end/gap-2/flex-start.png | Bin 0 -> 2987 bytes .../flex/row/flex-end/gap-2/space-around.png | Bin 0 -> 3615 bytes .../flex/row/flex-end/gap-2/space-between.png | Bin 0 -> 3503 bytes .../flex/row/flex-end/gap-2/space-evenly.png | Bin 0 -> 3457 bytes .../test/flex/row/flex-start/gap-2/center.png | Bin 0 -> 3246 bytes .../test/flex/row/flex-start/gap-2/flex-end.png | Bin 0 -> 3230 bytes .../flex/row/flex-start/gap-2/flex-start.png | Bin 0 -> 3460 bytes .../flex/row/flex-start/gap-2/space-around.png | Bin 0 -> 3850 bytes .../flex/row/flex-start/gap-2/space-between.png | Bin 0 -> 3950 bytes .../flex/row/flex-start/gap-2/space-evenly.png | Bin 0 -> 3971 bytes demo_app/test/flex/row/stretch/gap-2/center.png | Bin 0 -> 3017 bytes .../test/flex/row/stretch/gap-2/flex-end.png | Bin 0 -> 3043 bytes .../test/flex/row/stretch/gap-2/flex-start.png | Bin 0 -> 3210 bytes .../test/flex/row/stretch/gap-2/space-around.png | Bin 0 -> 3646 bytes .../flex/row/stretch/gap-2/space-between.png | Bin 0 -> 3733 bytes .../test/flex/row/stretch/gap-2/space-evenly.png | Bin 0 -> 3778 bytes packages/core/test/style_display_flex_test.dart | 9 ++++----- 61 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 demo_app/test/flex/column/baseline/gap-2/center.png create mode 100644 demo_app/test/flex/column/baseline/gap-2/flex-end.png create mode 100644 demo_app/test/flex/column/baseline/gap-2/flex-start.png create mode 100644 demo_app/test/flex/column/baseline/gap-2/space-around.png create mode 100644 demo_app/test/flex/column/baseline/gap-2/space-between.png create mode 100644 demo_app/test/flex/column/baseline/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/column/center/gap-2/center.png create mode 100644 demo_app/test/flex/column/center/gap-2/flex-end.png create mode 100644 demo_app/test/flex/column/center/gap-2/flex-start.png create mode 100644 demo_app/test/flex/column/center/gap-2/space-around.png create mode 100644 demo_app/test/flex/column/center/gap-2/space-between.png create mode 100644 demo_app/test/flex/column/center/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/center.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/flex-end.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/flex-start.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/space-around.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/space-between.png create mode 100644 demo_app/test/flex/column/flex-end/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/center.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/flex-end.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/flex-start.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/space-around.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/space-between.png create mode 100644 demo_app/test/flex/column/flex-start/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/center.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/flex-end.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/flex-start.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/space-around.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/space-between.png create mode 100644 demo_app/test/flex/column/stretch/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/center.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/flex-end.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/flex-start.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/space-around.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/space-between.png create mode 100644 demo_app/test/flex/row/baseline/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/row/center/gap-2/center.png create mode 100644 demo_app/test/flex/row/center/gap-2/flex-end.png create mode 100644 demo_app/test/flex/row/center/gap-2/flex-start.png create mode 100644 demo_app/test/flex/row/center/gap-2/space-around.png create mode 100644 demo_app/test/flex/row/center/gap-2/space-between.png create mode 100644 demo_app/test/flex/row/center/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/center.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/flex-end.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/flex-start.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/space-around.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/space-between.png create mode 100644 demo_app/test/flex/row/flex-end/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/center.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/flex-end.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/flex-start.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/space-around.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/space-between.png create mode 100644 demo_app/test/flex/row/flex-start/gap-2/space-evenly.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/center.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/flex-end.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/flex-start.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/space-around.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/space-between.png create mode 100644 demo_app/test/flex/row/stretch/gap-2/space-evenly.png diff --git a/demo_app/test/flex/column/baseline/gap-2/center.png b/demo_app/test/flex/column/baseline/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..792a13c8e2f7dc740301a0f4d1e9a63bbf9f6a22 GIT binary patch literal 3229 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 XOSDtvzdG!HF#zzTYo_JKZgKwr)4d|| literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/baseline/gap-2/flex-end.png b/demo_app/test/flex/column/baseline/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..49c24160ca70ab38752e7093904d993fa7eb9227 GIT binary patch literal 3224 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/baseline/gap-2/flex-start.png b/demo_app/test/flex/column/baseline/gap-2/flex-start.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6c9e835d6c493383f6088361fbfa55cc87f49a GIT binary patch literal 3371 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/baseline/gap-2/space-between.png b/demo_app/test/flex/column/baseline/gap-2/space-between.png new file mode 100644 index 0000000000000000000000000000000000000000..c82cf0286cb631d0025d23c30d525b695c79144d GIT binary patch literal 3899 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 H;~e`h8>VF` literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/baseline/gap-2/space-evenly.png b/demo_app/test/flex/column/baseline/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..73d4223580abde58148e94e0f802249ecd1154b1 GIT binary patch literal 3931 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/center/gap-2/center.png b/demo_app/test/flex/column/center/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..adc2006f0a5a37f7dd6de63c56d37456a1540cc9 GIT binary patch literal 3119 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/center/gap-2/flex-end.png b/demo_app/test/flex/column/center/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..753bfa810c3c7756b0b89867e379e01d968a6bea GIT binary patch literal 3125 zcmdT`c{tST9{))q>ZsE>i4&uc5W|rYCXtL`LbimV>|;X9SQ=S7r;fcW*+~pZOv=(& zMr7%Xbu2T-XvQ|oAnVM~7{=9e?|Gh{``qsR`@Vm?%kzG}@B4n==ll77KC#x8(EZ{v z;s5~bhnbn!0DzFe&b&ly&rT0b*3Q@&gznlvje*MEqq94U-FJ;)c49m2zL@7903b02 zGcmFY&0U~{C%AYOcCL(_^KlKPhcr0fv3+I7*iz~ z`C^&G%qSx*#);=hGqs=X;8lBfH{vf>f}h#>?J|$YVo!5KoZ|iK-qP~cv$UDrcei!J zLh330bs<#$+4Eyociw3G^mb|UJI^vdXF;aWG96;Tsqy@IA>jRp@iO4}U|i_+o)+Qj z`(s4k%j}kn(h-vbP;Dj7<6MY-Z?73Jep=o64iDzW6#LiS0Rw<69}2uO`kwRug@JC~ zLoH>5{B&*;33!jxOiZ0gP%r@2{%c^lZ^zY}uSeG^rZD~1fm3YVZRCp5L`=gHIG?R}3n;4s-6inX^A!s3WUxteb`t{VVzy=#Okp&1$Bi zN?P@o)_88iL^BFGN&#!1lU;TvhUj5bQ-?ok4k6OD_6O@>bSXI6%DeOASM$B*FrFn; zy_2LQp)s&Ac@UDB(#ALgZ8!H$Ppx|Kbx4)Anr@Yw4Q$A-}jqu6d%E!rvh9~qosb67@Ac#oto?TR|G z`}WVeNv@V_Dvyi6WMVdGPdzbkwwIV0@wA6)(BC(N+Msw}lzJHLKrY{CkQ!wA*(0a{ zC|Ex^&h&C%+f*tU-|%Y**5Az{rZ&KDh~sTQVhei8tst{!BBk?{1zE?sd@q1Fb}(> z+hc(Dqx=|V;v{@#2ORFPb^8eLYw_TiD9qmbW!3|vw( z60_DZ87EzY+A48@C3~^;80{Rt<7Ln{A~c6`IKCqOL9IYPom^{TBkHaN$?hrW4cir^ z!riP&`{frM`=ijYInYq%{M;Znn_!~?OPTCo8Ja??&*V^in7xB3!Om_KPdTwOLm&&D zPcs&5-?ibe{cPs9!ho`?HM+j*f=b}J`2A9msA~_Fs)4B6f8+YQ&>R$?Mv@jr`~C^| zoSC4c@1YwWCTzWaEC3K6-|Xk@ISYsYu{#xH@4r`&Z*Q7HNH;Pj&Nnd)nFaGVfJ`rX zdW&#Wmga&w-Rh%R7VVlBy_>j#&^b)8M>serlb$Hv+i!)Zh|lRiwh2qZ5vRR)OGsGC z%uN{^l#y)}>D@qJ>9izIH9Qnq=NRv95!Z%4NF?N^js_3E zdr?Vz69;cBY9keYJ%GFV=2!i@GEIdiBl`^%n&pAF&^~Br7UUXs-ShMY$wM{bj$=TV zy#OZyOF5*M{T6Aq5a9+5)O$tctI1#@DjS{ZaJ;J$ej0u()~bT|+m^QaX*CNy%-{{4 zR5f~;&7YP`>|DHHo`pD<7|zLz0~xB;O{ml%GMXswBR0X z{M?(X3Q{eDu++MDzr6oiv2L0;t7|T2`SQ@xi`wd!nzAqP&&sGuI!cn<%dgxB&x^^M zB{43~sC>UUzO#9Xr;CF2dDSUtq^>8!S}qB8uOM zhJR*+z=7+f`Ibn;n7zAhnLG&IEiqV_gfRTkzxwFaF@2Suu({SnJ@u>Ul4;8MR&gml zjA6(*S!l;rr{lTkqM_)tNo;0!C?I>te-MQst$hkODs){HA`*DqTzM}%9A-bQW}ZsX z?@_=#`6W*LZcFjK8*V3YRDQv6p}&esZJiEj`}Lqy9Tp#Ua1mZ1GYs@mk&z24?lyUZ zq*nBcoj_AR!(IAW$Vhh1stmnttrdO5Ke|B zmw*~_>Q9T6o)$PgzM81w5QplOxM(g1%O9xKk4>6v|827K$2(Ng0kw>b^f4-KCjob| zYBpTD=icoXlnLS2)_u$vZoAGof2eSd=(G-E`00=x&l)X`GAQ!cwy_HcbCuep82paE zP=mFv(eTY1s2vq1yzEky!30#A3Mx)U23RD<&)+eI{;s~YO4QQXE-M^(1Pzlt4@j)! z9R|Gj69#ty9S8pxTf+G`uhBqyM6l^DK>I5PkuwF6NL!ykP2iTEUSeu<@82}@U2d{e z3r&WcNK7*CDM7P)1}YH)7T`R5OHZ*4jQV=QC3)BTks&tav};HndencQK%ls_RyWWE zE*OaxdY?tUyIhGkjcYH4g3|NvuXg_+4tN_|l~x;Wm2n<`Op+)qw>&6}9SQg)=4GpFOiUi!N8P zSKU4`;ZuZ~?alCkBLDGn7W5nnDMS0-6ZyUGSj4C~nJxY6ul1J-TZseUVXHb1Ps%LRk{ zi5wW|Onr0732)<6bsV$MB8s&NH{bXGDqgy;9EZ@Lbm@!Ua-Bb&aBf8LGNi)ED?zK{ zmCHz89V$Z$-1HMf&?@zu5{Sq0H#!nKj_US@6TITJ_-oR(r)1cz63TSS2Dc+20iItM zR;Sfx2!hZXM>0d`vxMO3bP}O?y@|y`;iTC!IjIz!UBbxgi8j8cySv_Y$t>oK2gm}y zF~?#avN9$*1}71>FQJ7P;KFuiOG*5tKyqr_t6+rXrp7_vl%0-teAP9my=n=EcUN^nySoaJ*X-s*>Bwdxj;H? z122b={clrI?*|-|9?PBfo(L*8WfWJNiIM#IviIPNDhe=rctnJ5N*k`lqYP(^xsw`^ z=jO0uja*Jbsr($GH>L+6zci?C%>F$9l5!Z(lMAOP0zjF-E8b5+clcW+_=In1?mq_j z{c;ZIk&6cM4?haxRi7xxeFU`LJev(`Az(HC{l)Yfpm+BZPw2j%UGtxRsy6mZPmq0p zBewB|{^Ga0&39wi2R5~*R0$q%wpz85v|NONxV+u4)~F%DtuqcKwjoa!4AzW@xQVZC zlsTBvAaDCqS3$}pcPE|(_oi88?6I=xy;|&-Jnm>)LfpCJ6D}uhA6r+UT0x@RJ-_27 z?&w!n5vwVKG?E;oL%Q6q{-dI4*r|IZysuc0_2%1gqk>DbX|-4)@gZ3amxq-F*rd25 zwr3~lxq>4_J_?kUBBXRw0Dd7BlHs&^ZcL}froi;EVzMwiKH(DE&wv$ou5THHv&Ki< z^Q6JrlEb0+($y6T>pTTID_DXI^|s`;*#})NEt^|$RW7MHia_4*wyd%6+Q5OHO;7Ub zamk|Rg}UbUHvUt%ioXg+Vq5+sIg^X(7z1Y zA-YqY2k-X?#*NvjF`Gg`JFd#i&*m4pHj{`oSuB4o10P&OqQhaqm8h}y?!2EhZ}9)3o;kC#DMyI6c*yhLTzIq{@XelYD-D5&PmXNpO|;AQ-4 z5=?bT3aOAjKy-EIKXKRy8*EZI!w2;Hb9|I&PS(oNh0Xna6}5JjIQ1OXsu?&#RNH*V z*r1r7I={hP*z5M;#@7#CU|a=w=UG-uB`qAGQL`8x?w|0>SJ}50Rad2|O;iAE5{+;P zfsSGAi!0lEtB#Kj=K&`FlY~G0-+ki)uAn^W6^{-8(q-dUj?D=D#Lo|}c7iM*Nl6w4 z_J&5@*p`w71OSm;a76x$xj%d)BpTPR<@Jm`{}yh`+bWGP-zN-!ldhP2jyE^AZYqQ@ z$)rZ4Wj5YNEOy1eJvXB?^c3NpY@NR$#txPMO|)65#9hri*-anEj}%v)D6v092Um_e zyDUt?mPe)DHh(Nyb1^t+HDf{oB^#scR)ZTny-*H}F^NRUOHleRDbgkf(0>hQ9W}IG+|Kbh36g za{mx>7*4NvqDolB>3~WTUrwBzsNPW$xn<}^Db+q)GIFQ#1gG=;Z_ML(w)d2_5eM$sH}N7j=<;qLrf2Om$Matl z^--6OK*Wf@DYgq{+?GkJGXP{Ax=?K@Ye%w%vz=L%mnIxQkDymBhS@*D*az7=D|lsb zEh!nDjVqdLIkqho%O|pKFDP8 z=#@_gyjrGaG$xhBsD~@NAFLn|N?%*dogy5NlHtr=_t_YU=s~I5VV0bkN|lk|`3vYV ztcy!+{bS+`MSEGdtul({bj9J}(df6^%@-!(K!YY#r`bz=kTT&`)9?K0-(4gDw{HHd zMnA~-Lv!ky$%K&0|Kcy-JAZ;Fw0&+7e>tDh3A8TVfTV8e{Sco&RjThIr$_u`wE0xa zK-sy9nyXD6Z=$BkCH_KJfXh+ zoLG3x3$y#6QhwR2!nox(V5Za6MpsF3y|FqV^cguksUDumnv@;I;iAn(>ijn5iH#0O zj!$f7Uaw8Bk>6z4L?ZP)hDEi>9Bp1oBB6HPb;L~_hI@njwMwJt*$a*RM0$hE#&QlG zWOmk^vS{3}-H&_TL3Em1;&SoMRdX;E$WV}Hw5hV_90CiM1`w8YUhis;a9ef;re6!9 zIooWsMmshyM8}sC){wC10gIf&ehltC23wog^xZ&0b+~Tknh`*<sK&x$-0)*4cjVd?I6D}=g=Bn0 z;Qb0~{o*rZCgbyTtQH&PgND6OEzHVJSj%E<$K1Jb-7!7jOKRrYv#c)l`ki=|eT7GT zmp09Ecy3B3YFtUxRqkR5wZ6sZvCGwfwBl{&ZwSNnsfww=>LweAjdW1~EBbm8DW;ATQAG-yzL$^$^e8B*MmI!_ zVk080O*V_5_0hGY(1|G>`WBHCg3AKiMA22ZmUAMv+R=_3yLWHcgVr6P(+KH>32qzI zoH=pd+_W=L%0Qt+@OU69Bp@%orytFGZ9xzIYV_%=!iwsvil;KEpB^^}bSgO%*0kc4vy$k!@i+Z&Anx{N_lx~gNA`AqMlv}So(@uZt7tyj!WO??Y>>m1+GY9F77Lyhe;*)$-@8V!*Wj#b0>7CLse zM)%8d7g|C})0ex}85FfZigNIy7*c}r#yZ$&{kS14T1rv2VciQhj_kskw_&-9^|Q^Z zs<83cUMzA9TTj>dGGkKDg+>lfK}Q-Ea*-*F_UqTL>&HGEMz%+}0a(p-upl6A@mD42 zkLp!pHWtp^*s$%s1blh{MZUApZ~Kcn_rEgB|4cpq4+b8)v@;6%fP8`Px$lpx_;YAW aEt!z*w)>sG9@%|~09F^lAfnl|JO2djAx0kn literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/center/gap-2/space-around.png b/demo_app/test/flex/column/center/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8a6d1fe203b5e844c1e773be8706e4f5a03a32 GIT binary patch literal 3805 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/center/gap-2/space-between.png b/demo_app/test/flex/column/center/gap-2/space-between.png new file mode 100644 index 0000000000000000000000000000000000000000..11b9af91902230e075ad7959ff9700ed54bc3f94 GIT binary patch literal 3793 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 S&$;rj6o5LopQ*OLc;oL4UQWRP literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/center/gap-2/space-evenly.png b/demo_app/test/flex/column/center/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..be8f69f767e6ebdb2ad57fabef04eddc8a37771c GIT binary patch literal 3830 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-end/gap-2/flex-end.png b/demo_app/test/flex/column/flex-end/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..d891488f84470b1b79a10020d8ead88c4e5dbc6b GIT binary patch literal 3251 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 BhC~1W literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-end/gap-2/space-around.png b/demo_app/test/flex/column/flex-end/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4547388defc659c657eeea0e1318e257a13b55 GIT binary patch literal 3932 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 YDKYK&i#?fgdWQ_Ss%HW()p3aZJ6wxgaR2}S literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-end/gap-2/space-between.png b/demo_app/test/flex/column/flex-end/gap-2/space-between.png new file mode 100644 index 0000000000000000000000000000000000000000..37c08f0d9a4a0cc579a461945eca6d0dfbabe85b GIT binary patch literal 3920 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-end/gap-2/space-evenly.png b/demo_app/test/flex/column/flex-end/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa667b1f3a43c08ad80ba70bb9a1f33eafa0153 GIT binary patch literal 3957 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 TPVs_2FTlpi!LrWWFXjIL&*rvF literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-start/gap-2/space-around.png b/demo_app/test/flex/column/flex-start/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..7db35b5488c75cabab2381bf62d488eeceb05e9a GIT binary patch literal 4039 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-start/gap-2/space-between.png b/demo_app/test/flex/column/flex-start/gap-2/space-between.png new file mode 100644 index 0000000000000000000000000000000000000000..49e6e2f1d92bca56846429af6fb90dd4d1eb2bf1 GIT binary patch literal 4024 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/flex-start/gap-2/space-evenly.png b/demo_app/test/flex/column/flex-start/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..dda5439ef431440fc9700f08c4a43aa3c042c838 GIT binary patch literal 4064 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 Uyx7rl?vxHdok1hZPGgAw0r20Iw*UYD literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/center.png b/demo_app/test/flex/column/stretch/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..85eb39ee64e0df35e2a96e658b529747e53ac4c6 GIT binary patch literal 3215 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 Fe*=%4Ag}-c literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/flex-end.png b/demo_app/test/flex/column/stretch/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..fa10818f72263bdb36152b15a54c31a2bdd4c1f0 GIT binary patch literal 3210 zcmd5Gxf{}< zGR-#GA)<(880LPNXFbo;^E!W=p1+^(AK%;S{rbMXpUeC6{(kSW)IPT%Mm_0tf0l+?O3)6Fs5l?1E zVjsHu-sxT#g-ns#dabUx>c`$GOi(@UQom;)aE~(EEREQJb-c1?FDUE!?X)TvMP)DB zeVUTi=Uwq*4^(v1+j+EJ)t-vXU43{uyyV&JS%1s2PRi1|SPW#U-G3;2rsyQ%rlIRinrIrhM`2*~^dEnCBF@c)hKRWFH5&(Y@K&cgdmCro` z0`x>np@Hx8_y&sqoio1Qze`B;qgc|Ta`1sx+h$=eg_QpoZdN{WC=ZK+7cb?RUW72; zi+#b8-CnEsKE@W0k$y(tk5@S7FT!|M_M?pvL9{EMh0ioW(M=UrkP)UPxC+ZmiPv)mO4O)J-#V zH=GXAUYeM{8A$P6Hg9sMHXRQXM@MUwq;BYJqt+UNPD+!WSHO_=GJ%wWz9Pl*`V$Gu zXsC`~zUOhqhS_B+BbF_V!=`=4=RpFjquCcJ4K~)dXUa}1{Rq$R) zksd&h2qr(xK}iG;rX{Tb1&^-J6Ty>+f3AfweuCS0ca?vI$3YhMZl;2Y?DIBvpE9mJ z1Pz8NmG!_(&2Y-2*#s5*oZh0%i~Rtlt}Z_Nlo_*MRsSH$o%_163TIyW#USO;COPav zAi6EUYC1gW;w#QO!;mzQ3?KhY#gI}4J>+yywGHoaAt z*-38=Qpk)!VkLW;TT)0)KboPGkW5R3KfG?KS_D4nR++WjM0PpMXmc#(U3zOgK-h3q zDC3~R{Ld9VLtYeepJsl*Ab?XsWX3<*TROsBfp)$BmD%5@n=G?Ks>D!n+|vgDJI)1CPc-ZaK4f4?lC1e2!Tk za+X54WjSx%FfpWRV3pL@m$i~T3<^KP7B9|Os%agtJ3Z{Uc-Fo<2%GBm~&tBq!8`Z7~g z>y@Lm!h(7ctD>R^Pg_P`+kQfgezg#I<%G6WP_ln`;@h5{sGY8JI`(8O%$#0xo5bzN zqS>*8kjw9*P$(r?Lil_1m67tTS}+8=5N{xLm}wrwo)bzy2xWmadTiFQ#S=)GFFTj5 zmaCdT7M=<3AtkG5^Q$qkDL%>p;HZpMy7}~$Zy|hr!!+yoA%wJZ|3jTJPd}3_xly~V8*ZPTr%~4A z%jFas5zZceI4FM9^SxCqVc%M&&uaWkcv(DZef{O^WvF8H#2Y{Tb1?#!h_hqwr4YBa zxZMZkADqxX>@X$k4qET8K_wBc)r9rDzSW5;-nO9XTq)~&8GM+XzkGLi@q(feBkF|3q61H*to(V=O`XnO zaXD9D#gA^@UP9R5cPQ}w=R(5@}aDDkW_SW z_RVz~#%R)$-qwjS;RuFAmpa82$GJ*3kM2sM2H-H!RLUq2M?n@%0kGn%Yd zd-3+^L1dSqdYh4(BqnAN+(L6*X%}GiJ!5dVDF(%N1n^E7_YzBpNF+CGE+8N7Tw!m7LH$|~ zX{IW5m$llKEk_QLu7M*vqQ?YS65+mUyLMw4e>g= zF-R@0sKV+7WyUT3#G+f?EpTwDhev%?V7-=P%{7;d@|>Es!&taz*B-aHNQnVXobxn0 zLpLC8pjv#=aP29YVNFj0UmV@^kZ49X%slut@ zbJ~+%X#*`f{_(LpW5OMr=5Sf=%7+Xlbt-v~yuGyPbLGn8Xoi(x9x1iNE%w$t_x>;O zj6PTECSDZ2sE9<_UbRe;w)|AHG#gxxTiqU5;uZ+QFz)We*?v@q-_7uF|NM(3%Mr|~ zu`gxz9UMbLx&g=Pi02E48d$b{^m!fF^~rrRMLnVXawmVoxvyzZ@NbM)5+5V4v2S89 zZ1hT^@sk$fr%$JkTDJ1;B#L|Ca!F&eBeJh5n~@v5)w@%V)H9-@kv+rF)#!Pz8%itf zf^<%tG_);}I}s=kITkzP-651_yrmE^H{@U9>;ZZ4yk&=68?z3HbO9!7TntJ^YAuG^ zjP+hd&!1yeHOEugfkXX|F@wJJPH{_Q-7e`tupb7|0g^MA6NhY literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/flex-start.png b/demo_app/test/flex/column/stretch/gap-2/flex-start.png new file mode 100644 index 0000000000000000000000000000000000000000..a86ccb56916920f867618d62d889cb9b6b271223 GIT binary patch literal 3354 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 P8vtTpreCG|YwSM&4Y6&{ literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/space-around.png b/demo_app/test/flex/column/stretch/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..805ab6578e0fed497a7f75843a0f9d89a1db70f1 GIT binary patch literal 3892 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 E2iv!Z3;+NC literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/space-between.png b/demo_app/test/flex/column/stretch/gap-2/space-between.png new file mode 100644 index 0000000000000000000000000000000000000000..92eddfac022204049a2a37e5e16172a996054d88 GIT binary patch literal 3882 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 E0J%YcNdN!< literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/column/stretch/gap-2/space-evenly.png b/demo_app/test/flex/column/stretch/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..67f406118844b0ea574a4046751e70080304f384 GIT binary patch literal 3915 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 SJM~i?1Fq^AqKdTb!~X>uURZG(}CY>^UyE6fTq- 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 T;BB+>4g+9NxLu{~FA0AEymXDO literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/baseline/gap-2/flex-end.png b/demo_app/test/flex/row/baseline/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..56283b1f4921b41843144eddbea0db535d24ed4b GIT binary patch literal 2867 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/baseline/gap-2/flex-start.png b/demo_app/test/flex/row/baseline/gap-2/flex-start.png new file mode 100644 index 0000000000000000000000000000000000000000..87a5c2c41b5d9d5ed81e64a1a67398fbb0ac5bac GIT binary patch literal 3271 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/baseline/gap-2/space-around.png b/demo_app/test/flex/row/baseline/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..0e251c3784378287ec9f02c07fb1ac5077ee4123 GIT binary patch literal 3555 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

`x|M9S$_fBt#{64BJ`AvSc0kqd1?QoPEeq z!KAGp#+`UZU2yGtPIxgQY5Cm~D(1{{!vUnRhO3oMTZkTR_W?pVs2~GMFL$ATA47>o zorv;bZz4ij0i3SG%nEB$8~G+(bLOvhVuYZgeCg!tHQVMVTdv!5AmwV#|7eEz;rRTV;6HTk$n7U?tYj(sahI#3_TFj^spu( z49I|N58r?z!m(jmT83xW2^(l`^K|`d37%#RJne$|FC180oFiP!Gz!gE=u?dSW)$wd zxR$N%2u)JhA-#kq28<$I5Zg5-<5OWi>9>dF-b9u<4<}|MY{r(6LYCGx6Ur#Ad+NiA z20pj0D$B!Q$*UX)tk$2o49z0=7b_%?u+98?(R;!;UnY+~^i^!xxvsq1^c=X~+Pbgg zrZ}!;Na+X~)aD%h$Uv1}fiH+8?J{jIY@$V_7}>)Uys0N`92zgMa6qMD3Li*atGK4i{6C4}N$v3hD0; z*R-F0XWA9y`*f^3TiP$XjrMy|UxVW#^)HF`uWi&yLd2T%tTi>BLR@z0S4!G(Snj6} zbLAED+c|JXuPC^xdc|SmigWAIZg56h0*zgKz6+U@W`Y!&zhX5diVE0miByk%8h-2e-zhjSd-xW2a@$o0&CNURQ}qC_Q}wGCg=rwJh+&8#nAF7>qs`azZC!Y zjB?+9Sm!b}O=Y3#EoTwiYj<~qN~MUVZ^S!xmxOq`N@B#qP_|cI&^xi<^it~$B=txB z^O{!D8L^SA#EI^RHbGwSR_)v-h02%)zzz5k_0MwZv1*tx@=LLOo$#o#xJJGVWq-LF5y z_}*Qw_v!P3Yq-K>_RO>B222{ofkr}MhD^68FRfN!8b?1MqumkCktOU0<1Y@U@ibb! zU5Hxu>$%y;t_}SX@n6_rv@O>m!S~f$@Y|*@}m&yDFE;j6sUZ>?i^RP7xfa9S$kW5glJF5sJ`gb8;Rg{SOE z%`louH}*|b*}JFX;J>iazv*)K8%SU^@zzSU{I7s#?WLtS)4Bf*t^NCe|Ki*K%6tD` z;D0Pk{*Qp_%;NSVd(ejf5t_Q4|5+pbJ5y%GQZ(KAm`-6j*>m~cF2X&I#S)kp5I%L zK1?KG0#SnCC)N9Q<~%TR?2Mxv13pv~y(<@e|M>CCK-c#&G07`e$k-On;m!%wYsaFx zuWU5CC<}};;C&!+YA9|Y?<0~Xne!UZ#uL^k1psV{M4fCCJ1+E8`IHpE>zo##?{_31 z@9s~4x-?f`!hd{sdP?jxAg=@-TM+t{nlsDuRK(Md?} zQOwCU+5gFf=QDq8M>oo7u`2A?yKjNh+(8$9wgXEwI=41kw;EzBx}sXYu`pTU5^(Lf zA-$hZbO(R=MfO9tlMt^uEb_ZikA-2b?t=ab1{kD$d`5Y2VSnv8jbGaVT&_`^(L}~` zJ{_1vMdw1GqA?!cLJniUtHERpWseGhXFVKn9-3Xq63qOP=b}W z;~11P>lTW%t**GIf|2w$8$BrCpurS%-n{blgX({y9wOA){KVnaD=t(@xN(JLXr#vvgz zVY{(|lR~CS&B=_%Q(6-H32GBe$AFBbWoB4zE}nX+|1sG&qZWp(MUWC|Nao?+bKG>e zqojJKYnIE6;vrf92E_?na3~PM$+SqFTKeu?_Pws&I5m@xpKWhd^}Vj{$8JgFb(7Ly zJCnxLb#JhjuI9#>TDo5W2O9y}C%1tXw~!lk{mUbt`t;Ab40g+X6}ApW>L=K(*xdd~ zpsDpF>dOzD10&&84p%M?AC_&)iCGZcoflIgKR9-*BjyN;)dxUz0;DkiAAHkF=`vx~ zQvbd)eW@?RE5}NIjKhfbP`QB3xhtGj!vYS97pT6gSLZZP&cl_lNg z+1>%CJ6m6qVPLp}lLBIwBR8s^IBJ1O`UhY~vNdvLcMaH?0=m#^ZGkTg`@y2$^{Ao=WfVmC=7^4W|g;2&e z!??^7Jp2PjaS{FK*3>LbWb*NeXPYi5y4-;~I@b1G8W^@GPbpp-;38_}le_a~An;0N zv#KnSsZyWlW7|7@g79X%v~T^zdEwKM$VHxFew$Q$qH@u7h#m2}S#ElF|20b8oweL- z>%#P-de*|X9)2v9v(GUV#S2S{rN|rs;&8$ln1DOX57JjJ+D#NZSRNDcSXVZUNn27c za^8*QPk(2ew^arA`1z1fY_K=41oKQYw*S2ebr|L|czJ(krKT8Cqu`{dNUKE4wru70 zCdw=>mBA!J_(=5+n&vZCUK5)ffZT}voxSB^b1WYFxOy^P)QpUPyhiVQNJ?Uxxl{*! z4UA=+jmD!`b@qymo`pEzNSAVWZ7sS5rskKKe$PQc_RPkM)3gjbhaa*&EU3@t3;W33 zp!lheuT)D`ambFYeRk!fpOjjkX9TMi<-ipSccNs^hExU(r7~oAXjhs-in8pkI30%hdV8#;#57U{B_$F@8s)HQmRZCP0GaD9gOY3#@RNN+-qk; zxH_LO=QmI@o~HYX_fM?JmmcCLl_%{Y~!}4hpkBb&@*Duhl4p)k*T(2 z{+ViCiF0gI%+3dbWT_gPJi~We%=sc~ATjFLNXd$$Y^qe!=>D-L8PA2Cm=J_7g4l3(02OzQpC1ivs~k&Cl%Bp3gp4V! zfIw&al7TV7*HqO@#%8jupVjg&>zRT(GZajTPmEG%&uVWw*BD!VF8X3biOY+^X(22f zYCql3|AK=x6hzQ6{brvau&Z2`F{Oxh3tA;aI&!zCzC2>bH9p^6xz?LbA0asw-)ZaP zYVYD1+ee3=eG5@lSY<^dRLOpKwJ909w_*Qw&@BLi)MyMQCf{m4m3VOdD*=47cz|qRntpW{;@LxU zS0{8ZqT}qS^Co7qO^+t!m{wPmNNu<`>q5fUf-JCFKHc;=o3|ZX2|{slH5x@fyB--B z=^woraC57E%7%k53+RO;hOdul6H2-~;jdmq&u$bn#Giw~#$ld)wHqNG9<&hpcvyp= z1YWr>*;)=O41Myf)9WZ9e>0q9sZpwOrY$koZNc{X0WB&LMGLr^J1u*}=+G5=$Lgt| zcxV5ecf#^`pCNoHu6hO~1i9mxe4Iksn+a>nB$< zCq&18qGD2`SbomK6ghB0p5kfPUe z5VocMhJUDM45!=2cFFFoUS${=7#e`z*BG~NKaUfPBg}Vr68tXHL0Xps$aY70X9SXa ze=bi|PI|s`BmFFX_;wY<0DJP?5|@~2Ycd0saUQtn`-L2CiwUw>7sD!Cnz-kO- zk|>Al!N95aR^lp4Kjb^*?IwQn?5{7YtIAIJHifc0h(v9elXE#Ae=SA7o|-cWy~thB z4LG>`7+o5T-TT0*&DMhK(J2ZdI{T0$L6VC@^~Xn%tBnQC<^hKm@xLBiUPWts;7xWM zDmBZ3`j+xYp%myv8ezwU+DZ`zY+4|r_+O8XxcG=1^pG87A5vyX!d_{-2a7#|G&Y1=#l@^arlYXyq)7DbPN#A itNb?&_1}CxywrHf=c;{YKKMu#0!$1n^ec29M*R!LnGq%c literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/center/gap-2/center.png b/demo_app/test/flex/row/center/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..44d75aa50974675349bafca672ccbbb6eab8f08b GIT binary patch literal 2970 zcmd^>c{dwq7r@i%lu}K#qehG{En_R%iDm4yHIg>8k=QC|mD)nvAYyIR(8j(SYwbl* z(o~71s_LK-2|*ECDTy`Kif!@%`U&3mp7XoU^W1aq^T)mSoO@r~vV@8XgM%0cx-kS38*M*~>T^wjZMc3p_lsL-6`6QgP)zJ@Ciil#K|); zt2_E6r@Uv1F`HfjrNY`btS*J zoNO2P8G-HRtt@s!i=j`GF9z*Bc}W-e;H2$-vl!}fzTG>i{JatsiydaMwGdL;#%Nlq zT+7Js!+v93oWZ*D{?J}U?0OgsIV9pab13NbY_(MdY@v(a{JRB&1?zub9l-K#Tx7n4 zjP88NRjPK7PlqG5R9e=F8h1bTAF9+O4OOT1xK)s>gE#4gVNzNay%{j?VR$<6ty`>r zud44PhsiLPfKjQ)vlb!}P0I>-axHr`sLSww<2KiOO$!+dfBIM9XxfcVL4vAL`2=6 z))k*x)A(7{d@^E^%9CR=ZCM4GPRi1R68{MT144U`O;w=SPugrXX?SPkpo^{wISFWr zQi3x#Oo9zS1N#$w?bvDAer{=z;YLUHpX~DV`utdh0BqZ)yGEJF;{yko1P_E8a-WR7j;ZQy%6-wO;?0Hd7#n_N!6C+u7{C(CJP+ zS7j|cAIi-3hSykDT&SvwfY%a@lq+`!-d{f&z`PkfVxQvVPn3>}9i)_4*rqaM$chYR z3FAl6U)DU-4VyWpJ|bxUT7cCmG8E&uYl`cU&X=aMZ)VSC)OTc7WS-t*jy(eglIk84 zJaSfVG>-Sv#*BdfIGSnuO>j37j3y2mJ(5E#R<=44#ZG*xp$knIUerHp6hU!f8i+bg z>NPviCBp3%KZ>dP5jhDHz6f>k&2Vc}OJP#NSp1yNJuH$-KDBjo(Z;~W*2~<1J*Ubs zD1@e@@!psh63hD}bHpp726^r|9C{N`@V%rL-^V}!@7)_mC5A~_kF`O)zty&(rn?AX zyE!!SQ30?&8rOD9(>`E+OvYxf{$LR2m077Ot{DLuel455`*`N>h4Z1}Sa_ks`eu}(So-XVFc^Gf`xGW@3ko6dLMATZWF3U=&T;d(o%tjzN1&nfdh&|a1eE{82LJ4l^S{6cCXBNiXQFhIV^Fe7IX?u78ESF-zDEi^K-wx(fU!xdA-Et<&3dnlF15T zFJix zi&=>181Uo7bd}Q1*ftioA(35)_KhByF!XPha7r@dd3-YM!atXsFq}>Cxh{gN2BB-c zZ&sJdbED1~W4bb9pVjKrI5NbGw+9NEv|uS`Ds0|%?x45zrQgR6ubRvyWotpv2wTAh z=8Pu4aZ=>W|GG;EuyQ@r3V+yUyM@9^@tUV^3!6NRw2-ac-jbNO$P(*pjZ@-s`!RD5 z|GeCG7D;wnd=$v`mxBQf7it=*d5a%2;Ej~})t32fbvxO-N70+JsSMY|#sks=O3tZF z%r>=amHi0sxk{n2sF*h&!X|Qckos!a@dZQm)UVsRU{LJTvZR^A2qACUi@VsyK@lB2e@(z?1G6J<8Qv2pjU8tyDwEq+0mYlh%T* zGiomyM$^BJ4>xkJv$w}e2^-_*c9t7hd3K`XKJO0#*_w6G=sV<1ym-%XEViD}@w*Lbg(aJ8vw(0G3E3AC(dZ^yI zz&CIE>|AqwBnnI^S(*(mHT1b%LV<;=y&jBF72YxbHR?FOj&5b!6?1u7=E0ZNajguQ zx5{<8yVVKOQ3AgtHx=a+3yZUi8uvftBCC+ZBkezoR;xU5sJ(-*Tod_2*bJrPH2?4Y zb{&Ga6}Fb#s~(-Er%`^WWD4o}augIeLZAEswB7>e`cKG5x>u({j?#z6{%lNmU`io||lI z_nw5_`Rd6ksg+m}!?A76mHW?zgqal?$%ug9-A~h zLCYcmbt!aH04Q2s6#x<9yZ*1z9Q=n6$Uq1%B9%3L?8>vLpY!dAt@dYVJHXa~zh47j M=9XqPCN7cx0so(3y8r+H literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/center/gap-2/flex-end.png b/demo_app/test/flex/row/center/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..6ccf07fa293717beb7125320c77ced2ac64d87d8 GIT binary patch literal 3022 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 O2SAK04J-8TNBsqt8=h|f literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/center/gap-2/flex-start.png b/demo_app/test/flex/row/center/gap-2/flex-start.png new file mode 100644 index 0000000000000000000000000000000000000000..f71976a29250cf23df187133bb95bdb2edd5de97 GIT binary patch literal 3288 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 TQKz)mod94C&h~ZZFDL&Sglkix literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/center/gap-2/space-around.png b/demo_app/test/flex/row/center/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..f15a4b629921896894fe1f1ad4c7b13e680c3c04 GIT binary patch literal 3678 zcmds)`8ON*`o}{TYKr;R)*8|kGuD!#G-zvyh`m&8iH?fazLeNgZHJl;YAIqJBs5Xd zHkKxYs#d6|3e^!JCAKtnVheKh-gED{_n!0p1HRwS51-|n_xU{Md7g9L=Xs?$+CwBI z6eR!vfF#t~!WjS%0q@_d#1HT9kW5hi{vi_S47m!Z`>4d-e;kaw3Uv|RUkT#39svMS z;!uk#E-}UPtoXaRQ^~Yt_GosuAM&cT=(*!(Zjm3oJ_c*@agz5usKaMa;xn{(!;ush zlY01&Z}7{!A&(LBDA;3Mb)(k@d~g4C9&W_kmEiyW(1^3daqXWR$tvPUx@}c4-Ckq6 z9H`zw>v!^cGNp?%N>Uwy*4UX7N7=EZ8_MsVE<`Aa+&eTn3D#;QZ2$P<{_oWYrsZknX~V$7pHjb06;Q{i9^^>B#?k9BQu=1cS6-(xeRxao%2WlnFaoCdw|3mnu_ALGS*?L>Iim9U%NdQRWKCheio z`e!#mnXp|9cR-B3mnVOR|7}lzh-oiwu7NQd?I`QaWSTLmZmrr3+@y%%(mt`rMh_^(M@!cVfd+P zdV{TFvi$Ha7srrJdNPb~xg`ohx2|=Zw8{5Y)k1`kD@;n*K9EL*csamgJ5_dQZ zf-6#JX9$JmS&K>AY>Wl|N(w7qTk1dxiD)hF@ZVy`RA5*i$L$4_7?8Iz#hC3^tw8J& zT(0LCxe*H$xdOJ~Oz|bRxHTskieS-jobpY5bv0Etw6q?XULS;s{TRR4JLgGp`Os&` zsUzlB*=~i+nC3@J6Z3ZCAva{Qk3bp!lL^rfJxv`>aP++fg)-1q8N4zL!Wyw(D&4la z{!a}8%e1T$n;oaoM~r_P%q(8~qUKw|+H9b)q02$9Zs?2dVdGi2<`mA)lzk+ z4Gw$g2RbMHCtPOIpoN_tP0Lf2y7Q|3PR{T;-obD0(|$iNa${i+FsJcq)(YOYfQYE4 zYon2v6W5)x*3v_*Wz-6FOM>_TAkT#96RSL}M}I1bgGMh`AbV!|YIWd;D+e!bK-V{?743O(~N$1;UoPT$lpb{j9KDG=0aM{9T>h zdv|UJWuI*E+R*$-tvl!Sx%VyE8d@%y&rJhK&Em5$N!whL7iX8li zdAu&kUK=^g;@1kHhI7wo+GnQ2imP$2tMgFtP9onG%vYO@&48S; zu@qx&5j)o)G_Q5j5;PEayGyCa1{3J>z@22pe1#J>enA-a%wB%8Lm?0E?EK}6?2O)E zF_;YuQeWXksdJbMz89TBPnnmu)1p+BXa{xNOj9CW6(5EBspAhLN(;g8bS`FUej~1d z&HH@FBve7>*b(LBn6;w&XS{)iBytZ&m+I(-oF!6w_1kU_ zYU;X`E}79WAeyGXLlc&|bX8`uA+VRYyLT?&nq$D zdBdYSNqCBJWWKWrsDjVKl?g{R59l;&M)sp;>_HFWW>1qeOF@vr^H-RZ&vU~5OgjJh zOev_mrY6U9^#pgB*1IS96J0X-a}CareL+y=U^sJ;^_;sIF2ljWaL^pOUD{u#+#-SK z(NTUa(U4OH9`-WyY8#tllOV>?wv;U-DX0YOUZ`6sJeF|YZ13gTlunUfH0-g9M?hz; zMuc8W_T6|$^N{SJhG+F&TN#x0Ze zk_V3MfOlt2Jk>RVLy~Jx#~Qaxt9A$aeK32QO4dzSHr2Pi2#3_V0k4I5I<~hx9P}Qm z9U9h3G(5eZuq`^>h^?vuVx|}OCvtcPAct=wi`9ZyxdA2PgBwQPXzeqG@5=|aKlFZ$4?paBdOoG z_oVAXSgk?QBIbX5=YgemjuPnf#VaUV^4XD&iyEpas>pcp%Vr04XoH6XUE`gC8&gG! z^KURj|G%Tc->GRIu8M=CMFAFW=>d?{%HeAMkm8c-H%QuIqkZ_x;@0>xGS#sqj&$qW}Ov z7-4qV769Ob?azyj2=4c$2^#7917D!6sSyDGMTW7z;14uH*dN(%;YU240|3WO5SI<@ zgR`0AArDeGt(~iV70z8`(Id5}Q!j6bx|BH<_>_b2pqkOZC7dJVQz9g&R0vv$RKX^G zo4p1lWDmu));}+%+6_t=(xaqjJi%jK5R()C;!k>GnT9ye+nLSscpURA$*g~p$FcVM z5#p6QDay*7T!SUQP#Q@y{|z8BCHs>P@cxC-3gAN26yIIJw!>4$o(jE};f zN|@~PHkOb5d`kGOjb@<$UE&z~+*UhVqeu*v%^t=H{D0m5N3Qp$#>yN9Oyz{xXRVI& zi(E>GSd%Vo2zqP!6~3hy+`Stt3fPF3eYmm&RsQ-kJAB;EsZ0p?QW0??!E`Stxfm^& zj%H2W*Uw5We%={z>Y?#DW1W=aOyZtFp4*w2SGKSEln~~KOjwgkYFj)R4xQo;Ub@Jb zG6YK`bC*&39Nt!)g@d)9yaW)s-i|xX?}r!7y|=Y3JABC zCJo=@`VI1S?wfj^^Km;Y(bQ@{;qtQd7(l^wV4oBFQPq z?(nfbn0o?m!Hr%Ursso#=qHwxIR&k@NnZUaxXu&umO!LwZoB?8$APm z3&b<;2wVWi zOS)_1w#VTp+wESkI&TY4Pwg|wh45{|8^l4?1X*Zrrswo%b=&JW2M2^2+2^y;)g;xH ze$~DV_qyf`jc;}NwdWbxfs3pPXIq#*Us9m}u&^rJgvh;-r4m$JW={MeMS=z7vKhq# z!a8P@jp+8OTHCE5!kx{$T@R&;`=V`4tl#lcL@blDB3vhT8wJ)X35AJga3b&&RmvEM z7q79nRTJMpz*r3YqH<^CN8iPfen3Nxeg zYo+_{Z+?BQE%20hb^z}nnGu@5^w|Hb>^oi-Z1iN;{u!5iY#!Jywg!1sT{- zIp3Z_AzuoS1}Y#v=E>p?)0XY(HRY{86l7zXKTRYScw9G{{)QY3^>bpGwT&JVZ$-UJ ztIN{#LF1)V%kAoinHd{_eIp`FXqD6AP(=-jkSUdwDC65J#rUG9;wP=`Bnk@o+Y2)? zl0<`QX^jxwJBIO#`J@QKL?#&)T5s>?lZG&jRtXyTGaQUW;1iyHGI6Ogs^blJa%DcRoMzRXrO0N6B7q*I+~b z$~Dlqz5p7iXl)+kIMgM!UUKtlqV1EE8>X>y0o?Ln&r&JXizUGkmd>O)hx#(721lxy zD-ZM?)8qK4-7vaS8|sb3vv$?oIO#*BzPAhH=a`?|97{6M>riS;@(%2&>JROJ{~6Me>B_ z^=EDl{h|&4O~db6&ns8z(Fyd5py6}C-Q@`Hx>~s%v!jBz{cv5c0WCN3-c3Gr%zb{K z$0Gwu47P{G-PjqOT}KCx;q#>87?1mk)9VBoGtYZ}sJ^aWpjH^_{^a=C!-i(HU8V!L zP;WHeptZCNs(N)^6XJyK)UU$|+XmmMlQ(8gR?k^TG+a9S*6CV3dgsgBwB1Jt>XzK? z3|3LfuZ_N3)`)c~VZ6BI)#etv2%@NwWNzknvCi2!td{gNz00a(v!VzuS+ww@kC4$l zSc={0kY-Np^y<)8&&r-i1*%pb-Yj>dbG{Z}(wck{QGGp@RU}LnDo@?`MpM5(k712l zoy8F9iKEy6T2=Z`W!;>(I0N-%iT_Zno0^)nDXwt{D}G9b)ux~P=ZK}%F9R}qXjm1a z3EA16Z)BE1=vw2g$WbD7XaQ5viXl-r$Q5(3-^S@D2a-bsGO1%FDTT#>YeCk5W{TaH zJ3DNNWvvdt`>Y^Sivk5-Bh7ctCOBeU^EL9WRL^|2+M;8vJ;OXQiAWCYjr0y83|) zwE2`JkBvPdhzkh+=w-j$>P;eaf1mbN+YcI})1@U{LzNZv8TkrYn#0aLrg9CaVJN=3 zt|5s%Xot=IH66?JxZ;mzs_roZ8n-jN@2ubZDi6GUu%m{8jAN1Ov$6&*p-e4cH`S4@ z-u5L~fwI@y+cOdT5#;`XpHY;x`1{OEyY^6pa#kwd1+0SfqPH#^koIO1=(JDfjI9Oc z1()K9j!}9e4@rptO)ynnZRHt;WIEfI#oL?H2+>+9W8uTPVrNdE<^mj?KScZ$t2mQ6 zI8pRMRterOnV!4uE7d0))JxV?jOyHb-4$%*(m-2;-hNZ!RD!h9qm?J@on`tGDORRV~o90`=sey>;e$>um5S^z?;HS-r(3nsvnO1vOXY9aehdVom2_Jc~y0@7yyw z4ZP-kH-ZDzYrD5TuD#~c*po|N8jq#OdT!naPLw$?=%Lc+0QyqE_SHDP`tp!;eAp~8 zvT6Jjw>-QXJgQe|-fbCn>&UZ1EFJzqZK6Yn^xE8uFlumwG3^oTo;9rk|C9Nz29W@} z1hhNLCL=9K+ggR|B> z<(IKW2U#A8%0HCE>b=Ain@|Qh>bzYoo_pULqlB<0J zvD(t)_otlAkkSYQc>_Nt!Ws-Vj7pO1Y_yPu#+S`ic%^PP*gvs(>mGKx{bd2f)!9$! z0t_5&JzsH=?6i?3p;YQ|uCyc2*bk;N$Yl9AUl#i8M?zhXbRNG&a~Du|80R9k1QSjY zt6lSf-*j->;Deg?ZKES{?7DAZ=eV=X()dHgzV~v!8R`7>@9^L!2LsO1!RV@=;j=Q* z@EY{%h+mrAjY|GHqOa;1v(FqYtHA(qe&B=7VS{j24#LBz``HuFq5g7LIPB&DgZOI# z`h~o6I#g8vX8U|%alj}4*;w&^l=Y8ZSl6ngO8qq4r?dCR{+Gu7$u53RX!v+OY;2&e Ra33%M2otNzc%z$7{|l3>DKr28 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/center/gap-2/space-evenly.png b/demo_app/test/flex/row/center/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..b90da28c9e4654f3290ff42e6244265bdd7c89ab GIT binary patch literal 3727 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 AbpQYW literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-end/gap-2/center.png b/demo_app/test/flex/row/flex-end/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..0c4e9bf299efc86196aab4ccb93161be03136272 GIT binary patch literal 2761 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 UmpHGOgK-o9GPf}!m|RQx4?5H)qW}N^ literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-end/gap-2/flex-end.png b/demo_app/test/flex/row/flex-end/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..3be226437b784a3fc95a638cd96175fe0a6b6b70 GIT binary patch literal 2766 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-end/gap-2/space-around.png b/demo_app/test/flex/row/flex-end/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..3d312d81a700aabd9ed3c61b82c04dfd469115c7 GIT binary patch literal 3615 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-start/gap-2/center.png b/demo_app/test/flex/row/flex-start/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..f7eb553b18716041a955fe95164778c692b44619 GIT binary patch literal 3246 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 N0CEEATJ3x`vPX)m6jcL)AFpj}C5Uom zriFK|N-NE*Y#uX-WFEq;!1C7nkPA&~IUYS?8lZjWZ43?oC<00;+%np&1_=A%3}Eo5 zH~`6J3E+KqY{&BpOLuQXmi7@aJyH8Poc=EYf99&8s~?w(^Q!hWWV1~X$My!zbA(;a zZo5tgeCf!_*@*S}L%j6MT>c!K z8$~E$ogyQigSGZoR?ed>rD1SAtHsF;{Uc`V+IGx!MzMIv$AzQpG?U}g%kk!Ef*2M# zYB`xIEI)J7&WQ70{@6UcexsYJH5Q9&|*_xY~*H1)&?zWT;du)Q)SaCB$Ypb z#1n_{^CoEBI;Vh{mpkBKX~|mPmTl11pT&%|*W|9x zl!5(AJarsp6dVhUG4mU1P9+lR{`=Ub>mz{;yp$HDT5l9sD`ev_bcE!6S;Vb(ay*VN z*_<1m0GtT)m8+Fxp08K8B(J&)A0K#;Q8ZC~&xVe_Zn9(}cru2r z%0eP2RpJxlt z>z{AtfYI+HF|o6A(V)B-X!O~`5oS)3B3D8UcyM5(Zfh!BNRQ?t|}Lq-^ATB;qb z6dQ*l_XO|9bm_Sh=YJ(M9DN2Zt=v*f4o!|GOQYAcc-WG@S7)xYim;wQOu@Up;(@hw z2K23!HWa(z*XVe7v$8JueqDU+s*vI|1iP~HKyG1_aRk|Fu+(nK+j^5whbUYX3y!0z zt68;7ETqWL9Q`-B^27!G4O;4+NlqAEPVbQQf?G=9)EC;lZAC(TwW&4rNlf|B%LLQC z7NAh=f_^Vu{?dE)AU=&Mic_CdwQuRzv*~0`Ks>CJ%_*~ldppTBX)!wm3R*RZkJ7g; zUpzN|mmTlTKCqBkDdd}-cs@-~nvR=dnp9BJI%W_rcM@u%VoF>J%SUQ8m?~|KIt3RZ z6s)g%1s4~y*lvYvzEIH1U#?|(S&KeI6cXvV*5R%`EAb)Ywpym+^vK(G)~U z@U@QFw`fmP*{Ao@U#!47GxxC4)!ox|1|=R>@T51(X7eky3F?R5V_&YKau=UnQuJM6 zFmVZnh=CEUEp*GO3 z-f?#3aneW8joQU5J#0+_B40GWaY{`+pr~%F_awTGDaU`V(qB|Yq~5%1)2i~_Y*AiQ zD!isLd}u(gtlk%Aa@iNhG8|yIb59Rb(CEh9uiC_%gmr)rHZxALV;S2jn=1!=LSW-yXCH$yHj&)NE*UeY*8v z85ylii}S{xcfW_8RZPXFT-D{4Sdnaz@Nf=p3p;L#HZT6DTw8H{chFRle6u?E5@y7Gy8q76GoIJvmBjLD5bTp3V10vu%1FrgJj( zr)sF1D58cAg6I7MmEi_3VO)3@WFn%lz_-YgS<&oyO{X%-KEEilY+R(S>chp`I>EQs zt$cU&4rhty0vtjOBqPw$kA&J=zOZp}clYDbTPG?$S1x9%Demi>ok-ff(B=lyk%Alc(ZT{wxq!lVxA@!PWK+;O#09`h%TtGpq#h>Rqw`m@iCV=&slc1?j z=M90IV=}DS0hUU{<148XDpR5s9%#DQWF2**^!JxHTb|;}=q0FI!c~S`RRPuMh{l3O~&JbZN>&X|Pdd{0F9EGpocJ$)cW$vu?)~idGA=FG(*4wHo zn1`46TU|%SQHG8)0i_9Sy6O;{I1$Yzr$73>66RNB{-`hte~Yqhkd$}O1b4?tZ%~y( z$~$!GD!scKmJ|{YU&5#lS|?K+%SqS$yhd-CM9ad-TG~x<-pVWY#Q9z8Kg@j$an+7! z9e`E$PQHC}ktRGD!UrRL#TnMw(o13i-Y;C=z3?mcx599PgPMcYr-{wCcku14^HR2u zD?*vWhI;u;n>V!f>eG|v^!cYt^y!>79#tx6E(B?`k3PZ7tR6}*dsj3l4)L?hRS*s_X?Jq#12y)=ibr&LV zJkwwrvjU80_h2Kdk8Z?JEXo7VxntIqj3mJgFXUJZW*@{dO>NwPrrqfe((K>&uux9( zL2LocKrHzz^DU~z!e@|NOr5_Y*Trj_Rznt6)_PP?4!2deZhob=EHqz9tuA{7JEkOX z@;7Jk(4INP+a z)NQ3mIby~ddy(?Dj5BG89gb8(Cwz0Bw61`te6r%x?^Xq8ft6|He%m5_n-uq0?EHGs zXC>!3m~@O{LUJrGjdt;w#J<=*Ch#ev+iF{3##?6P@I}x05dD1e&UD&b7>8Z~$$pfvS zy3SG=XN=~qfq(lzWgqQV0lU~c^X2j#;n#Hoq;mJ1f*k7Qj8sP6^uAq0jD!wL>4)Ob zq+fu`3Fnr@=b|%rKspo)0yPGx5aQVL3QpVW{U7$Bf%M$b*HHlHTqB+xO+ZWyqU>D1 z<%`2qrx)Mfc3eS3&l`eiro_KBT~F21%-4%RF8`dT-s$g>UBtlj1 zG6g)Fj+io|UiZ7fO1ryIpV7tDqdO|Y1}QItCj9-TEocdpS*1qATxWI_-NK}7u8ICN z`-r{rH}5uSYvbnauNa!rp+5?})+bmJ0}t;42OR=<{M;+60Qe(Uez|?{q-bFT85(>? zD-3Zml!nFQNMvHjKb>H3zN_BOqyQj0*YjlCfII&HvLLi< literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-start/gap-2/space-around.png b/demo_app/test/flex/row/flex-start/gap-2/space-around.png new file mode 100644 index 0000000000000000000000000000000000000000..2e3773c564086478548ab9b5091fc5d281436fed GIT binary patch literal 3850 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/flex-start/gap-2/space-evenly.png b/demo_app/test/flex/row/flex-start/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e175e67a37738c45c61649325898aff6df4434 GIT binary patch literal 3971 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 WB$M*o40%EtU~6S(S$)+j@jn4zHQn?8 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/stretch/gap-2/center.png b/demo_app/test/flex/row/stretch/gap-2/center.png new file mode 100644 index 0000000000000000000000000000000000000000..61918c20bff40a3ec0f9ae70bf602cee1a9b0feb GIT binary patch literal 3017 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/stretch/gap-2/flex-end.png b/demo_app/test/flex/row/stretch/gap-2/flex-end.png new file mode 100644 index 0000000000000000000000000000000000000000..a94eebfa6a54e0c21e7b79fb6d242f46d477d726 GIT binary patch literal 3043 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 S#2rZuCXFGs6Y^;SRj#( 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 literal 0 HcmV?d00001 diff --git a/demo_app/test/flex/row/stretch/gap-2/space-evenly.png b/demo_app/test/flex/row/stretch/gap-2/space-evenly.png new file mode 100644 index 0000000000000000000000000000000000000000..5b94496ccdf592f98bdec980e50ff7e3a12f9205 GIT binary patch literal 3778 zcmeHKc{CJk+aIN}WSN9yDQlv~HiT@6(qzw)k}Vo}>_&`rWLI{D!5CDQghIx?rr|Nn zBU{2429w3v8%w z4J%lm2}>V)I)@=sn>N?i;vAfdZPEv#OJW7jSu3e#M3yd`KQH}INapsiVwr>`Bzcsk znI+&B&z-1#FM$JW3F={wwN$lZ6tlSm(AR5Q)^?|TXJ;?rHVPf=l+bRPx~K{4&>B4w zN8hO9Y^8>@<4#nYjQaBeKS#B6oVhF!P%8_Qc*1qc-0)*DAt_Pqyf*N2eDoEGaf>a( zuNU#uusRpK4FZ?fDef@;x*>{2&?R^MB)o*75>^(Gt`E!(;YG1w{IMw;> z@WfI!&r)WW&9&czI$hGvM5PZ5_7(S(@8+Uf{i77Et+&xPBPZ03${Ld~oH2|Yq5cZO zO6A<3y0}1$1>1Gsc%USNA0Q8Tz|Aj_Ht;1U$}o&BY;&5Rz%wM zZR6(_iE{g1;MCSkqL&q_Or+i^Eej9ZIBjst#=&O{js#3HvCy9R8dj?5_^eJ!|56U(FHpX-w+ea+%A)1+SG}TcuvJw)X{W7WyK39Zcvx{QXY$m*s-JyrxB)R zX=B32x>_7crT6P$!&K21{w3UI#98}>&b|zpc0iqbeqy!VaGBx}ILAs4 zrmZD1Uu$>%M)aDthsC$OG%`-!FGAz>+zM%J{8QxdN|hdjts`Q;%Rb zI@063t3>u-8f#>w8*kP~IJw}a?+PDmx!wltiQkuQqCXeW;Kher5!TG%Je*-#z6tz^ zee#Re!%Q;ol+MY;v;^nVrl048v_eu4ryK(_LXM78K}3KC*EpPMTVBr;Iz*UTXYA_x zv=y$!PWdLR{0=JJ@M&Zj(&k&jzL;f>iwLVL2p5tHLE>%m95f1Qt^kVl;>CIfZN%1u z_iE!mu`tOze56ZaAck+42Sx3Ev+2(kyxuyCu@kI8;QEC@_Af8Jpr1s$wW7&M`n=oW4NPDxL^ZolJ zMvCxY<~Bh;(GYuoWD|E9`pcrca#bj$!fFnRijl90%{*7PU?PQ`%9NIA%yHy6*h4%G zkbBy#;$ITN=;3ik>AA)?o$f>i=OHF@I=mnb2JxMnaNi*=p(hYHvStd6OD4Ns8c3BF z*`T*iAsrNg(cbwj>CKWrmM0n) z1t|Mtm2>zomk9;FcC+RBrnDdl9v#-24m{P~@x2J9PowZ&+IzWYH)W_n%M092&(+uJoV zz5HGofUkL-sjZOm1*KOc#q+If`{1;HbJ?-demK8AgC(Q*gE z3(rE)(l2-ur|!Oyx;p82k32hAPdvURD6Q^`)ETMrM{3EXSB+$UJhdoYoc0Bn0xlH6alue%{%Z%>e9iWm>Z!LE7{=~?p7Y6QKylTh&JyV&|_ z@%8L8#*@oD7OUji+Vb36S9-o0eq7ZQl$!r2CkJ_g@$xa01IJ(tvM@cLM4I8GB$zDR z<#MtA`lyqGQHi!by_Dmzkf1l|%XdE;(IkC;?ns8tIsQpRWyi2NrPtIj!N~8u!&z8G zw3|nCeB}xoYSOIN>GV8%SW=oMGR>{v?KrL2-`hc$BP3zF zkERlf$<2Mw`90PsfqirdD8#=KT15=%^u{axJC*D`rD0CyUz-e4rg(R392St&TL}0cvSE@ZqcTp27}Y%SGbqhE%8v z-#zL^DWQW)Cq?z`8?acwX4?dIO$iQJ{>YkYs4+ zPJ|OFu(BCFXoN2gmqTIkRY91Udeq4Hs^<*5I&&XTF>gKbIZ!|E_|q1-<_KIS4&E6j zYcysxLF@b$?@@vzj1>J_@~^Ldt!ZNfQO5K4LqR4b=4t>LC+A=vFI_QBHf$)dn)(4&JPNT(r@Mi zGc3h_%IutNC$2Mwnn#oeMj#1+d76B>yI1S7!jBjXoje|e9NXu%6!rant=Hxsq`DOc(jaS9w?1RPC(bag4WHqII(C zpQLF*vGD^9-b)D;(3I#Lc@>2}n6_pFKR__nph&^FN{*Y+k zs^OSGNIj=5u86n2bn?0luf{YPZQjbAs%TK88>I!Q240*n^K)l!m(eTyltUOg*IL!S zwzeth)pY`DZdTh)yA4&Oz>G;&$Vg47;S-C3?0!?$;Men>+Zh)`%KSrh5K#!E^uW2} za%V;EzL{#`DW!SYAFC#kW-u~(C))Qs=$V1^vh&NWTwbz1!~o;3rRp?lNcMc+n5oe1 zddqN#jd-tFcIt8Jl_eQ%IgY*fLm#So_o2lCKzi9E_tp8%`|IOw98~sz&{2$5F1DO>Kh7KDr jBTFCjZ>sG-<0Bt28McDzSeb}p9SQ*7HZ!cg main() async { kCssAlignItemsStretch, ]; - const List gaps = [null, 10]; + const List gaps = [null, 2]; const justifyContents = [ kCssJustifyContentFlexStart, @@ -482,7 +482,7 @@ Future main() async { for (final justifyContent in justifyContents) { for (final gap in gaps) { final key = - '$flexDirection/$alignItem/${gap != null ? 'gap-${gap}px' : ''}$justifyContent'; + '$flexDirection/$alignItem/${gap != null ? 'gap-$gap/' : ''}$justifyContent'; testGoldens( key, (tester) async { @@ -524,7 +524,7 @@ extension on WidgetTester { class _Golden extends StatelessWidget { final String flexDirection; final String alignItem; - final double? gap; + final int? gap; final String justifyContent; const _Golden({ @@ -539,7 +539,7 @@ class _Golden extends StatelessWidget { final inlineStyle = '$kCssDisplay: $kCssDisplayFlex; ' '$kCssFlexDirection: $flexDirection; ' '$kCssAlignItems: $alignItem; ' - '${gap != null ? '$kCssGap: ${gap}px' : ''}' + '${gap != null ? '$kCssGap: ${gap}px; ' : ''}' '$kCssJustifyContent: $justifyContent'; return Scaffold( body: Padding( @@ -548,7 +548,6 @@ class _Golden extends StatelessWidget {

$flexDirection
$alignItem
- ${gap != null ? '
gap-${gap}px
' : ''}
$justifyContent
'''), ),