private void MeasureChild()

in src/Avalonia.Controls/RelativePanel.cs [292:506]


            private void MeasureChild(GraphNode node)
            {
                var child = node.Element;
                child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                node.OriginDesiredSize = child.DesiredSize;

                var alignLeftWithPanel = GetAlignLeftWithPanel(child);
                var alignTopWithPanel = GetAlignTopWithPanel(child);
                var alignRightWithPanel = GetAlignRightWithPanel(child);
                var alignBottomWithPanel = GetAlignBottomWithPanel(child);

                if (alignLeftWithPanel)
                    node.Left = 0;
                if (alignTopWithPanel)
                    node.Top = 0;
                if (alignRightWithPanel)
                    node.Right = 0;
                if (alignBottomWithPanel)
                    node.Bottom = 0;

                if (node.AlignLeftWithNode != null)
                {
                    node.Left = node.Left.IsNaN() ? node.AlignLeftWithNode.Left : node.AlignLeftWithNode.Left * 0.5;
                }

                if (node.AlignTopWithNode != null)
                {
                    node.Top = node.Top.IsNaN() ? node.AlignTopWithNode.Top : node.AlignTopWithNode.Top * 0.5;
                }

                if (node.AlignRightWithNode != null)
                {
                    node.Right = node.Right.IsNaN()
                        ? node.AlignRightWithNode.Right
                        : node.AlignRightWithNode.Right * 0.5;
                }

                if (node.AlignBottomWithNode != null)
                {
                    node.Bottom = node.Bottom.IsNaN()
                        ? node.AlignBottomWithNode.Bottom
                        : node.AlignBottomWithNode.Bottom * 0.5;
                }

                if (node.BelowNode != null)
                {
                    if (node.Top.IsNaN())
                    {
                        node.Top = AvailableSize.Height - node.BelowNode.Bottom;
                    }
                }
                
                if (node.RightOfNode != null)
                {
                    if (node.Left.IsNaN())
                    {
                        node.Left = AvailableSize.Width - node.RightOfNode.Right;
                    }
                }
                
                var availableHeight = AvailableSize.Height - node.Top - node.Bottom;
                if (availableHeight.IsNaN())
                {
                    availableHeight = AvailableSize.Height;

                    if (!node.Top.IsNaN() && node.Bottom.IsNaN())
                    {
                        availableHeight -= node.Top;
                    }
                    else if (node.Top.IsNaN() && !node.Bottom.IsNaN())
                    {
                        availableHeight -= node.Bottom;
                    }
                }

                var availableWidth = AvailableSize.Width - node.Left - node.Right;
                if (availableWidth.IsNaN())
                {
                    availableWidth = AvailableSize.Width;

                    if (!node.Left.IsNaN() && node.Right.IsNaN())
                    {
                        availableWidth -= node.Left;
                    }
                    else if (node.Left.IsNaN() && !node.Right.IsNaN())
                    {
                        availableWidth -= node.Right;
                    }
                }

                child.Measure(new Size(Math.Max(availableWidth, 0), Math.Max(availableHeight, 0)));
                var childSize = child.DesiredSize;

                if (node.LeftOfNode != null && node.Left.IsNaN())
                {
                    node.Left = node.LeftOfNode.Left - childSize.Width;
                }

                if (node.AboveNode != null && node.Top.IsNaN())
                {
                    node.Top = node.AboveNode.Top - childSize.Height;
                }

                if (node.RightOfNode != null)
                {
                    if (node.Right.IsNaN())
                    {
                        node.Right = node.RightOfNode.Right - childSize.Width;
                    }

                }

                if (node.BelowNode != null)
                {
                    if (node.Bottom.IsNaN())
                    {
                        node.Bottom = node.BelowNode.Bottom - childSize.Height;
                    }

                }

                if (node.AlignHorizontalCenterWith != null)
                {
                    var halfWidthLeft = (AvailableSize.Width + node.AlignHorizontalCenterWith.Left - node.AlignHorizontalCenterWith.Right - childSize.Width) * 0.5;
                    var halfWidthRight = (AvailableSize.Width - node.AlignHorizontalCenterWith.Left + node.AlignHorizontalCenterWith.Right - childSize.Width) * 0.5;

                    if (node.Left.IsNaN())
                        node.Left = halfWidthLeft;
                    else
                        node.Left = (node.Left + halfWidthLeft) * 0.5;

                    if (node.Right.IsNaN())
                        node.Right = halfWidthRight;
                    else
                        node.Right = (node.Right + halfWidthRight) * 0.5;
                }

                if (node.AlignVerticalCenterWith != null)
                {
                    var halfHeightTop = (AvailableSize.Height + node.AlignVerticalCenterWith.Top - node.AlignVerticalCenterWith.Bottom - childSize.Height) * 0.5;
                    var halfHeightBottom = (AvailableSize.Height - node.AlignVerticalCenterWith.Top + node.AlignVerticalCenterWith.Bottom - childSize.Height) * 0.5;

                    if (node.Top.IsNaN())
                        node.Top = halfHeightTop;
                    else
                        node.Top = (node.Top + halfHeightTop) * 0.5;

                    if (node.Bottom.IsNaN())
                        node.Bottom = halfHeightBottom;
                    else
                        node.Bottom = (node.Bottom + halfHeightBottom) * 0.5;
                }

                if (GetAlignHorizontalCenterWithPanel(child))
                {
                    var halfSubWidth = (AvailableSize.Width - childSize.Width) * 0.5;

                    if (node.Left.IsNaN())
                        node.Left = halfSubWidth;
                    else
                        node.Left = (node.Left + halfSubWidth) * 0.5;

                    if (node.Right.IsNaN())
                        node.Right = halfSubWidth;
                    else
                        node.Right = (node.Right + halfSubWidth) * 0.5;
                }

                if (GetAlignVerticalCenterWithPanel(child))
                {
                    var halfSubHeight = (AvailableSize.Height - childSize.Height) * 0.5;

                    if (node.Top.IsNaN())
                        node.Top = halfSubHeight;
                    else
                        node.Top = (node.Top + halfSubHeight) * 0.5;

                    if (node.Bottom.IsNaN())
                        node.Bottom = halfSubHeight;
                    else
                        node.Bottom = (node.Bottom + halfSubHeight) * 0.5;
                }

                if (node.Left.IsNaN())
                {
                    if (!node.Right.IsNaN())
                        node.Left = AvailableSize.Width - node.Right - childSize.Width;
                    else
                    {
                        node.Left = 0;
                        node.Right = AvailableSize.Width - childSize.Width;
                    }
                }
                else if (!node.Left.IsNaN() && node.Right.IsNaN())
                {
                    node.Right = AvailableSize.Width - node.Left - childSize.Width;
                }

                if (node.Top.IsNaN())
                {
                    if (!node.Bottom.IsNaN())
                        node.Top = AvailableSize.Height - node.Bottom - childSize.Height;
                    else
                    {
                        node.Top = 0;
                        node.Bottom = AvailableSize.Height - childSize.Height;
                    }
                }
                else if (!node.Top.IsNaN() && node.Bottom.IsNaN())
                {
                    node.Bottom = AvailableSize.Height - node.Top - childSize.Height;
                }

                node.Measured = true;
            }