| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | |
| 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | |
| 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | |
| 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. | |
| 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | |
| 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | |
| 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | |
| 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | |
| 11 * Copyright (C) 2012 Google Inc. All rights reserved. | |
| 12 * | |
| 13 * This library is free software; you can redistribute it and/or | |
| 14 * modify it under the terms of the GNU Library General Public | |
| 15 * License as published by the Free Software Foundation; either | |
| 16 * version 2 of the License, or (at your option) any later version. | |
| 17 * | |
| 18 * This library is distributed in the hope that it will be useful, | |
| 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 21 * Library General Public License for more details. | |
| 22 * | |
| 23 * You should have received a copy of the GNU Library General Public License | |
| 24 * along with this library; see the file COPYING.LIB. If not, write to | |
| 25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| 26 * Boston, MA 02110-1301, USA. | |
| 27 */ | |
| 28 | |
| 29 #include "config.h" | |
| 30 #include "core/css/TransformBuilder.h" | |
| 31 | |
| 32 #include "core/css/WebKitCSSTransformValue.h" | |
| 33 #include "core/rendering/style/RenderStyle.h" | |
| 34 #include "core/platform/graphics/transforms/Matrix3DTransformOperation.h" | |
| 35 #include "core/platform/graphics/transforms/MatrixTransformOperation.h" | |
| 36 #include "core/platform/graphics/transforms/PerspectiveTransformOperation.h" | |
| 37 #include "core/platform/graphics/transforms/RotateTransformOperation.h" | |
| 38 #include "core/platform/graphics/transforms/ScaleTransformOperation.h" | |
| 39 #include "core/platform/graphics/transforms/SkewTransformOperation.h" | |
| 40 #include "core/platform/graphics/transforms/TransformationMatrix.h" | |
| 41 #include "core/platform/graphics/transforms/TranslateTransformOperation.h" | |
| 42 | |
| 43 #include "core/css/WebKitCSSFilterValue.h" | |
| 44 #include "core/platform/graphics/filters/FilterOperation.h" | |
| 45 #include "core/css/CSSPrimitiveValueMappings.h" | |
| 46 | |
| 47 namespace WebCore { | |
| 48 | |
| 49 TransformBuilder::TransformBuilder() | |
| 50 { | |
| 51 } | |
| 52 | |
| 53 TransformBuilder::~TransformBuilder() | |
| 54 { | |
| 55 } | |
| 56 | |
| 57 static Length convertToFloatLength(CSSPrimitiveValue* primitiveValue, RenderStyl
e* style, RenderStyle* rootStyle, double multiplier) | |
| 58 { | |
| 59 return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion
| PercentConversion | CalculatedConversion | FractionConversion | ViewportPerce
ntageConversion>(style, rootStyle, multiplier) : Length(Undefined); | |
| 60 } | |
| 61 | |
| 62 static TransformOperation::OperationType getTransformOperationType(WebKitCSSTran
sformValue::TransformOperationType type) | |
| 63 { | |
| 64 switch (type) { | |
| 65 case WebKitCSSTransformValue::ScaleTransformOperation: return TransformOpera
tion::SCALE; | |
| 66 case WebKitCSSTransformValue::ScaleXTransformOperation: return TransformOper
ation::SCALE_X; | |
| 67 case WebKitCSSTransformValue::ScaleYTransformOperation: return TransformOper
ation::SCALE_Y; | |
| 68 case WebKitCSSTransformValue::ScaleZTransformOperation: return TransformOper
ation::SCALE_Z; | |
| 69 case WebKitCSSTransformValue::Scale3DTransformOperation: return TransformOpe
ration::SCALE_3D; | |
| 70 case WebKitCSSTransformValue::TranslateTransformOperation: return TransformO
peration::TRANSLATE; | |
| 71 case WebKitCSSTransformValue::TranslateXTransformOperation: return Transform
Operation::TRANSLATE_X; | |
| 72 case WebKitCSSTransformValue::TranslateYTransformOperation: return Transform
Operation::TRANSLATE_Y; | |
| 73 case WebKitCSSTransformValue::TranslateZTransformOperation: return Transform
Operation::TRANSLATE_Z; | |
| 74 case WebKitCSSTransformValue::Translate3DTransformOperation: return Transfor
mOperation::TRANSLATE_3D; | |
| 75 case WebKitCSSTransformValue::RotateTransformOperation: return TransformOper
ation::ROTATE; | |
| 76 case WebKitCSSTransformValue::RotateXTransformOperation: return TransformOpe
ration::ROTATE_X; | |
| 77 case WebKitCSSTransformValue::RotateYTransformOperation: return TransformOpe
ration::ROTATE_Y; | |
| 78 case WebKitCSSTransformValue::RotateZTransformOperation: return TransformOpe
ration::ROTATE_Z; | |
| 79 case WebKitCSSTransformValue::Rotate3DTransformOperation: return TransformOp
eration::ROTATE_3D; | |
| 80 case WebKitCSSTransformValue::SkewTransformOperation: return TransformOperat
ion::SKEW; | |
| 81 case WebKitCSSTransformValue::SkewXTransformOperation: return TransformOpera
tion::SKEW_X; | |
| 82 case WebKitCSSTransformValue::SkewYTransformOperation: return TransformOpera
tion::SKEW_Y; | |
| 83 case WebKitCSSTransformValue::MatrixTransformOperation: return TransformOper
ation::MATRIX; | |
| 84 case WebKitCSSTransformValue::Matrix3DTransformOperation: return TransformOp
eration::MATRIX_3D; | |
| 85 case WebKitCSSTransformValue::PerspectiveTransformOperation: return Transfor
mOperation::PERSPECTIVE; | |
| 86 case WebKitCSSTransformValue::UnknownTransformOperation: return TransformOpe
ration::NONE; | |
| 87 } | |
| 88 return TransformOperation::NONE; | |
| 89 } | |
| 90 | |
| 91 bool TransformBuilder::createTransformOperations(CSSValue* inValue, RenderStyle*
style, RenderStyle* rootStyle, TransformOperations& outOperations) | |
| 92 { | |
| 93 if (!inValue || !inValue->isValueList()) { | |
| 94 outOperations.clear(); | |
| 95 return false; | |
| 96 } | |
| 97 | |
| 98 float zoomFactor = style ? style->effectiveZoom() : 1; | |
| 99 TransformOperations operations; | |
| 100 for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) { | |
| 101 CSSValue* currValue = i.value(); | |
| 102 | |
| 103 if (!currValue->isWebKitCSSTransformValue()) | |
| 104 continue; | |
| 105 | |
| 106 WebKitCSSTransformValue* transformValue = static_cast<WebKitCSSTransform
Value*>(i.value()); | |
| 107 if (!transformValue->length()) | |
| 108 continue; | |
| 109 | |
| 110 bool haveNonPrimitiveValue = false; | |
| 111 for (unsigned j = 0; j < transformValue->length(); ++j) { | |
| 112 if (!transformValue->itemWithoutBoundsCheck(j)->isPrimitiveValue())
{ | |
| 113 haveNonPrimitiveValue = true; | |
| 114 break; | |
| 115 } | |
| 116 } | |
| 117 if (haveNonPrimitiveValue) | |
| 118 continue; | |
| 119 | |
| 120 CSSPrimitiveValue* firstValue = static_cast<CSSPrimitiveValue*>(transfor
mValue->itemWithoutBoundsCheck(0)); | |
| 121 | |
| 122 switch (transformValue->operationType()) { | |
| 123 case WebKitCSSTransformValue::ScaleTransformOperation: | |
| 124 case WebKitCSSTransformValue::ScaleXTransformOperation: | |
| 125 case WebKitCSSTransformValue::ScaleYTransformOperation: { | |
| 126 double sx = 1.0; | |
| 127 double sy = 1.0; | |
| 128 if (transformValue->operationType() == WebKitCSSTransformValue::Scal
eYTransformOperation) | |
| 129 sy = firstValue->getDoubleValue(); | |
| 130 else { | |
| 131 sx = firstValue->getDoubleValue(); | |
| 132 if (transformValue->operationType() != WebKitCSSTransformValue::
ScaleXTransformOperation) { | |
| 133 if (transformValue->length() > 1) { | |
| 134 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiv
eValue*>(transformValue->itemWithoutBoundsCheck(1)); | |
| 135 sy = secondValue->getDoubleValue(); | |
| 136 } else | |
| 137 sy = sx; | |
| 138 } | |
| 139 } | |
| 140 operations.operations().append(ScaleTransformOperation::create(sx, s
y, 1.0, getTransformOperationType(transformValue->operationType()))); | |
| 141 break; | |
| 142 } | |
| 143 case WebKitCSSTransformValue::ScaleZTransformOperation: | |
| 144 case WebKitCSSTransformValue::Scale3DTransformOperation: { | |
| 145 double sx = 1.0; | |
| 146 double sy = 1.0; | |
| 147 double sz = 1.0; | |
| 148 if (transformValue->operationType() == WebKitCSSTransformValue::Scal
eZTransformOperation) | |
| 149 sz = firstValue->getDoubleValue(); | |
| 150 else if (transformValue->operationType() == WebKitCSSTransformValue:
:ScaleYTransformOperation) | |
| 151 sy = firstValue->getDoubleValue(); | |
| 152 else { | |
| 153 sx = firstValue->getDoubleValue(); | |
| 154 if (transformValue->operationType() != WebKitCSSTransformValue::
ScaleXTransformOperation) { | |
| 155 if (transformValue->length() > 2) { | |
| 156 CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitive
Value*>(transformValue->itemWithoutBoundsCheck(2)); | |
| 157 sz = thirdValue->getDoubleValue(); | |
| 158 } | |
| 159 if (transformValue->length() > 1) { | |
| 160 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiv
eValue*>(transformValue->itemWithoutBoundsCheck(1)); | |
| 161 sy = secondValue->getDoubleValue(); | |
| 162 } else | |
| 163 sy = sx; | |
| 164 } | |
| 165 } | |
| 166 operations.operations().append(ScaleTransformOperation::create(sx, s
y, sz, getTransformOperationType(transformValue->operationType()))); | |
| 167 break; | |
| 168 } | |
| 169 case WebKitCSSTransformValue::TranslateTransformOperation: | |
| 170 case WebKitCSSTransformValue::TranslateXTransformOperation: | |
| 171 case WebKitCSSTransformValue::TranslateYTransformOperation: { | |
| 172 Length tx = Length(0, Fixed); | |
| 173 Length ty = Length(0, Fixed); | |
| 174 if (transformValue->operationType() == WebKitCSSTransformValue::Tran
slateYTransformOperation) | |
| 175 ty = convertToFloatLength(firstValue, style, rootStyle, zoomFact
or); | |
| 176 else { | |
| 177 tx = convertToFloatLength(firstValue, style, rootStyle, zoomFact
or); | |
| 178 if (transformValue->operationType() != WebKitCSSTransformValue::
TranslateXTransformOperation) { | |
| 179 if (transformValue->length() > 1) { | |
| 180 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiv
eValue*>(transformValue->itemWithoutBoundsCheck(1)); | |
| 181 ty = convertToFloatLength(secondValue, style, rootStyle,
zoomFactor); | |
| 182 } | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 if (tx.isUndefined() || ty.isUndefined()) | |
| 187 return false; | |
| 188 | |
| 189 operations.operations().append(TranslateTransformOperation::create(t
x, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType
()))); | |
| 190 break; | |
| 191 } | |
| 192 case WebKitCSSTransformValue::TranslateZTransformOperation: | |
| 193 case WebKitCSSTransformValue::Translate3DTransformOperation: { | |
| 194 Length tx = Length(0, Fixed); | |
| 195 Length ty = Length(0, Fixed); | |
| 196 Length tz = Length(0, Fixed); | |
| 197 if (transformValue->operationType() == WebKitCSSTransformValue::Tran
slateZTransformOperation) | |
| 198 tz = convertToFloatLength(firstValue, style, rootStyle, zoomFact
or); | |
| 199 else if (transformValue->operationType() == WebKitCSSTransformValue:
:TranslateYTransformOperation) | |
| 200 ty = convertToFloatLength(firstValue, style, rootStyle, zoomFact
or); | |
| 201 else { | |
| 202 tx = convertToFloatLength(firstValue, style, rootStyle, zoomFact
or); | |
| 203 if (transformValue->operationType() != WebKitCSSTransformValue::
TranslateXTransformOperation) { | |
| 204 if (transformValue->length() > 2) { | |
| 205 CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitive
Value*>(transformValue->itemWithoutBoundsCheck(2)); | |
| 206 tz = convertToFloatLength(thirdValue, style, rootStyle,
zoomFactor); | |
| 207 } | |
| 208 if (transformValue->length() > 1) { | |
| 209 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiv
eValue*>(transformValue->itemWithoutBoundsCheck(1)); | |
| 210 ty = convertToFloatLength(secondValue, style, rootStyle,
zoomFactor); | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined()) | |
| 216 return false; | |
| 217 | |
| 218 operations.operations().append(TranslateTransformOperation::create(t
x, ty, tz, getTransformOperationType(transformValue->operationType()))); | |
| 219 break; | |
| 220 } | |
| 221 case WebKitCSSTransformValue::RotateTransformOperation: { | |
| 222 double angle = firstValue->computeDegrees(); | |
| 223 operations.operations().append(RotateTransformOperation::create(0, 0
, 1, angle, getTransformOperationType(transformValue->operationType()))); | |
| 224 break; | |
| 225 } | |
| 226 case WebKitCSSTransformValue::RotateXTransformOperation: | |
| 227 case WebKitCSSTransformValue::RotateYTransformOperation: | |
| 228 case WebKitCSSTransformValue::RotateZTransformOperation: { | |
| 229 double x = 0; | |
| 230 double y = 0; | |
| 231 double z = 0; | |
| 232 double angle = firstValue->computeDegrees(); | |
| 233 | |
| 234 if (transformValue->operationType() == WebKitCSSTransformValue::Rota
teXTransformOperation) | |
| 235 x = 1; | |
| 236 else if (transformValue->operationType() == WebKitCSSTransformValue:
:RotateYTransformOperation) | |
| 237 y = 1; | |
| 238 else | |
| 239 z = 1; | |
| 240 operations.operations().append(RotateTransformOperation::create(x, y
, z, angle, getTransformOperationType(transformValue->operationType()))); | |
| 241 break; | |
| 242 } | |
| 243 case WebKitCSSTransformValue::Rotate3DTransformOperation: { | |
| 244 if (transformValue->length() < 4) | |
| 245 break; | |
| 246 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(tra
nsformValue->itemWithoutBoundsCheck(1)); | |
| 247 CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(tran
sformValue->itemWithoutBoundsCheck(2)); | |
| 248 CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(tra
nsformValue->itemWithoutBoundsCheck(3)); | |
| 249 double x = firstValue->getDoubleValue(); | |
| 250 double y = secondValue->getDoubleValue(); | |
| 251 double z = thirdValue->getDoubleValue(); | |
| 252 double angle = fourthValue->computeDegrees(); | |
| 253 operations.operations().append(RotateTransformOperation::create(x, y
, z, angle, getTransformOperationType(transformValue->operationType()))); | |
| 254 break; | |
| 255 } | |
| 256 case WebKitCSSTransformValue::SkewTransformOperation: | |
| 257 case WebKitCSSTransformValue::SkewXTransformOperation: | |
| 258 case WebKitCSSTransformValue::SkewYTransformOperation: { | |
| 259 double angleX = 0; | |
| 260 double angleY = 0; | |
| 261 double angle = firstValue->computeDegrees(); | |
| 262 if (transformValue->operationType() == WebKitCSSTransformValue::Skew
YTransformOperation) | |
| 263 angleY = angle; | |
| 264 else { | |
| 265 angleX = angle; | |
| 266 if (transformValue->operationType() == WebKitCSSTransformValue::
SkewTransformOperation) { | |
| 267 if (transformValue->length() > 1) { | |
| 268 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiv
eValue*>(transformValue->itemWithoutBoundsCheck(1)); | |
| 269 angleY = secondValue->computeDegrees(); | |
| 270 } | |
| 271 } | |
| 272 } | |
| 273 operations.operations().append(SkewTransformOperation::create(angleX
, angleY, getTransformOperationType(transformValue->operationType()))); | |
| 274 break; | |
| 275 } | |
| 276 case WebKitCSSTransformValue::MatrixTransformOperation: { | |
| 277 if (transformValue->length() < 6) | |
| 278 break; | |
| 279 double a = firstValue->getDoubleValue(); | |
| 280 double b = static_cast<CSSPrimitiveValue*>(transformValue->itemWitho
utBoundsCheck(1))->getDoubleValue(); | |
| 281 double c = static_cast<CSSPrimitiveValue*>(transformValue->itemWitho
utBoundsCheck(2))->getDoubleValue(); | |
| 282 double d = static_cast<CSSPrimitiveValue*>(transformValue->itemWitho
utBoundsCheck(3))->getDoubleValue(); | |
| 283 double e = zoomFactor * static_cast<CSSPrimitiveValue*>(transformVal
ue->itemWithoutBoundsCheck(4))->getDoubleValue(); | |
| 284 double f = zoomFactor * static_cast<CSSPrimitiveValue*>(transformVal
ue->itemWithoutBoundsCheck(5))->getDoubleValue(); | |
| 285 operations.operations().append(MatrixTransformOperation::create(a, b
, c, d, e, f)); | |
| 286 break; | |
| 287 } | |
| 288 case WebKitCSSTransformValue::Matrix3DTransformOperation: { | |
| 289 if (transformValue->length() < 16) | |
| 290 break; | |
| 291 TransformationMatrix matrix(static_cast<CSSPrimitiveValue*>(transfor
mValue->itemWithoutBoundsCheck(0))->getDoubleValue(), | |
| 292 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(1))->getDoubleValue(), | |
| 293 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(2))->getDoubleValue(), | |
| 294 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(3))->getDoubleValue(), | |
| 295 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(4))->getDoubleValue(), | |
| 296 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(5))->getDoubleValue(), | |
| 297 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(6))->getDoubleValue(), | |
| 298 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(7))->getDoubleValue(), | |
| 299 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(8))->getDoubleValue(), | |
| 300 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(9))->getDoubleValue(), | |
| 301 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(10))->getDoubleValue(), | |
| 302 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(11))->getDoubleValue(), | |
| 303 zoomFactor * static_cast<CSSPrimitiveValue*>(tran
sformValue->itemWithoutBoundsCheck(12))->getDoubleValue(), | |
| 304 zoomFactor * static_cast<CSSPrimitiveValue*>(tran
sformValue->itemWithoutBoundsCheck(13))->getDoubleValue(), | |
| 305 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(14))->getDoubleValue(), | |
| 306 static_cast<CSSPrimitiveValue*>(transformValue->i
temWithoutBoundsCheck(15))->getDoubleValue()); | |
| 307 operations.operations().append(Matrix3DTransformOperation::create(ma
trix)); | |
| 308 break; | |
| 309 } | |
| 310 case WebKitCSSTransformValue::PerspectiveTransformOperation: { | |
| 311 Length p = Length(0, Fixed); | |
| 312 if (firstValue->isLength()) | |
| 313 p = convertToFloatLength(firstValue, style, rootStyle, zoomFacto
r); | |
| 314 else { | |
| 315 // This is a quirk that should go away when 3d transforms are fi
nalized. | |
| 316 double val = firstValue->getDoubleValue(); | |
| 317 p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Leng
th(Undefined); | |
| 318 } | |
| 319 | |
| 320 if (p.isUndefined()) | |
| 321 return false; | |
| 322 | |
| 323 operations.operations().append(PerspectiveTransformOperation::create
(p)); | |
| 324 break; | |
| 325 } | |
| 326 case WebKitCSSTransformValue::UnknownTransformOperation: | |
| 327 ASSERT_NOT_REACHED(); | |
| 328 break; | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 outOperations = operations; | |
| 333 return true; | |
| 334 } | |
| 335 | |
| 336 } // namespace WebCore | |
| OLD | NEW |