initial import
[vuplus_webkit] / Source / WebCore / css / CSSProperty.cpp
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
30 String CSSProperty::cssText() const
31 {
32     return String(getPropertyName(static_cast<CSSPropertyID>(id()))) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; ";
33 }
34
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
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
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         
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