예제 #1
0
NS_IMETHODIMP
nsSVGLength::SetValueAsString(const nsAString & aValueAsString)
{
  nsresult rv = NS_OK;

  char *str = ToNewCString(aValueAsString);

  char* number = str;
  while (*number && isspace(*number))
    ++number;

  if (*number) {
    char *rest;
    float value = float(PR_strtod(number, &rest));
    if (rest!=number) {
      const char* unitStr = nsCRT::strtok(rest, "\x20\x9\xD\xA", &rest);
      PRUint16 unitType = SVG_LENGTHTYPE_UNKNOWN;
      if (!unitStr || *unitStr=='\0') {
        unitType = SVG_LENGTHTYPE_NUMBER;
      } else {
        nsCOMPtr<nsIAtom> unitAtom = do_GetAtom(unitStr);
        if (unitAtom == nsGkAtoms::px)
          unitType = SVG_LENGTHTYPE_PX;
        else if (unitAtom == nsGkAtoms::mm)
          unitType = SVG_LENGTHTYPE_MM;
        else if (unitAtom == nsGkAtoms::cm)
          unitType = SVG_LENGTHTYPE_CM;
        else if (unitAtom == nsGkAtoms::in)
          unitType = SVG_LENGTHTYPE_IN;
        else if (unitAtom == nsGkAtoms::pt)
          unitType = SVG_LENGTHTYPE_PT;
        else if (unitAtom == nsGkAtoms::pc)
          unitType = SVG_LENGTHTYPE_PC;
        else if (unitAtom == nsGkAtoms::em)
          unitType = SVG_LENGTHTYPE_EMS;
        else if (unitAtom == nsGkAtoms::ex)
          unitType = SVG_LENGTHTYPE_EXS;
        else if (unitAtom == nsGkAtoms::percentage)
          unitType = SVG_LENGTHTYPE_PERCENTAGE;
      }
      if (IsValidUnitType(unitType) && NS_FloatIsFinite(value)) {
        WillModify();
        mValueInSpecifiedUnits = value;
        mSpecifiedUnitType     = unitType;
        DidModify();
      } else { // parse error
        // not a valid unit type
        rv = NS_ERROR_DOM_SYNTAX_ERR;
      }
    }
    else { // parse error
      // no number
      rv = NS_ERROR_DOM_SYNTAX_ERR;
    }
  }

  nsMemory::Free(str);

  return rv;
}
예제 #2
0
nsresult
nsSVGElement::ParseNumberOptionalNumber(const nsAString& aValue,
                                        PRUint32 aIndex1, PRUint32 aIndex2)
{
  NS_ConvertUTF16toUTF8 value(aValue);
  const char *str = value.get();

  if (NS_IsAsciiWhitespace(*str))
    return NS_ERROR_FAILURE;

  char *rest;
  float x = float(PR_strtod(str, &rest));
  float y = x;

  if (str == rest || !NS_FloatIsFinite(x)) {
    //first value was illformed
    return NS_ERROR_FAILURE;
  }
  
  if (*rest != '\0') {
    while (NS_IsAsciiWhitespace(*rest)) {
      ++rest;
    }
    if (*rest == ',') {
      ++rest;
    }

    y = float(PR_strtod(rest, &rest));
    if (*rest != '\0' || !NS_FloatIsFinite(y)) {
      //second value was illformed or there was trailing content
      return NS_ERROR_FAILURE;
    }
  }

  NumberAttributesInfo numberInfo = GetNumberInfo();

  numberInfo.mNumbers[aIndex1].SetBaseValue(x, this, PR_FALSE);
  numberInfo.mNumbers[aIndex2].SetBaseValue(y, this, PR_FALSE);
  return NS_OK;
}
예제 #3
0
static nsresult
GetValueFromString(const nsAString &aValueAsString,
                   float *aValue,
                   PRUint16 *aUnitType)
{
  NS_ConvertUTF16toUTF8 value(aValueAsString);
  const char *str = value.get();

  if (NS_IsAsciiWhitespace(*str))
    return NS_ERROR_DOM_SYNTAX_ERR;
  
  char *rest;
  *aValue = float(PR_strtod(str, &rest));
  if (rest != str && NS_FloatIsFinite(*aValue)) {
    *aUnitType = GetUnitTypeForString(rest);
    if (IsValidUnitType(*aUnitType)) {
      return NS_OK;
    }
  }
  
  return NS_ERROR_DOM_SYNTAX_ERR;
}
PRInt32
nsSVGTransformSMILAttr::ParseParameterList(const nsAString& aSpec,
                                           float* aVars,
                                           PRInt32 aNVars)
{
  NS_ConvertUTF16toUTF8 spec(aSpec);

  nsACString::const_iterator start, end;
  spec.BeginReading(start);
  spec.EndReading(end);

  SkipWsp(start, end);

  int numArgsFound = 0;

  while (start != end) {
    char const *arg = start.get();
    char *argend;
    float f = float(PR_strtod(arg, &argend));
    if (arg == argend || argend > end.get() || !NS_FloatIsFinite(f))
      return -1;

    if (numArgsFound < aNVars) {
      aVars[numArgsFound] = f;
    }

    start.advance(argend - arg);
    numArgsFound++;

    SkipWsp(start, end);
    if (*start == ',') {
      ++start;
      SkipWsp(start, end);
    }
  }

  return numArgsFound;
}
nsresult
SVGLengthListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                       const nsSMILValue& aTo,
                                       double& aDistance) const
{
  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
  NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type");

  const SVGLengthListAndInfo& from =
    *static_cast<const SVGLengthListAndInfo*>(aFrom.mU.mPtr);
  const SVGLengthListAndInfo& to =
    *static_cast<const SVGLengthListAndInfo*>(aTo.mU.mPtr);

  // To understand this code, see the comments documenting our Init() method,
  // and documenting SVGLengthListAndInfo::CanZeroPadList().

  NS_ASSERTION((from.CanZeroPadList() == to.CanZeroPadList()) ||
               (from.CanZeroPadList() && from.IsEmpty()) ||
               (to.CanZeroPadList() && to.IsEmpty()),
               "Only \"zero\" nsSMILValues from the SMIL engine should "
               "return PR_TRUE for CanZeroPadList() when the attribute "
               "being animated can't be zero padded");

  if ((from.Length() < to.Length() && !from.CanZeroPadList()) ||
      (to.Length() < from.Length() && !to.CanZeroPadList())) {
    // nsSVGUtils::ReportToConsole
    return NS_ERROR_FAILURE;
  }

  // We return the root of the sum of the squares of the deltas between the
  // user unit values of the lengths at each correspanding index. In the
  // general case, paced animation is probably not useful, but this strategy at
  // least does the right thing for paced animation in the face of simple
  // 'values' lists such as:
  //
  //   values="100 200 300; 101 201 301; 110 210 310"
  //
  // I.e. half way through the simple duration we'll get "105 205 305".

  double total = 0.0;

  PRUint32 i = 0;
  for (; i < from.Length() && i < to.Length(); ++i) {
    double f = from[i].GetValueInUserUnits(from.Element(), from.Axis());
    double t = to[i].GetValueInUserUnits(to.Element(), to.Axis());
    double delta = t - f;
    total += delta * delta;
  }

  // In the case that from.Length() != to.Length(), one of the following loops
  // will run. (OK since CanZeroPadList()==true for the other list.)

  for (; i < from.Length(); ++i) {
    double f = from[i].GetValueInUserUnits(from.Element(), from.Axis());
    total += f * f;
  }
  for (; i < to.Length(); ++i) {
    double t = to[i].GetValueInUserUnits(to.Element(), to.Axis());
    total += t * t;
  }

  float distance = sqrt(total);
  if (!NS_FloatIsFinite(distance)) {
    return NS_ERROR_FAILURE;
  }
  aDistance = distance;
  return NS_OK;
}