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();
}
Exemple #2
0
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;
}