Exemplo n.º 1
0
nsresult
SVGAnimatedPathSegList::
  SMILAnimatedPathSegList::ValueFromString(const nsAString& aStr,
                               const dom::SVGAnimationElement* /*aSrcElement*/,
                               nsSMILValue& aValue,
                               bool& aPreventCachingOfSandwich) const
{
  nsSMILValue val(SVGPathSegListSMILType::Singleton());
  SVGPathDataAndInfo *list = static_cast<SVGPathDataAndInfo*>(val.mU.mPtr);
  nsresult rv = list->SetValueFromString(aStr);
  if (NS_SUCCEEDED(rv)) {
    list->SetElement(mElement);
    aValue = Move(val);
  }
  aPreventCachingOfSandwich = false;
  return rv;
}
Exemplo n.º 2
0
nsSMILValue
SVGAnimatedPathSegList::SMILAnimatedPathSegList::GetBaseValue() const
{
  // To benefit from Return Value Optimization and avoid copy constructor calls
  // due to our use of return-by-value, we must return the exact same object
  // from ALL return points. This function must only return THIS variable:
  nsSMILValue val;

  nsSMILValue tmp(SVGPathSegListSMILType::Singleton());
  SVGPathDataAndInfo *list = static_cast<SVGPathDataAndInfo*>(tmp.mU.mPtr);
  nsresult rv = list->CopyFrom(mVal->mBaseVal);
  if (NS_SUCCEEDED(rv)) {
    list->SetElement(mElement);
    val = Move(tmp);
  }
  return val;
}
/**
 * Helper function for Add & Interpolate, to add multiples of two path-segment
 * lists.
 *
 * NOTE: aList1 and aList2 are assumed to have their segment-types and
 * segment-count match exactly (unless aList1 is an identity value).
 *
 * NOTE: aResult, the output list, is expected to either be an identity value
 * (in which case we'll grow it) *or* to already have the exactly right length
 * (e.g. in cases where aList1 and aResult are actually the same list).
 *
 * @param aCoeff1    The coefficient to use on the first path segment list.
 * @param aList1     The first path segment list. Allowed to be identity.
 * @param aCoeff2    The coefficient to use on the second path segment list.
 * @param aList2     The second path segment list.
 * @param [out] aResultSeg The resulting path segment list. Allowed to be
 *                         identity, in which case we'll grow it to the right
 *                         size. Also allowed to be the same list as aList1.
 */
static nsresult AddWeightedPathSegLists(double aCoeff1,
                                        const SVGPathDataAndInfo& aList1,
                                        double aCoeff2,
                                        const SVGPathDataAndInfo& aList2,
                                        SVGPathDataAndInfo& aResult) {
  MOZ_ASSERT(aCoeff1 >= 0.0 && aCoeff2 >= 0.0,
             "expecting non-negative coefficients");
  MOZ_ASSERT(!aList2.IsIdentity(), "expecting 2nd list to be non-identity");
  MOZ_ASSERT(aList1.IsIdentity() || aList1.Length() == aList2.Length(),
             "expecting 1st list to be identity or to have same "
             "length as 2nd list");
  MOZ_ASSERT(aResult.IsIdentity() || aResult.Length() == aList2.Length(),
             "expecting result list to be identity or to have same "
             "length as 2nd list");

  SVGPathDataAndInfo::const_iterator iter1, end1;
  if (aList1.IsIdentity()) {
    iter1 = end1 = nullptr;  // indicate that this is an identity list
  } else {
    iter1 = aList1.begin();
    end1 = aList1.end();
  }
  SVGPathDataAndInfo::const_iterator iter2 = aList2.begin();
  SVGPathDataAndInfo::const_iterator end2 = aList2.end();

  // Grow |aResult| if necessary. (NOTE: It's possible that aResult and aList1
  // are the same list, so this may implicitly resize aList1. That's fine,
  // because in that case, we will have already set iter1 to nullptr above, to
  // record that our first operand is an identity value.)
  if (aResult.IsIdentity()) {
    if (!aResult.SetLength(aList2.Length())) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    aResult.SetElement(aList2.Element());  // propagate target element info!
  }

  SVGPathDataAndInfo::iterator resultIter = aResult.begin();

  while ((!iter1 || iter1 != end1) && iter2 != end2) {
    AddWeightedPathSegs(aCoeff1, iter1, aCoeff2, iter2, resultIter);
  }
  MOZ_ASSERT(
      (!iter1 || iter1 == end1) && iter2 == end2 && resultIter == aResult.end(),
      "Very, very bad - path data corrupt");
  return NS_OK;
}