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; } } }
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; }