1 /** 2 * (C) 1999-2003 Lars Knoll (knoll (at) 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 286