File: GridLayoutUtils.cpp

package info (click to toggle)
webkit2gtk 2.51.3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 477,912 kB
  • sloc: cpp: 3,898,343; javascript: 198,215; ansic: 165,229; python: 50,371; asm: 21,819; ruby: 18,095; perl: 16,953; xml: 4,623; sh: 2,398; yacc: 2,356; java: 2,019; lex: 1,358; pascal: 372; makefile: 197
file content (128 lines) | stat: -rw-r--r-- 5,761 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Copyright (C) 2025 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "GridLayoutUtils.h"

namespace WebCore {
namespace Layout {
namespace GridLayoutUtils {

LayoutUnit computeGapValue(const Style::GapGutter& gap)
{
    if (gap.isNormal())
        return { };

    // Only handle fixed length gaps for now
    if (auto fixedGap = gap.tryFixed())
        return Style::evaluate<LayoutUnit>(*fixedGap, 0_lu, Style::ZoomNeeded { });

    ASSERT_NOT_REACHED();
    return { };
}

LayoutUnit usedInlineSizeForGridItem(const PlacedGridItem& placedGridItem, LayoutUnit borderAndPadding, const TrackSizes& usedColumnSizes,
    LayoutUnit columnsGap)
{
    auto columnsSize = [&] {
        auto columnsStartPosition = computeGridLinePosition(placedGridItem.columnStartLine(), usedColumnSizes, columnsGap);
        auto columnsEndPosition = computeGridLinePosition(placedGridItem.columnEndLine(), usedColumnSizes, columnsGap);
        ASSERT(columnsEndPosition >= columnsStartPosition);
        return columnsEndPosition - columnsStartPosition;
    };

    auto& inlineAxisSizes = placedGridItem.inlineAxisSizes();
    ASSERT(inlineAxisSizes.minimumSize.isFixed() && (inlineAxisSizes.maximumSize.isFixed() || inlineAxisSizes.maximumSize.isNone()));

    auto& preferredSize = inlineAxisSizes.preferredSize;
    if (auto fixedInlineSize = preferredSize.tryFixed())
        return LayoutUnit { fixedInlineSize->resolveZoom(placedGridItem.usedZoom()) } + borderAndPadding;

    if (preferredSize.isAuto()) {
        // Grid item calculations for automatic sizes in a given dimensions vary by their
        // self-alignment values:
        auto alignmentPosition = placedGridItem.inlineAxisAlignment().position();

        // normal:
        // If the grid item has no preferred aspect ratio, and no natural size in the relevant
        // axis (if it is a replaced element), the grid item is sized as for align-self: stretch.
        //
        // https://www.w3.org/TR/css-align-3/#propdef-align-self
        //
        // When the box’s computed width/height (as appropriate to the axis) is auto and neither of
        // its margins (in the appropriate axis) are auto, sets the box’s used size to the length
        // necessary to make its outer size as close to filling the alignment container as possible
        // while still respecting the constraints imposed by min-height/min-width/max-height/max-width.
        auto& marginStart = inlineAxisSizes.marginStart;
        auto& marginEnd = inlineAxisSizes.marginEnd;
        if ((alignmentPosition == ItemPosition::Normal) && !placedGridItem.hasPreferredAspectRatio() && !placedGridItem.isReplacedElement()
            && !marginStart.isAuto() && !marginEnd.isAuto()) {
            auto& usedZoom = placedGridItem.usedZoom();

            auto minimumSize = LayoutUnit { inlineAxisSizes.minimumSize.tryFixed()->resolveZoom(usedZoom) };
            auto maximumSize = [&inlineAxisSizes, &usedZoom] {
                auto& computedMaximumSize = inlineAxisSizes.maximumSize;
                if (computedMaximumSize.isNone())
                    return LayoutUnit::max();
                return LayoutUnit { computedMaximumSize.tryFixed()->resolveZoom(usedZoom) };
            };

            auto stretchedWidth = columnsSize() - LayoutUnit { marginStart.tryFixed()->resolveZoom(usedZoom) } - LayoutUnit { marginEnd.tryFixed()->resolveZoom(usedZoom) } - borderAndPadding;
            return std::max(minimumSize, std::min(maximumSize(), stretchedWidth));
        }

        ASSERT_NOT_IMPLEMENTED_YET();
        return { };
    }

    ASSERT_NOT_IMPLEMENTED_YET();
    return { };
}

LayoutUnit usedBlockSizeForGridItem(const PlacedGridItem& placedGridItem)
{
    auto& blockAxisSizes = placedGridItem.blockAxisSizes();
    if (auto fixedBlockSize = blockAxisSizes.preferredSize.tryFixed())
        return LayoutUnit { fixedBlockSize->resolveZoom(placedGridItem.usedZoom()) };

    ASSERT_NOT_IMPLEMENTED_YET();
    return { };
}


LayoutUnit computeGridLinePosition(size_t gridLineIndex, const TrackSizes& trackSizes, LayoutUnit gap)
{
    auto trackSizesBefore = trackSizes.subspan(0, gridLineIndex);
    auto sumOfTrackSizes = std::reduce(trackSizesBefore.begin(), trackSizesBefore.end());

    // For grid line i, there are i-1 gaps before it (between the i tracks)
    auto numberOfGaps = gridLineIndex > 0 ? gridLineIndex - 1 : 0;

    return sumOfTrackSizes + (numberOfGaps * gap);
}

}
}
}