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
36namespace WebCore {
37
38enum 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.
55class GridTrackSize {
56public:
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
129private:
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
147