bool AnimatablePath::usesDefaultInterpolationWith(const AnimatableValue* value) const { // Default interpolation is used if the paths have different lengths, // or the paths have a segment with different types (ignoring "relativeness"). const StylePath* toPath = toAnimatablePath(value)->path(); if (!m_path || !toPath) return true; SVGPathByteStreamSource fromSource(path()->byteStream()); SVGPathByteStreamSource toSource(toPath->byteStream()); while (fromSource.hasMoreData()) { if (!toSource.hasMoreData()) return true; PathSegmentData fromSeg = fromSource.parseSegment(); PathSegmentData toSeg = toSource.parseSegment(); ASSERT(fromSeg.command != PathSegUnknown); ASSERT(toSeg.command != PathSegUnknown); if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType(toSeg.command)) return true; } return toSource.hasMoreData(); }
static bool pathSegTypesMatch(const Vector<SVGPathSegType>& a, const Vector<SVGPathSegType>& b) { if (a.size() != b.size()) return false; for (size_t i = 0; i < a.size(); i++) { if (toAbsolutePathSegType(a[i]) != toAbsolutePathSegType(b[i])) return false; } return true; }
bool SVGPathBlender::BlendState::canBlend(const PathSegmentData& fromSeg, const PathSegmentData& toSeg) { // Update state first because we'll need it if we return true below. m_typesAreEqual = fromSeg.command == toSeg.command; m_fromIsAbsolute = isAbsolutePathSegType(fromSeg.command); // If the types are equal, they'll blend regardless of parameters. if (m_typesAreEqual) return true; // Addition require segments with the same type. if (m_addTypesCount) return false; // Allow the segments to differ in "relativeness". return toAbsolutePathSegType(fromSeg.command) == toAbsolutePathSegType(toSeg.command); }
std::unique_ptr<InterpolableValue> consumeSingleCoordinate( const PathSegmentData& segment, PathCoordinates& coordinates) { bool isAbsolute = isAbsolutePathSegType(segment.command); std::unique_ptr<InterpolableList> result = InterpolableList::create(2); result->set( 0, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX)); result->set( 1, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY)); if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) { // Any upcoming 'closepath' commands bring us back to the location we have // just moved to. coordinates.initialX = coordinates.currentX; coordinates.initialY = coordinates.currentY; } return std::move(result); }
PathSegmentData consumeInterpolableSingleCoordinate( const InterpolableValue& value, SVGPathSegType segType, PathCoordinates& coordinates) { const InterpolableList& list = toInterpolableList(value); bool isAbsolute = isAbsolutePathSegType(segType); PathSegmentData segment; segment.command = segType; segment.targetPoint.setX(consumeInterpolableCoordinateAxis( list.get(0), isAbsolute, coordinates.currentX)); segment.targetPoint.setY(consumeInterpolableCoordinateAxis( list.get(1), isAbsolute, coordinates.currentY)); if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) { // Any upcoming 'closepath' commands bring us back to the location we have // just moved to. coordinates.initialX = coordinates.currentX; coordinates.initialY = coordinates.currentY; } return segment; }