Vector<RefPtr<TransformOperation>> concat(const TransformOperations& a,
                                           const TransformOperations& b) {
   Vector<RefPtr<TransformOperation>> result;
   result.reserveCapacity(a.size() + b.size());
   result.appendVector(a.operations());
   result.appendVector(b.operations());
   return result;
 }
void ArgumentCoder<TransformOperations>::encode(ArgumentEncoder& encoder, const TransformOperations& transformOperations)
{
    encoder << static_cast<uint32_t>(transformOperations.size());
    for (size_t i = 0; i < transformOperations.size(); ++i) {
        const TransformOperation* operation = transformOperations.at(i);
        encoder.encodeEnum(operation->getOperationType());

        switch (operation->getOperationType()) {
        case TransformOperation::SCALE_X:
        case TransformOperation::SCALE_Y:
        case TransformOperation::SCALE:
        case TransformOperation::SCALE_Z:
        case TransformOperation::SCALE_3D:
            encoder << static_cast<const ScaleTransformOperation*>(operation)->x();
            encoder << static_cast<const ScaleTransformOperation*>(operation)->y();
            encoder << static_cast<const ScaleTransformOperation*>(operation)->z();
            break;
        case TransformOperation::TRANSLATE_X:
        case TransformOperation::TRANSLATE_Y:
        case TransformOperation::TRANSLATE:
        case TransformOperation::TRANSLATE_Z:
        case TransformOperation::TRANSLATE_3D:
            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->x());
            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->y());
            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->z());
            break;
        case TransformOperation::ROTATE:
        case TransformOperation::ROTATE_X:
        case TransformOperation::ROTATE_Y:
        case TransformOperation::ROTATE_3D:
            encoder << static_cast<const RotateTransformOperation*>(operation)->x();
            encoder << static_cast<const RotateTransformOperation*>(operation)->y();
            encoder << static_cast<const RotateTransformOperation*>(operation)->z();
            encoder << static_cast<const RotateTransformOperation*>(operation)->angle();
            break;
        case TransformOperation::SKEW_X:
        case TransformOperation::SKEW_Y:
        case TransformOperation::SKEW:
            encoder << static_cast<const SkewTransformOperation*>(operation)->angleX();
            encoder << static_cast<const SkewTransformOperation*>(operation)->angleY();
            break;
        case TransformOperation::MATRIX:
            ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const MatrixTransformOperation*>(operation)->matrix());
            break;
        case TransformOperation::MATRIX_3D:
            ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const Matrix3DTransformOperation*>(operation)->matrix());
            break;
        case TransformOperation::PERSPECTIVE:
            ArgumentCoder<Length>::encode(encoder, static_cast<const PerspectiveTransformOperation*>(operation)->perspective());
            break;
        case TransformOperation::IDENTITY:
            break;
        case TransformOperation::NONE:
            ASSERT_NOT_REACHED();
            break;
        }
    }
}
void PrintTo(const AnimatableTransform& animTransform, ::std::ostream* os)
{
    TransformOperations ops = animTransform.transformOperations();

    *os << "AnimatableTransform(";
    // FIXME: TransformOperations should really have it's own pretty-printer
    // then we could just call that.
    // FIXME: Output useful names not just the raw matrixes.
    for (unsigned i = 0; i < ops.size(); i++) {
        const TransformOperation* op = ops.at(i);

        TransformationMatrix matrix;
        op->apply(matrix, FloatSize(1.0, 1.0));

        *os << "[";
        if (matrix.isAffine()) {
            *os << matrix.a();
            *os << " " << matrix.b();
            *os << " " << matrix.c();
            *os << " " << matrix.d();
            *os << " " << matrix.e();
            *os << " " << matrix.f();
        } else {
            *os << matrix.m11();
            *os << " " << matrix.m12();
            *os << " " << matrix.m13();
            *os << " " << matrix.m14();
            *os << " ";
            *os << " " << matrix.m21();
            *os << " " << matrix.m22();
            *os << " " << matrix.m23();
            *os << " " << matrix.m24();
            *os << " ";
            *os << " " << matrix.m31();
            *os << " " << matrix.m32();
            *os << " " << matrix.m33();
            *os << " " << matrix.m34();
            *os << " ";
            *os << " " << matrix.m41();
            *os << " " << matrix.m42();
            *os << " " << matrix.m43();
            *os << " " << matrix.m44();
        }
        *os << "]";
        if (i < ops.size() - 1)
            *os << ", ";
    }
    *os << ")";
}
static TransformationMatrix applyTransformAnimation(const TransformOperations& from, const TransformOperations& to, double progress, const FloatSize& boxSize, bool listsMatch)
{
    TransformationMatrix matrix;

    // First frame of an animation.
    if (!progress) {
        from.apply(boxSize, matrix);
        return matrix;
    }

    // Last frame of an animation.
    if (progress == 1) {
        to.apply(boxSize, matrix);
        return matrix;
    }

    // If we have incompatible operation lists, we blend the resulting matrices.
    if (!listsMatch) {
        TransformationMatrix fromMatrix;
        to.apply(boxSize, matrix);
        from.apply(boxSize, fromMatrix);
        matrix.blend(fromMatrix, progress);
        return matrix;
    }

    // Animation to "-webkit-transform: none".
    if (!to.size()) {
        TransformOperations blended(from);
        for (auto& operation : blended.operations())
            operation->blend(nullptr, progress, true)->apply(matrix, boxSize);
        return matrix;
    }

    // Animation from "-webkit-transform: none".
    if (!from.size()) {
        TransformOperations blended(to);
        for (auto& operation : blended.operations())
            operation->blend(nullptr, 1 - progress, true)->apply(matrix, boxSize);
        return matrix;
    }

    // Normal animation with a matching operation list.
    TransformOperations blended(to);
    for (size_t i = 0; i < blended.operations().size(); ++i)
        blended.operations()[i]->blend(from.at(i), progress, !from.at(i))->apply(matrix, boxSize);
    return matrix;
}
TransformOperations TransformOperations::blend(const TransformOperations& from, double progress, const LayoutSize& size) const
{
    if (from == *this)
        return *this;

    if (from.size() && from.operationsMatch(*this))
        return blendByMatchingOperations(from, progress);

    return blendByUsingMatrixInterpolation(from, progress, size);
}
PassOwnPtr<WebTransformOperations> toWebTransformOperations(const TransformOperations& transformOperations, const FloatSize& boxSize)
{
    // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
    OwnPtr<WebTransformOperations> webTransformOperations = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations());
    if (!webTransformOperations)
        return nullptr;
    for (size_t j = 0; j < transformOperations.size(); ++j) {
        TransformOperation::OperationType operationType = transformOperations.operations()[j]->getOperationType();
        switch (operationType) {
        case TransformOperation::SCALE_X:
        case TransformOperation::SCALE_Y:
        case TransformOperation::SCALE_Z:
        case TransformOperation::SCALE_3D:
        case TransformOperation::SCALE: {
            ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
            break;
        }
        case TransformOperation::TRANSLATE_X:
        case TransformOperation::TRANSLATE_Y:
        case TransformOperation::TRANSLATE_Z:
        case TransformOperation::TRANSLATE_3D:
        case TransformOperation::TRANSLATE: {
            TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendTranslate(floatValueForLength(transform->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1));
            break;
        }
        case TransformOperation::ROTATE_X:
        case TransformOperation::ROTATE_Y:
        case TransformOperation::ROTATE_3D:
        case TransformOperation::ROTATE: {
            RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
            break;
        }
        case TransformOperation::SKEW_X:
        case TransformOperation::SKEW_Y:
        case TransformOperation::SKEW: {
            SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendSkew(transform->angleX(), transform->angleY());
            break;
        }
        case TransformOperation::MATRIX: {
            MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations->appendMatrix(TransformSkMatrix44Conversions::convert(m));
            break;
        }
        case TransformOperation::MATRIX_3D: {
            Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations->appendMatrix(TransformSkMatrix44Conversions::convert(m));
            break;
        }
        case TransformOperation::PERSPECTIVE: {
            PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendPerspective(floatValueForLength(transform->perspective(), 0));
            break;
        }
        case TransformOperation::IDENTITY:
            webTransformOperations->appendIdentity();
            break;
        case TransformOperation::NONE:
            // Do nothing.
            break;
        } // switch
    } // for each operation

    return webTransformOperations.release();
}
void toWebTransformOperations(const TransformOperations& transformOperations, WebTransformOperations* webTransformOperations)
{
    // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
    for (size_t j = 0; j < transformOperations.size(); ++j) {
        switch (transformOperations.operations()[j]->type()) {
        case TransformOperation::ScaleX:
        case TransformOperation::ScaleY:
        case TransformOperation::ScaleZ:
        case TransformOperation::Scale3D:
        case TransformOperation::Scale: {
            ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
            break;
        }
        case TransformOperation::TranslateX:
        case TransformOperation::TranslateY:
        case TransformOperation::TranslateZ:
        case TransformOperation::Translate3D:
        case TransformOperation::Translate: {
            TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
            ASSERT(transform->x().isFixed() && transform->y().isFixed());
            webTransformOperations->appendTranslate(transform->x().value(), transform->y().value(), transform->z());
            break;
        }
        case TransformOperation::RotateX:
        case TransformOperation::RotateY:
        case TransformOperation::Rotate3D:
        case TransformOperation::Rotate: {
            RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
            break;
        }
        case TransformOperation::SkewX:
        case TransformOperation::SkewY:
        case TransformOperation::Skew: {
            SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendSkew(transform->angleX(), transform->angleY());
            break;
        }
        case TransformOperation::Matrix: {
            MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
            break;
        }
        case TransformOperation::Matrix3D: {
            Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
            break;
        }
        case TransformOperation::Perspective: {
            PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations->appendPerspective(transform->perspective());
            break;
        }
        case TransformOperation::Interpolated: {
            TransformationMatrix m;
            transformOperations.operations()[j]->apply(m, FloatSize());
            webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
            break;
        }
        case TransformOperation::Identity:
            webTransformOperations->appendIdentity();
            break;
        case TransformOperation::None:
            // Do nothing.
            break;
        } // switch
    } // for each operation
}
void ArgumentCoder<TransformOperations>::encode(ArgumentEncoder& encoder, const TransformOperations& transformOperations)
{
    encoder << static_cast<uint32_t>(transformOperations.size());
    for (const auto& operation : transformOperations.operations()) {
        encoder.encodeEnum(operation->type());

        switch (operation->type()) {
        case TransformOperation::SCALE_X:
        case TransformOperation::SCALE_Y:
        case TransformOperation::SCALE:
        case TransformOperation::SCALE_Z:
        case TransformOperation::SCALE_3D: {
            const auto& scaleOperation = downcast<ScaleTransformOperation>(*operation);
            encoder << scaleOperation.x();
            encoder << scaleOperation.y();
            encoder << scaleOperation.z();
            break;
        }
        case TransformOperation::TRANSLATE_X:
        case TransformOperation::TRANSLATE_Y:
        case TransformOperation::TRANSLATE:
        case TransformOperation::TRANSLATE_Z:
        case TransformOperation::TRANSLATE_3D: {
            const auto& translateOperation = downcast<TranslateTransformOperation>(*operation);
            ArgumentCoder<Length>::encode(encoder, translateOperation.x());
            ArgumentCoder<Length>::encode(encoder, translateOperation.y());
            ArgumentCoder<Length>::encode(encoder, translateOperation.z());
            break;
        }
        case TransformOperation::ROTATE:
        case TransformOperation::ROTATE_X:
        case TransformOperation::ROTATE_Y:
        case TransformOperation::ROTATE_3D: {
            const auto& rotateOperation = downcast<RotateTransformOperation>(*operation);
            encoder << rotateOperation.x();
            encoder << rotateOperation.y();
            encoder << rotateOperation.z();
            encoder << rotateOperation.angle();
            break;
        }
        case TransformOperation::SKEW_X:
        case TransformOperation::SKEW_Y:
        case TransformOperation::SKEW: {
            const auto& skewOperation = downcast<SkewTransformOperation>(*operation);
            encoder << skewOperation.angleX();
            encoder << skewOperation.angleY();
            break;
        }
        case TransformOperation::MATRIX:
            ArgumentCoder<TransformationMatrix>::encode(encoder, downcast<MatrixTransformOperation>(*operation).matrix());
            break;
        case TransformOperation::MATRIX_3D:
            ArgumentCoder<TransformationMatrix>::encode(encoder, downcast<Matrix3DTransformOperation>(*operation).matrix());
            break;
        case TransformOperation::PERSPECTIVE:
            ArgumentCoder<Length>::encode(encoder, downcast<PerspectiveTransformOperation>(*operation).perspective());
            break;
        case TransformOperation::IDENTITY:
            break;
        case TransformOperation::NONE:
            ASSERT_NOT_REACHED();
            break;
        }
    }
}
Beispiel #9
0
WebTransformOperations toWebTransformOperations(const TransformOperations& transformOperations, const FloatSize& boxSize)
{
    // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
    WebTransformOperations webTransformOperations;
    for (size_t j = 0; j < transformOperations.size(); ++j) {
        TransformOperation::OperationType operationType = transformOperations.operations()[j]->getOperationType();
        switch (operationType) {
        case TransformOperation::SCALE_X:
        case TransformOperation::SCALE_Y:
        case TransformOperation::SCALE_Z:
        case TransformOperation::SCALE_3D:
        case TransformOperation::SCALE: {
            ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations.appendScale(transform->x(), transform->y(), transform->z());
            break;
        }
        case TransformOperation::TRANSLATE_X:
        case TransformOperation::TRANSLATE_Y:
        case TransformOperation::TRANSLATE_Z:
        case TransformOperation::TRANSLATE_3D:
        case TransformOperation::TRANSLATE: {
            TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations.appendTranslate(floatValueForLength(transform->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1));
            break;
        }
        case TransformOperation::ROTATE_X:
        case TransformOperation::ROTATE_Y:
        case TransformOperation::ROTATE_3D:
        case TransformOperation::ROTATE: {
            RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations.appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
            break;
        }
        case TransformOperation::SKEW_X:
        case TransformOperation::SKEW_Y:
        case TransformOperation::SKEW: {
            SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations.appendSkew(transform->angleX(), transform->angleY());
            break;
        }
        case TransformOperation::MATRIX: {
            MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations.appendMatrix(WebTransformationMatrix(m));
            break;
        }
        case TransformOperation::MATRIX_3D: {
            Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
            TransformationMatrix m = transform->matrix();
            webTransformOperations.appendMatrix(WebTransformationMatrix(m));
            break;
        }
        case TransformOperation::PERSPECTIVE: {
            PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
            webTransformOperations.appendPerspective(floatValueForLength(transform->perspective(), 0));
            break;
        }
        case TransformOperation::IDENTITY:
        case TransformOperation::NONE:
            // Do nothing.
            break;
        } // switch
    } // for each operation

    return webTransformOperations;
}