1 /**
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
4 *
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.
9 *
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.
14 *
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.
19 */
20
21 #include "config.h"
22 #include "CSSProperty.h"
23
24 #include "CSSPropertyNames.h"
25 #include "PlatformString.h"
26 #include "RenderStyleConstants.h"
27
28 namespace WebCore {
29
cssText() const30 String CSSProperty::cssText() const
31 {
32 return String(getPropertyName(static_cast<CSSPropertyID>(id()))) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; ";
33 }
34
operator ==(const CSSProperty & a,const CSSProperty & b)35 bool operator==(const CSSProperty& a, const CSSProperty& b)
36 {
37 return a.m_id == b.m_id && a.m_important == b.m_important && a.m_value == b.m_value;
38 }
39
40 enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide };
41 enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide };
42
resolveToPhysicalProperty(TextDirection direction,WritingMode writingMode,LogicalBoxSide logicalSide,const int * properties)43 static int resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const int* properties)
44 {
45 if (direction == LTR) {
46 if (writingMode == TopToBottomWritingMode) {
47 // The common case. The logical and physical box sides match.
48 // Left = Start, Right = End, Before = Top, After = Bottom
49 return properties[logicalSide];
50 }
51
52 if (writingMode == BottomToTopWritingMode) {
53 // Start = Left, End = Right, Before = Bottom, After = Top.
54 switch (logicalSide) {
55 case StartSide:
56 return properties[LeftSide];
57 case EndSide:
58 return properties[RightSide];
59 case BeforeSide:
60 return properties[BottomSide];
61 default:
62 return properties[TopSide];
63 }
64 }
65
66 if (writingMode == LeftToRightWritingMode) {
67 // Start = Top, End = Bottom, Before = Left, After = Right.
68 switch (logicalSide) {
69 case StartSide:
70 return properties[TopSide];
71 case EndSide:
72 return properties[BottomSide];
73 case BeforeSide:
74 return properties[LeftSide];
75 default:
76 return properties[RightSide];
77 }
78 }
79
80 // Start = Top, End = Bottom, Before = Right, After = Left
81 switch (logicalSide) {
82 case StartSide:
83 return properties[TopSide];
84 case EndSide:
85 return properties[BottomSide];
86 case BeforeSide:
87 return properties[RightSide];
88 default:
89 return properties[LeftSide];
90 }
91 }
92
93 if (writingMode == TopToBottomWritingMode) {
94 // Start = Right, End = Left, Before = Top, After = Bottom
95 switch (logicalSide) {
96 case StartSide:
97 return properties[RightSide];
98 case EndSide:
99 return properties[LeftSide];
100 case BeforeSide:
101 return properties[TopSide];
102 default:
103 return properties[BottomSide];
104 }
105 }
106
107 if (writingMode == BottomToTopWritingMode) {
108 // Start = Right, End = Left, Before = Bottom, After = Top
109 switch (logicalSide) {
110 case StartSide:
111 return properties[RightSide];
112 case EndSide:
113 return properties[LeftSide];
114 case BeforeSide:
115 return properties[BottomSide];
116 default:
117 return properties[TopSide];
118 }
119 }
120
121 if (writingMode == LeftToRightWritingMode) {
122 // Start = Bottom, End = Top, Before = Left, After = Right
123 switch (logicalSide) {
124 case StartSide:
125 return properties[BottomSide];
126 case EndSide:
127 return properties[TopSide];
128 case BeforeSide:
129 return properties[LeftSide];
130 default:
131 return properties[RightSide];
132 }
133 }
134
135 // Start = Bottom, End = Top, Before = Right, After = Left
136 switch (logicalSide) {
137 case StartSide:
138 return properties[BottomSide];
139 case EndSide:
140 return properties[TopSide];
141 case BeforeSide:
142 return properties[RightSide];
143 default:
144 return properties[LeftSide];
145 }
146 }
147
148 enum LogicalExtent { LogicalWidth, LogicalHeight };
149
resolveToPhysicalProperty(WritingMode writingMode,LogicalExtent logicalSide,const int * properties)150 static int resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const int* properties)
151 {
152 if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode)
153 return properties[logicalSide];
154 return logicalSide == LogicalWidth ? properties[1] : properties[0];
155 }
156
resolveDirectionAwareProperty(int propertyID,TextDirection direction,WritingMode writingMode)157 int CSSProperty::resolveDirectionAwareProperty(int propertyID, TextDirection direction, WritingMode writingMode)
158 {
159 switch (static_cast<CSSPropertyID>(propertyID)) {
160 case CSSPropertyWebkitMarginEnd: {
161 const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
162 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
163 }
164 case CSSPropertyWebkitMarginStart: {
165 const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
166 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
167 }
168 case CSSPropertyWebkitMarginBefore: {
169 const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
170 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
171 }
172 case CSSPropertyWebkitMarginAfter: {
173 const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
174 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
175 }
176 case CSSPropertyWebkitPaddingEnd: {
177 const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
178 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
179 }
180 case CSSPropertyWebkitPaddingStart: {
181 const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
182 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
183 }
184 case CSSPropertyWebkitPaddingBefore: {
185 const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
186 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
187 }
188 case CSSPropertyWebkitPaddingAfter: {
189 const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
190 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
191 }
192 case CSSPropertyWebkitBorderEnd: {
193 const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
194 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
195 }
196 case CSSPropertyWebkitBorderStart: {
197 const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
198 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
199 }
200 case CSSPropertyWebkitBorderBefore: {
201 const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
202 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
203 }
204 case CSSPropertyWebkitBorderAfter: {
205 const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
206 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
207 }
208 case CSSPropertyWebkitBorderEndColor: {
209 const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
210 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
211 }
212 case CSSPropertyWebkitBorderStartColor: {
213 const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
214 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
215 }
216 case CSSPropertyWebkitBorderBeforeColor: {
217 const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
218 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
219 }
220 case CSSPropertyWebkitBorderAfterColor: {
221 const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
222 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
223 }
224 case CSSPropertyWebkitBorderEndStyle: {
225 const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
226 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
227 }
228 case CSSPropertyWebkitBorderStartStyle: {
229 const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
230 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
231 }
232 case CSSPropertyWebkitBorderBeforeStyle: {
233 const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
234 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
235 }
236 case CSSPropertyWebkitBorderAfterStyle: {
237 const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
238 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
239 }
240 case CSSPropertyWebkitBorderEndWidth: {
241 const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
242 return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
243 }
244 case CSSPropertyWebkitBorderStartWidth: {
245 const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
246 return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
247 }
248 case CSSPropertyWebkitBorderBeforeWidth: {
249 const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
250 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
251 }
252 case CSSPropertyWebkitBorderAfterWidth: {
253 const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
254 return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
255 }
256 case CSSPropertyWebkitLogicalWidth: {
257 const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
258 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
259 }
260 case CSSPropertyWebkitLogicalHeight: {
261 const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
262 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
263 }
264 case CSSPropertyWebkitMinLogicalWidth: {
265 const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
266 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
267 }
268 case CSSPropertyWebkitMinLogicalHeight: {
269 const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
270 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
271 }
272 case CSSPropertyWebkitMaxLogicalWidth: {
273 const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
274 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
275 }
276 case CSSPropertyWebkitMaxLogicalHeight: {
277 const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
278 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
279 }
280 default:
281 return propertyID;
282 }
283 }
284
285 } // namespace WebCore
286