2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
22 #include "CSSProperty.h"
24 #include "CSSValueList.h"
25 #include "RenderStyleConstants.h"
26 #include "StylePropertyShorthand.h"
28 #include <wtf/text/StringBuilder.h>
32 struct SameSizeAsCSSProperty {
37 COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small);
39 CSSPropertyID StylePropertyMetadata::shorthandID() const
41 if (!m_isSetFromShorthand)
42 return CSSPropertyInvalid;
44 Vector<StylePropertyShorthand> shorthands = matchingShorthandsForLonghand(static_cast<CSSPropertyID>(m_propertyID));
45 ASSERT(shorthands.size() && m_indexInShorthandsVector >= 0 && m_indexInShorthandsVector < shorthands.size());
46 return shorthands[m_indexInShorthandsVector].id();
49 void CSSProperty::wrapValueInCommaSeparatedList()
51 RefPtr<CSSValue> value = m_value.release();
52 m_value = CSSValueList::createCommaSeparated();
53 toCSSValueList(m_value.get())->append(value.release());
56 enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide };
57 enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide };
59 static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand)
61 if (direction == LTR) {
62 if (writingMode == TopToBottomWritingMode) {
63 // The common case. The logical and physical box sides match.
64 // Left = Start, Right = End, Before = Top, After = Bottom
65 return shorthand.properties()[logicalSide];
68 if (writingMode == BottomToTopWritingMode) {
69 // Start = Left, End = Right, Before = Bottom, After = Top.
70 switch (logicalSide) {
72 return shorthand.properties()[LeftSide];
74 return shorthand.properties()[RightSide];
76 return shorthand.properties()[BottomSide];
78 return shorthand.properties()[TopSide];
82 if (writingMode == LeftToRightWritingMode) {
83 // Start = Top, End = Bottom, Before = Left, After = Right.
84 switch (logicalSide) {
86 return shorthand.properties()[TopSide];
88 return shorthand.properties()[BottomSide];
90 return shorthand.properties()[LeftSide];
92 return shorthand.properties()[RightSide];
96 // Start = Top, End = Bottom, Before = Right, After = Left
97 switch (logicalSide) {
99 return shorthand.properties()[TopSide];
101 return shorthand.properties()[BottomSide];
103 return shorthand.properties()[RightSide];
105 return shorthand.properties()[LeftSide];
109 if (writingMode == TopToBottomWritingMode) {
110 // Start = Right, End = Left, Before = Top, After = Bottom
111 switch (logicalSide) {
113 return shorthand.properties()[RightSide];
115 return shorthand.properties()[LeftSide];
117 return shorthand.properties()[TopSide];
119 return shorthand.properties()[BottomSide];
123 if (writingMode == BottomToTopWritingMode) {
124 // Start = Right, End = Left, Before = Bottom, After = Top
125 switch (logicalSide) {
127 return shorthand.properties()[RightSide];
129 return shorthand.properties()[LeftSide];
131 return shorthand.properties()[BottomSide];
133 return shorthand.properties()[TopSide];
137 if (writingMode == LeftToRightWritingMode) {
138 // Start = Bottom, End = Top, Before = Left, After = Right
139 switch (logicalSide) {
141 return shorthand.properties()[BottomSide];
143 return shorthand.properties()[TopSide];
145 return shorthand.properties()[LeftSide];
147 return shorthand.properties()[RightSide];
151 // Start = Bottom, End = Top, Before = Right, After = Left
152 switch (logicalSide) {
154 return shorthand.properties()[BottomSide];
156 return shorthand.properties()[TopSide];
158 return shorthand.properties()[RightSide];
160 return shorthand.properties()[LeftSide];
164 enum LogicalExtent { LogicalWidth, LogicalHeight };
166 static CSSPropertyID resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const CSSPropertyID* properties)
168 if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode)
169 return properties[logicalSide];
170 return logicalSide == LogicalWidth ? properties[1] : properties[0];
173 static const StylePropertyShorthand& borderDirections()
175 static const CSSPropertyID properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
176 DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderDirections, (CSSPropertyBorder, properties, WTF_ARRAY_LENGTH(properties)));
177 return borderDirections;
180 CSSPropertyID CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID, TextDirection direction, WritingMode writingMode)
182 switch (propertyID) {
183 case CSSPropertyWebkitMarginEnd:
184 return resolveToPhysicalProperty(direction, writingMode, EndSide, marginShorthand());
185 case CSSPropertyWebkitMarginStart:
186 return resolveToPhysicalProperty(direction, writingMode, StartSide, marginShorthand());
187 case CSSPropertyWebkitMarginBefore:
188 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, marginShorthand());
189 case CSSPropertyWebkitMarginAfter:
190 return resolveToPhysicalProperty(direction, writingMode, AfterSide, marginShorthand());
191 case CSSPropertyWebkitPaddingEnd:
192 return resolveToPhysicalProperty(direction, writingMode, EndSide, paddingShorthand());
193 case CSSPropertyWebkitPaddingStart:
194 return resolveToPhysicalProperty(direction, writingMode, StartSide, paddingShorthand());
195 case CSSPropertyWebkitPaddingBefore:
196 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, paddingShorthand());
197 case CSSPropertyWebkitPaddingAfter:
198 return resolveToPhysicalProperty(direction, writingMode, AfterSide, paddingShorthand());
199 case CSSPropertyWebkitBorderEnd:
200 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderDirections());
201 case CSSPropertyWebkitBorderStart:
202 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderDirections());
203 case CSSPropertyWebkitBorderBefore:
204 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderDirections());
205 case CSSPropertyWebkitBorderAfter:
206 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderDirections());
207 case CSSPropertyWebkitBorderEndColor:
208 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderColorShorthand());
209 case CSSPropertyWebkitBorderStartColor:
210 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderColorShorthand());
211 case CSSPropertyWebkitBorderBeforeColor:
212 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderColorShorthand());
213 case CSSPropertyWebkitBorderAfterColor:
214 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderColorShorthand());
215 case CSSPropertyWebkitBorderEndStyle:
216 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderStyleShorthand());
217 case CSSPropertyWebkitBorderStartStyle:
218 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderStyleShorthand());
219 case CSSPropertyWebkitBorderBeforeStyle:
220 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderStyleShorthand());
221 case CSSPropertyWebkitBorderAfterStyle:
222 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderStyleShorthand());
223 case CSSPropertyWebkitBorderEndWidth:
224 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderWidthShorthand());
225 case CSSPropertyWebkitBorderStartWidth:
226 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderWidthShorthand());
227 case CSSPropertyWebkitBorderBeforeWidth:
228 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderWidthShorthand());
229 case CSSPropertyWebkitBorderAfterWidth:
230 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderWidthShorthand());
231 case CSSPropertyWebkitLogicalWidth: {
232 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
233 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
235 case CSSPropertyWebkitLogicalHeight: {
236 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
237 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
239 case CSSPropertyWebkitMinLogicalWidth: {
240 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
241 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
243 case CSSPropertyWebkitMinLogicalHeight: {
244 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
245 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
247 case CSSPropertyWebkitMaxLogicalWidth: {
248 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
249 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
251 case CSSPropertyWebkitMaxLogicalHeight: {
252 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
253 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
260 } // namespace WebCore