153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) Research In Motion Limited 2011. All rights reserved.
1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * This library is free software; you can redistribute it and/or
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modify it under the terms of the GNU Library General Public
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * License as published by the Free Software Foundation; either
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * version 2 of the License, or (at your option) any later version.
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * This library is distributed in the hope that it will be useful,
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Library General Public License for more details.
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * You should have received a copy of the GNU Library General Public License
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Boston, MA 02110-1301, USA.
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h"
3081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/css/resolver/TransformBuilder.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/css/CSSPrimitiveValueMappings.h"
335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/CSSTransformValue.h"
3481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h"
35f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/Matrix3DTransformOperation.h"
36f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/MatrixTransformOperation.h"
37f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/PerspectiveTransformOperation.h"
38f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/RotateTransformOperation.h"
39f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/ScaleTransformOperation.h"
40f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/SkewTransformOperation.h"
41f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/TransformationMatrix.h"
42f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/transforms/TranslateTransformOperation.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace WebCore {
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TransformBuilder::TransformBuilder()
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TransformBuilder::~TransformBuilder()
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
54a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static Length convertToFloatLength(CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
56a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return primitiveValue ? primitiveValue->convertToLength<FixedConversion | PercentConversion>(conversionData) : Length(Undefined);
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)static TransformOperation::OperationType getTransformOperationType(CSSTransformValue::TransformOperationType type)
6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    switch (type) {
621fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::ScaleTransformOperation: return TransformOperation::Scale;
631fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::ScaleXTransformOperation: return TransformOperation::ScaleX;
641fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::ScaleYTransformOperation: return TransformOperation::ScaleY;
651fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::ScaleZTransformOperation: return TransformOperation::ScaleZ;
661fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::Scale3DTransformOperation: return TransformOperation::Scale3D;
671fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::TranslateTransformOperation: return TransformOperation::Translate;
681fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::TranslateXTransformOperation: return TransformOperation::TranslateX;
691fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::TranslateYTransformOperation: return TransformOperation::TranslateY;
701fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::TranslateZTransformOperation: return TransformOperation::TranslateZ;
711fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::Translate3DTransformOperation: return TransformOperation::Translate3D;
721fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::RotateTransformOperation: return TransformOperation::Rotate;
731fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::RotateXTransformOperation: return TransformOperation::RotateX;
741fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::RotateYTransformOperation: return TransformOperation::RotateY;
751fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::RotateZTransformOperation: return TransformOperation::RotateZ;
761fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::Rotate3DTransformOperation: return TransformOperation::Rotate3D;
771fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::SkewTransformOperation: return TransformOperation::Skew;
781fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::SkewXTransformOperation: return TransformOperation::SkewX;
791fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::SkewYTransformOperation: return TransformOperation::SkewY;
801fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::MatrixTransformOperation: return TransformOperation::Matrix;
811fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::Matrix3DTransformOperation: return TransformOperation::Matrix3D;
821fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::PerspectiveTransformOperation: return TransformOperation::Perspective;
831fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    case CSSTransformValue::UnknownTransformOperation: return TransformOperation::None;
8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
851fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    return TransformOperation::None;
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
88a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToLengthConversionData& conversionData, TransformOperations& outOperations)
8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!inValue || !inValue->isValueList()) {
9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        outOperations.clear();
9253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
9353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
95a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    float zoomFactor = conversionData.zoom();
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    TransformOperations operations;
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        CSSValue* currValue = i.value();
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!currValue->isTransformValue())
10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        CSSTransformValue* transformValue = toCSSTransformValue(i.value());
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (!transformValue->length())
10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        bool haveNonPrimitiveValue = false;
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (unsigned j = 0; j < transformValue->length(); ++j) {
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (!transformValue->itemWithoutBoundsCheck(j)->isPrimitiveValue()) {
11053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                haveNonPrimitiveValue = true;
11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                break;
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (haveNonPrimitiveValue)
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
11653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
117e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        CSSPrimitiveValue* firstValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(0));
11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        switch (transformValue->operationType()) {
1205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::ScaleTransformOperation:
1215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::ScaleXTransformOperation:
1225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::ScaleYTransformOperation: {
12353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double sx = 1.0;
12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double sy = 1.0;
1255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation)
12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sy = firstValue->getDoubleValue();
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sx = firstValue->getDoubleValue();
1295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) {
13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 1) {
131e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        sy = secondValue->getDoubleValue();
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    } else
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        sy = sx;
13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType())));
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
1405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::ScaleZTransformOperation:
1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::Scale3DTransformOperation: {
14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double sx = 1.0;
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double sy = 1.0;
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double sz = 1.0;
1455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::ScaleZTransformOperation)
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sz = firstValue->getDoubleValue();
1475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            else if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation)
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sy = firstValue->getDoubleValue();
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                sx = firstValue->getDoubleValue();
1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) {
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 2) {
153e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2));
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        sz = thirdValue->getDoubleValue();
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
15653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 1) {
157e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        sy = secondValue->getDoubleValue();
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    } else
16053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        sy = sx;
16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType())));
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::TranslateTransformOperation:
1675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::TranslateXTransformOperation:
1685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::TranslateYTransformOperation: {
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length tx = Length(0, Fixed);
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length ty = Length(0, Fixed);
1715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation)
172a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                ty = convertToFloatLength(firstValue, conversionData);
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
174a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                tx = convertToFloatLength(firstValue, conversionData);
1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) {
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 1) {
177e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        ty = convertToFloatLength(secondValue, conversionData);
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
18053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
18153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
18253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (tx.isUndefined() || ty.isUndefined())
18453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                return false;
18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType())));
18753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
18853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
1895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::TranslateZTransformOperation:
1905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::Translate3DTransformOperation: {
19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length tx = Length(0, Fixed);
19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length ty = Length(0, Fixed);
19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length tz = Length(0, Fixed);
1945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::TranslateZTransformOperation)
195a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                tz = convertToFloatLength(firstValue, conversionData);
1965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            else if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation)
197a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                ty = convertToFloatLength(firstValue, conversionData);
19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
199a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                tx = convertToFloatLength(firstValue, conversionData);
2005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) {
20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 2) {
202e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2));
203a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        tz = convertToFloatLength(thirdValue, conversionData);
20453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
20553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 1) {
206e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
207a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        ty = convertToFloatLength(secondValue, conversionData);
20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined())
21353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                return false;
21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType())));
21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::RotateTransformOperation: {
21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angle = firstValue->computeDegrees();
22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType())));
22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::RotateXTransformOperation:
2245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::RotateYTransformOperation:
2255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::RotateZTransformOperation: {
22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double x = 0;
22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double y = 0;
22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double z = 0;
22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angle = firstValue->computeDegrees();
23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::RotateXTransformOperation)
23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                x = 1;
2335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            else if (transformValue->operationType() == CSSTransformValue::RotateYTransformOperation)
23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                y = 1;
23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else
23653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                z = 1;
23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType())));
23853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::Rotate3DTransformOperation: {
24153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (transformValue->length() < 4)
24253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                break;
243e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
244e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2));
245e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            CSSPrimitiveValue* fourthValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3));
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double x = firstValue->getDoubleValue();
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double y = secondValue->getDoubleValue();
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double z = thirdValue->getDoubleValue();
24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angle = fourthValue->computeDegrees();
25053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType())));
25153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::SkewTransformOperation:
2545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::SkewXTransformOperation:
2555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::SkewYTransformOperation: {
25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angleX = 0;
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angleY = 0;
25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double angle = firstValue->computeDegrees();
2595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if (transformValue->operationType() == CSSTransformValue::SkewYTransformOperation)
26053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                angleY = angle;
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                angleX = angle;
2635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (transformValue->operationType() == CSSTransformValue::SkewTransformOperation) {
26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    if (transformValue->length() > 1) {
265e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                        CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                        angleY = secondValue->computeDegrees();
26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                    }
26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                }
26953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType())));
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::MatrixTransformOperation: {
27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (transformValue->length() < 6)
27553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                break;
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            double a = firstValue->getDoubleValue();
277e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            double b = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue();
278e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            double c = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue();
279e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            double d = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue();
280e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            double e = zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue();
281e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            double f = zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue();
28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f));
28353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
28453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
2855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::Matrix3DTransformOperation: {
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (transformValue->length() < 16)
28753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                break;
288e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            TransformationMatrix matrix(toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(0))->getDoubleValue(),
289e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(),
290e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(),
291e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(),
292e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(),
293e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(),
294e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(6))->getDoubleValue(),
295e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(7))->getDoubleValue(),
296e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(8))->getDoubleValue(),
297e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(9))->getDoubleValue(),
298e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(10))->getDoubleValue(),
299e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(11))->getDoubleValue(),
300e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(12))->getDoubleValue(),
301e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(13))->getDoubleValue(),
302e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(14))->getDoubleValue(),
303e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)                toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(15))->getDoubleValue());
30453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(Matrix3DTransformOperation::create(matrix));
30553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
30653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
3075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::PerspectiveTransformOperation: {
30853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            Length p = Length(0, Fixed);
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (firstValue->isLength())
310a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                p = convertToFloatLength(firstValue, conversionData);
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            else {
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                // This is a quirk that should go away when 3d transforms are finalized.
31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                double val = firstValue->getDoubleValue();
31453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Length(Undefined);
31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
31753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (p.isUndefined())
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                return false;
31953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            operations.operations().append(PerspectiveTransformOperation::create(p));
32153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
3235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        case CSSTransformValue::UnknownTransformOperation:
32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            ASSERT_NOT_REACHED();
32553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
32653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
32753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
32853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    outOperations = operations;
33053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return true;
33153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
33253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} // namespace WebCore
334