Implement CSS `display: flow-root` (modern clearfix)
[WebKit-https.git] / Source / WebCore / rendering / style / GridTrackSize.h
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2013, 2014 Igalia S.L.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #pragma once
33
34 #include "GridLength.h"
35
36 namespace WebCore {
37
38 enum GridTrackSizeType {
39     LengthTrackSizing,
40     MinMaxTrackSizing,
41     FitContentTrackSizing
42 };
43
44 // This class represents a <track-size> from the spec. Althought there are 3 different types of
45 // <track-size> there is always an equivalent minmax() representation that could represent any of
46 // them. The only special case is fit-content(argument) which is similar to minmax(auto,
47 // max-content) except that the track size is clamped at argument if it is greater than the auto
48 // minimum. At the GridTrackSize level we don't need to worry about clamping so we treat that case
49 // exactly as auto.
50 //
51 // We're using a separate attribute to store fit-content argument even though we could directly use
52 // m_maxTrackBreadth. The reason why we don't do it is because the maxTrackBreadh() call is a hot
53 // spot, so adding a conditional statement there (to distinguish between fit-content and any other
54 // case) was causing a severe performance drop.
55 class GridTrackSize {
56 public:
57     GridTrackSize(const GridLength& length, GridTrackSizeType trackSizeType = LengthTrackSizing)
58         : m_type(trackSizeType)
59         , m_minTrackBreadth(trackSizeType == FitContentTrackSizing ? Length(Auto) : length)
60         , m_maxTrackBreadth(trackSizeType == FitContentTrackSizing ? Length(Auto) : length)
61         , m_fitContentTrackBreadth(trackSizeType == FitContentTrackSizing ? length : GridLength(Length(Fixed)))
62     {
63         ASSERT(trackSizeType == LengthTrackSizing || trackSizeType == FitContentTrackSizing);
64         ASSERT(trackSizeType != FitContentTrackSizing || length.isLength());
65         cacheMinMaxTrackBreadthTypes();
66     }
67
68     GridTrackSize(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth)
69         : m_type(MinMaxTrackSizing)
70         , m_minTrackBreadth(minTrackBreadth)
71         , m_maxTrackBreadth(maxTrackBreadth)
72         , m_fitContentTrackBreadth(GridLength(Length(Fixed)))
73     {
74         cacheMinMaxTrackBreadthTypes();
75     }
76
77     const GridLength& fitContentTrackBreadth() const
78     {
79         ASSERT(m_type == FitContentTrackSizing);
80         return m_fitContentTrackBreadth;
81     }
82
83     const GridLength& minTrackBreadth() const { return m_minTrackBreadth; }
84     const GridLength& maxTrackBreadth() const { return m_maxTrackBreadth; }
85
86     GridTrackSizeType type() const { return m_type; }
87
88     bool isContentSized() const { return m_minTrackBreadth.isContentSized() || m_maxTrackBreadth.isContentSized(); }
89     bool isFitContent() const { return m_type == FitContentTrackSizing; }
90
91     bool operator==(const GridTrackSize& other) const
92     {
93         return m_type == other.m_type && m_minTrackBreadth == other.m_minTrackBreadth && m_maxTrackBreadth == other.m_maxTrackBreadth
94             && m_fitContentTrackBreadth == other.m_fitContentTrackBreadth;
95     }
96
97     void cacheMinMaxTrackBreadthTypes()
98     {
99         m_minTrackBreadthIsAuto = minTrackBreadth().isLength() && minTrackBreadth().length().isAuto();
100         m_minTrackBreadthIsMinContent = minTrackBreadth().isLength() && minTrackBreadth().length().isMinContent();
101         m_minTrackBreadthIsMaxContent = minTrackBreadth().isLength() && minTrackBreadth().length().isMaxContent();
102         m_maxTrackBreadthIsMaxContent = maxTrackBreadth().isLength() && maxTrackBreadth().length().isMaxContent();
103         m_maxTrackBreadthIsMinContent = maxTrackBreadth().isLength() && maxTrackBreadth().length().isMinContent();
104         m_maxTrackBreadthIsAuto = maxTrackBreadth().isLength() && maxTrackBreadth().length().isAuto();
105         m_maxTrackBreadthIsFixed = maxTrackBreadth().isLength() && maxTrackBreadth().length().isSpecified();
106
107         // These values depend on the above ones so keep them here.
108         m_minTrackBreadthIsIntrinsic = m_minTrackBreadthIsMaxContent || m_minTrackBreadthIsMinContent
109             || m_minTrackBreadthIsAuto || isFitContent();
110         m_maxTrackBreadthIsIntrinsic = m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsMinContent
111             || m_maxTrackBreadthIsAuto || isFitContent();
112     }
113
114     bool hasIntrinsicMinTrackBreadth() const { return m_minTrackBreadthIsIntrinsic; }
115     bool hasIntrinsicMaxTrackBreadth() const { return m_maxTrackBreadthIsIntrinsic; }
116     bool hasMinOrMaxContentMinTrackBreadth() const { return m_minTrackBreadthIsMaxContent || m_minTrackBreadthIsMinContent; }
117     bool hasAutoMinTrackBreadth() const { return m_minTrackBreadthIsAuto; }
118     bool hasAutoMaxTrackBreadth() const { return m_maxTrackBreadthIsAuto; }
119     bool hasMaxContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent; }
120     bool hasMaxContentOrAutoMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsAuto; }
121     bool hasMinContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMinContent; }
122     bool hasMinOrMaxContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsMinContent; }
123     bool hasMaxContentMinTrackBreadth() const { return m_minTrackBreadthIsMaxContent; }
124     bool hasMinContentMinTrackBreadth() const { return m_minTrackBreadthIsMinContent; }
125     bool hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth() const { return m_minTrackBreadthIsMaxContent && m_maxTrackBreadthIsMaxContent; }
126     bool hasAutoOrMinContentMinTrackBreadthAndIntrinsicMaxTrackBreadth() const { return (m_minTrackBreadthIsMinContent || m_minTrackBreadthIsAuto) && m_maxTrackBreadthIsIntrinsic; }
127     bool hasFixedMaxTrackBreadth() const { return m_maxTrackBreadthIsFixed; }
128
129 private:
130     GridTrackSizeType m_type;
131     GridLength m_minTrackBreadth;
132     GridLength m_maxTrackBreadth;
133     GridLength m_fitContentTrackBreadth;
134
135     bool m_minTrackBreadthIsAuto : 1;
136     bool m_maxTrackBreadthIsAuto : 1;
137     bool m_minTrackBreadthIsMaxContent : 1;
138     bool m_minTrackBreadthIsMinContent : 1;
139     bool m_maxTrackBreadthIsMaxContent : 1;
140     bool m_maxTrackBreadthIsMinContent : 1;
141     bool m_minTrackBreadthIsIntrinsic : 1;
142     bool m_maxTrackBreadthIsIntrinsic : 1;
143     bool m_maxTrackBreadthIsFixed : 1;
144 };
145
146 } // namespace WebCore