void GraphicsLayer::fetchTransformOperationList(const KeyframeValueList& valueList, TransformOperationList& list, bool& isValid, bool& hasBigRotation) { ASSERT(valueList.property() == AnimatedPropertyWebkitTransform); list.clear(); isValid = false; hasBigRotation = false; if (valueList.size() < 2) return; // Empty transforms match anything, so find the first non-empty entry as the reference. size_t firstIndex = 0; for ( ; firstIndex < valueList.size(); ++firstIndex) { if (operationsAt(valueList, firstIndex)->operations().size() > 0) break; } if (firstIndex >= valueList.size()) return; const TransformOperations* firstVal = operationsAt(valueList, firstIndex); // See if the keyframes are valid. for (size_t i = firstIndex + 1; i < valueList.size(); ++i) { const TransformOperations* val = operationsAt(valueList, i); // a null transform matches anything if (val->operations().isEmpty()) continue; if (firstVal->operations().size() != val->operations().size()) return; for (size_t j = 0; j < firstVal->operations().size(); ++j) { if (!firstVal->operations().at(j)->isSameType(*val->operations().at(j))) return; } } // Keyframes are valid, fill in the list. isValid = true; double lastRotAngle = 0.0; double maxRotAngle = -1.0; list.resize(firstVal->operations().size()); for (size_t j = 0; j < firstVal->operations().size(); ++j) { TransformOperation::OperationType type = firstVal->operations().at(j)->getOperationType(); list[j] = type; // if this is a rotation entry, we need to see if any angle differences are >= 180 deg if (type == TransformOperation::ROTATE_X || type == TransformOperation::ROTATE_Y || type == TransformOperation::ROTATE_Z || type == TransformOperation::ROTATE_3D) { lastRotAngle = static_cast<RotateTransformOperation*>(firstVal->operations().at(j).get())->angle(); if (maxRotAngle < 0) maxRotAngle = fabs(lastRotAngle); for (size_t i = firstIndex + 1; i < valueList.size(); ++i) { const TransformOperations* val = operationsAt(valueList, i); double rotAngle = val->operations().isEmpty() ? 0 : (static_cast<RotateTransformOperation*>(val->operations().at(j).get())->angle()); double diffAngle = fabs(rotAngle - lastRotAngle); if (diffAngle > maxRotAngle) maxRotAngle = diffAngle; lastRotAngle = rotAngle; } } } hasBigRotation = maxRotAngle >= 180.0; }
int GraphicsLayer::validateTransformOperations(const KeyframeValueList& valueList, bool& hasBigRotation) { ASSERT(valueList.property() == AnimatedPropertyTransform); hasBigRotation = false; if (valueList.size() < 2) return -1; // Empty transforms match anything, so find the first non-empty entry as the reference. size_t firstIndex = 0; for ( ; firstIndex < valueList.size(); ++firstIndex) { if (!operationsAt(valueList, firstIndex).operations().isEmpty()) break; } if (firstIndex >= valueList.size()) return -1; const TransformOperations& firstVal = operationsAt(valueList, firstIndex); // See if the keyframes are valid. for (size_t i = firstIndex + 1; i < valueList.size(); ++i) { const TransformOperations& val = operationsAt(valueList, i); // An empty transform list matches anything. if (val.operations().isEmpty()) continue; if (!firstVal.operationsMatch(val)) return -1; } // Keyframes are valid, check for big rotations. double lastRotationAngle = 0.0; double maxRotationAngle = -1.0; for (size_t j = 0; j < firstVal.operations().size(); ++j) { TransformOperation::OperationType type = firstVal.operations().at(j)->type(); // if this is a rotation entry, we need to see if any angle differences are >= 180 deg if (type == TransformOperation::ROTATE_X || type == TransformOperation::ROTATE_Y || type == TransformOperation::ROTATE_Z || type == TransformOperation::ROTATE_3D) { lastRotationAngle = downcast<RotateTransformOperation>(*firstVal.operations().at(j)).angle(); if (maxRotationAngle < 0) maxRotationAngle = fabs(lastRotationAngle); for (size_t i = firstIndex + 1; i < valueList.size(); ++i) { const TransformOperations& val = operationsAt(valueList, i); double rotationAngle = val.operations().isEmpty() ? 0 : downcast<RotateTransformOperation>(*val.operations().at(j)).angle(); double diffAngle = fabs(rotationAngle - lastRotationAngle); if (diffAngle > maxRotationAngle) maxRotationAngle = diffAngle; lastRotationAngle = rotationAngle; } } } hasBigRotation = maxRotationAngle >= 180.0; return firstIndex; }