void SVGComponentTransferFunctionElement::parseMappedAttribute(Attribute* attr)
{
    const String& value = attr->value();
    if (attr->name() == SVGNames::typeAttr) {
        if (value == "identity")
            setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_IDENTITY);
        else if (value == "table")
            setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_TABLE);
        else if (value == "discrete")
            setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_DISCRETE);
        else if (value == "linear")
            setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_LINEAR);
        else if (value == "gamma")
            setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_GAMMA);
    } else if (attr->name() == SVGNames::tableValuesAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedTableValuesListWrappers(newList.size());
        setTableValuesBaseValue(newList);
    } else if (attr->name() == SVGNames::slopeAttr)
        setSlopeBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::interceptAttr)
        setInterceptBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::amplitudeAttr)
        setAmplitudeBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::exponentAttr)
        setExponentBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::offsetAttr)
        setOffsetBaseValue(value.toFloat());
    else
        SVGElement::parseMappedAttribute(attr);
}
void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!isSupportedAttribute(name)) {
        SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
        return;
    }

    if (name == SVGNames::typeAttr) {
        ColorMatrixType propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value);
        if (propertyValue > 0)
            setTypeBaseValue(propertyValue);
        return;
    }

    if (name == SVGNames::inAttr) {
        setIn1BaseValue(value);
        return;
    }

    if (name == SVGNames::valuesAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedValuesListWrappers(newList.size());
        setValuesBaseValue(newList);
        return;
    }

    ASSERT_NOT_REACHED();
}
void
DOMSVGAnimatedNumberList::InternalBaseValListWillChangeTo(const SVGNumberList& aNewValue)
{
  // When the number of items in our internal counterpart's baseVal changes,
  // we MUST keep our baseVal in sync. If we don't, script will either see a
  // list that is too short and be unable to access indexes that should be
  // valid, or else, MUCH WORSE, script will see a list that is too long and be
  // able to access "items" at indexes that are out of bounds (read/write to
  // bad memory)!!

  RefPtr<DOMSVGAnimatedNumberList> kungFuDeathGrip;
  if (mBaseVal) {
    if (aNewValue.Length() < mBaseVal->LengthNoFlush()) {
      // InternalListLengthWillChange might clear last reference to |this|.
      // Retain a temporary reference to keep from dying before returning.
      kungFuDeathGrip = this;
    }
    mBaseVal->InternalListLengthWillChange(aNewValue.Length());
  }

  // If our attribute is not animating, then our animVal mirrors our baseVal
  // and we must sync its length too. (If our attribute is animating, then the
  // SMIL engine takes care of calling InternalAnimValListWillChangeTo() if
  // necessary.)

  if (!IsAnimating()) {
    InternalAnimValListWillChangeTo(aNewValue);
  }
}
nsresult
SVGAnimatedNumberList::SetBaseValueString(const nsAString& aValue)
{
  SVGNumberList newBaseValue;
  nsresult rv = newBaseValue.SetValueFromString(aValue);
  if (NS_FAILED(rv)) {
    return rv;
  }

  DOMSVGAnimatedNumberList *domWrapper =
    DOMSVGAnimatedNumberList::GetDOMWrapperIfExists(this);
  if (domWrapper) {
    // We must send this notification *before* changing mBaseVal! If the length
    // of our baseVal is being reduced, our baseVal's DOM wrapper list may have
    // to remove DOM items from itself, and any removed DOM items need to copy
    // their internal counterpart values *before* we change them.
    //
    domWrapper->InternalBaseValListWillChangeTo(newBaseValue);
  }

  // We don't need to call DidChange* here - we're only called by
  // nsSVGElement::ParseAttribute under Element::SetAttr,
  // which takes care of notifying.

  mIsBaseSet = true;
  rv = mBaseVal.CopyFrom(newBaseValue);
  if (NS_FAILED(rv) && domWrapper) {
    // Attempting to increase mBaseVal's length failed - reduce domWrapper
    // back to the same length:
    domWrapper->InternalBaseValListWillChangeTo(mBaseVal);
  }
  return rv;
}
void SVGTextPositioningElement::parseMappedAttribute(Attribute* attr)
{
    if (attr->name() == SVGNames::xAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeWidth);
        detachAnimatedXListWrappers(newList.size());
        setXBaseValue(newList);
    } else if (attr->name() == SVGNames::yAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeHeight);
        detachAnimatedYListWrappers(newList.size());
        setYBaseValue(newList);
    } else if (attr->name() == SVGNames::dxAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeWidth);
        detachAnimatedDxListWrappers(newList.size());
        setDxBaseValue(newList);
    } else if (attr->name() == SVGNames::dyAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeHeight);
        detachAnimatedDyListWrappers(newList.size());
        setDyBaseValue(newList);
    } else if (attr->name() == SVGNames::rotateAttr) {
        SVGNumberList newList;
        newList.parse(attr->value());
        detachAnimatedRotateListWrappers(newList.size());
        setRotateBaseValue(newList);
    } else
        SVGTextContentElement::parseMappedAttribute(attr);
}
Esempio n. 6
0
nsresult
SVGNumberList::SetValueFromString(const nsAString& aValue)
{
  SVGNumberList temp;

  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
    tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);

  nsAutoCString str;  // outside loop to minimize memory churn

  while (tokenizer.hasMoreTokens()) {
    CopyUTF16toUTF8(tokenizer.nextToken(), str); // NS_ConvertUTF16toUTF8
    const char *token = str.get();
    if (*token == '\0') {
      return NS_ERROR_DOM_SYNTAX_ERR; // nothing between commas
    }
    char *end;
    float num = float(PR_strtod(token, &end));
    if (*end != '\0' || !NS_finite(num)) {
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    if (!temp.AppendItem(num)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  if (tokenizer.lastTokenEndedWithSeparator()) {
    return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
  }
  return CopyFrom(temp);
}
Esempio n. 7
0
SVGPropertyBase* SVGNumberListInterpolationType::appliedSVGValue(
    const InterpolableValue& interpolableValue,
    const NonInterpolableValue*) const {
    SVGNumberList* result = SVGNumberList::create();
    const InterpolableList& list = toInterpolableList(interpolableValue);
    for (size_t i = 0; i < list.length(); i++)
        result->append(
            SVGNumber::create(toInterpolableNumber(list.get(i))->value()));
    return result;
}
Esempio n. 8
0
static inline void extractFloatValuesFromSVGNumberList(const SVGNumberList& list, Vector<float>& floatValues, unsigned textContentLength)
{
    unsigned length = list.size();
    if (length > textContentLength)
        length = textContentLength;
    floatValues.reserveCapacity(length);

    for (unsigned i = 0; i < length; ++i)
        floatValues.append(list.at(i));
}
void SVGNumberList::add(SVGPropertyBase* other, SVGElement* contextElement)
{
    SVGNumberList* otherList = toSVGNumberList(other);

    if (length() != otherList->length())
        return;

    for (size_t i = 0; i < length(); ++i)
        at(i)->setValue(at(i)->value() + otherList->at(i)->value());
}
Esempio n. 10
0
PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* filterBuilder)
{
    FilterEffect* input1 = filterBuilder->getEffectById(in1());

    if (!input1)
        return 0;

    Vector<float> kernelMatrixValues;
    SVGNumberList* numbers = kernelMatrix();

    ExceptionCode ec = 0;
    int numberOfItems = numbers->numberOfItems();
    for (int i = 0; i < numberOfItems; ++i)
        kernelMatrixValues.append(numbers->getItem(i, ec));

    int orderXValue = orderX();
    int orderYValue = orderY();
    if (!hasAttribute(SVGNames::orderAttr)) {
        orderXValue = 3;
        orderYValue = 3;
    }
    // The spec says this is a requirement, and should bail out if fails
    if (orderXValue * orderYValue != numberOfItems)
        return 0;

    int targetXValue = targetX();
    int targetYValue = targetY();
    if (hasAttribute(SVGNames::targetXAttr) && (targetXValue < 0 || targetXValue >= orderXValue))
        return 0;
    // The spec says the default value is: targetX = floor ( orderX / 2 ))
    if (!hasAttribute(SVGNames::targetXAttr))
        targetXValue = static_cast<int>(floorf(orderXValue / 2));
    if (hasAttribute(SVGNames::targetYAttr) && (targetYValue < 0 || targetYValue >= orderYValue))
        return 0;
    // The spec says the default value is: targetY = floor ( orderY / 2 ))
    if (!hasAttribute(SVGNames::targetYAttr))
        targetYValue = static_cast<int>(floorf(orderYValue / 2));

    float divisorValue = divisor();
    if (hasAttribute(SVGNames::divisorAttr) && !divisorValue)
        return 0;
    if (!hasAttribute(SVGNames::divisorAttr)) {
        for (int i = 0; i < numberOfItems; ++i)
            divisorValue += kernelMatrixValues[i];
        if (!divisorValue)
            divisorValue = 1;
    }

    RefPtr<FilterEffect> effect = FEConvolveMatrix::create(
                                      IntSize(orderXValue, orderYValue), divisorValue,
                                      bias(), IntPoint(targetXValue, targetYValue), static_cast<EdgeModeType>(edgeMode()),
                                      FloatPoint(kernelUnitLengthX(), kernelUnitLengthX()), preserveAlpha(), kernelMatrixValues);
    effect->inputEffects().append(input1);
    return effect.release();
}
void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!isSupportedAttribute(name)) {
        SVGTextContentElement::parseAttribute(name, value);
        return;
    }

    if (name == SVGNames::xAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeWidth);
        detachAnimatedXListWrappers(newList.size());
        setXBaseValue(newList);
        return;
    }

    if (name == SVGNames::yAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeHeight);
        detachAnimatedYListWrappers(newList.size());
        setYBaseValue(newList);
        return;
    }

    if (name == SVGNames::dxAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeWidth);
        detachAnimatedDxListWrappers(newList.size());
        setDxBaseValue(newList);
        return;
    }

    if (name == SVGNames::dyAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeHeight);
        detachAnimatedDyListWrappers(newList.size());
        setDyBaseValue(newList);
        return;
    }

    if (name == SVGNames::rotateAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedRotateListWrappers(newList.size());
        setRotateBaseValue(newList);
        return;
    }

    ASSERT_NOT_REACHED();
}
Esempio n. 12
0
void
DOMSVGAnimatedNumberList::InternalAnimValListWillChangeTo(const SVGNumberList& aNewValue)
{
  if (mAnimVal) {
    mAnimVal->InternalListLengthWillChange(aNewValue.Length());
  }
}
bool SVGFEColorMatrixElement::build(SVGResourceFilter* filterResource)
{
    FilterEffect* input1 = filterResource->builder()->getEffectById(in1());

    if (!input1)
        return false;

    Vector<float> filterValues;
    SVGNumberList* numbers = values();
    const ColorMatrixType filterType(static_cast<const ColorMatrixType>(type()));

    // Use defaults if values is empty (SVG 1.1 15.10).
    if (!hasAttribute(SVGNames::valuesAttr)) {
        switch (filterType) {
        case FECOLORMATRIX_TYPE_MATRIX:
            for (size_t i = 0; i < 20; i++)
                filterValues.append((i % 6) ? 0.0f : 1.0f);
            break;
        case FECOLORMATRIX_TYPE_HUEROTATE:
            filterValues.append(0.0f);
            break;
        case FECOLORMATRIX_TYPE_SATURATE:
            filterValues.append(1.0f);
            break;
        default:
            break;
        }
    } else {
        size_t size = numbers->numberOfItems();
        for (size_t i = 0; i < size; i++) {
            ExceptionCode ec = 0;
            filterValues.append(numbers->getItem(i, ec));
        }
        size = filterValues.size();

        if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20)
            || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1)
            || (filterType == FECOLORMATRIX_TYPE_SATURATE && (size != 1
                || filterValues[0] < 0.0f || filterValues[0] > 1.0f)))
            return false;
    }

    RefPtr<FilterEffect> effect = FEColorMatrix::create(input1, filterType, filterValues);
    filterResource->addFilterEffect(this, effect.release());
    
    return true;
}
ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const
{
    ComponentTransferFunction func;
    func.type = (ComponentTransferType) type();
    func.slope = slope();
    func.intercept = intercept();
    func.amplitude = amplitude();
    func.exponent = exponent();
    func.offset = offset();
    SVGNumberList* numbers = tableValues();

    ExceptionCode ec = 0;
    unsigned int nr = numbers->numberOfItems();
    for (unsigned int i = 0; i < nr; i++)
        func.tableValues.append(numbers->getItem(i, ec));
    return func;
}
Esempio n. 15
0
void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr)
{
    const String& value = attr->value();
    if (attr->name() == SVGNames::inAttr)
        setIn1BaseValue(value);
    else if (attr->name() == SVGNames::orderAttr) {
        float x, y;
        if (parseNumberOptionalNumber(value, x, y)) {
            setOrderXBaseValue(x);
            setOrderYBaseValue(y);
        }
    } else if (attr->name() == SVGNames::edgeModeAttr) {
        if (value == "duplicate")
            setEdgeModeBaseValue(EDGEMODE_DUPLICATE);
        else if (value == "wrap")
            setEdgeModeBaseValue(EDGEMODE_WRAP);
        else if (value == "none")
            setEdgeModeBaseValue(EDGEMODE_NONE);
    } else if (attr->name() == SVGNames::kernelMatrixAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedKernelMatrixListWrappers(newList.size());
        kernelMatrixBaseValue() = newList;
    } else if (attr->name() == SVGNames::divisorAttr)
        setDivisorBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::biasAttr)
        setBiasBaseValue(value.toFloat());
    else if (attr->name() == SVGNames::targetXAttr)
        setTargetXBaseValue(value.toUIntStrict());
    else if (attr->name() == SVGNames::targetYAttr)
        setTargetYBaseValue(value.toUIntStrict());
    else if (attr->name() == SVGNames::kernelUnitLengthAttr) {
        float x, y;
        if (parseNumberOptionalNumber(value, x, y)) {
            setKernelUnitLengthXBaseValue(x);
            setKernelUnitLengthYBaseValue(y);
        }
    } else if (attr->name() == SVGNames::preserveAlphaAttr) {
        if (value == "true")
            setPreserveAlphaBaseValue(true);
        else if (value == "false")
            setPreserveAlphaBaseValue(false);
    } else
        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
Esempio n. 16
0
nsresult
SVGNumberList::CopyFrom(const SVGNumberList& rhs)
{
  if (!mNumbers.SetCapacity(rhs.Length())) {
    // Yes, we do want fallible alloc here
    return NS_ERROR_OUT_OF_MEMORY;
  }
  mNumbers = rhs.mNumbers;
  return NS_OK;
}
Esempio n. 17
0
bool SVGFEColorMatrixElement::build(FilterBuilder* builder)
{
    FilterEffect* input1 = builder->getEffectById(in1());

    if(!input1)
        return false;

    Vector<float> _values;
    SVGNumberList* numbers = values();

    ExceptionCode ec = 0;
    unsigned int nr = numbers->numberOfItems();
    for (unsigned int i = 0;i < nr;i++)
        _values.append(numbers->getItem(i, ec));

    builder->add(result(), FEColorMatrix::create(input1, static_cast<ColorMatrixType> (type()), _values));
    
    return true;
}
Esempio n. 18
0
void SVGFEColorMatrixElement::parseMappedAttribute(Attribute* attr)
{
    const String& value = attr->value();
    if (attr->name() == SVGNames::typeAttr) {
        if (value == "matrix")
            setTypeBaseValue(FECOLORMATRIX_TYPE_MATRIX);
        else if (value == "saturate")
            setTypeBaseValue(FECOLORMATRIX_TYPE_SATURATE);
        else if (value == "hueRotate")
            setTypeBaseValue(FECOLORMATRIX_TYPE_HUEROTATE);
        else if (value == "luminanceToAlpha")
            setTypeBaseValue(FECOLORMATRIX_TYPE_LUMINANCETOALPHA);
    } else if (attr->name() == SVGNames::inAttr)
        setIn1BaseValue(value);
    else if (attr->name() == SVGNames::valuesAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedValuesListWrappers(newList.size());
        setValuesBaseValue(newList);
    } else
        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
Esempio n. 19
0
nsresult
SVGNumberList::SetValueFromString(const nsAString& aValue)
{
  SVGNumberList temp;

  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
    tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);

  while (tokenizer.hasMoreTokens()) {
    float num;
    if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), num)) {
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    if (!temp.AppendItem(num)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  if (tokenizer.separatorAfterCurrentToken()) {
    return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
  }
  return CopyFrom(temp);
}
Esempio n. 20
0
void SVGNumberList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, SVGPropertyBase* fromValue, SVGPropertyBase* toValue, SVGPropertyBase* toAtEndOfDurationValue, SVGElement* contextElement)
{
    SVGNumberList* fromList = toSVGNumberList(fromValue);
    SVGNumberList* toList = toSVGNumberList(toValue);
    SVGNumberList* toAtEndOfDurationList = toSVGNumberList(toAtEndOfDurationValue);

    size_t fromListSize = fromList->length();
    size_t toListSize = toList->length();
    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();

    if (!adjustFromToListValues(fromList, toList, percentage, animationElement->getAnimationMode()))
        return;

    for (size_t i = 0; i < toListSize; ++i) {
        float effectiveFrom = fromListSize ? fromList->at(i)->value() : 0;
        float effectiveTo = toListSize ? toList->at(i)->value() : 0;
        float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationList->at(i)->value() : 0;

        float animated = at(i)->value();
        animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, effectiveTo, effectiveToAtEnd, animated);
        at(i)->setValue(animated);
    }
}
void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!isSupportedAttribute(name)) {
        SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
        return;
    }

    if (name == SVGNames::inAttr) {
        setIn1BaseValue(value);
        return;
    }

    if (name == SVGNames::orderAttr) {
        float x, y;
        if (parseNumberOptionalNumber(value, x, y) && x >= 1 && y >= 1) {
            setOrderXBaseValue(x);
            setOrderYBaseValue(y);
        } else
            document().accessSVGExtensions()->reportWarning(
                "feConvolveMatrix: problem parsing order=\"" + value
                + "\". Filtered element will not be displayed.");
        return;
    }

    if (name == SVGNames::edgeModeAttr) {
        EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
        if (propertyValue > 0)
            setEdgeModeBaseValue(propertyValue);
        else
            document().accessSVGExtensions()->reportWarning(
                "feConvolveMatrix: problem parsing edgeMode=\"" + value
                + "\". Filtered element will not be displayed.");
        return;
    }

    if (name == SVGNames::kernelMatrixAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedKernelMatrixListWrappers(newList.size());
        setKernelMatrixBaseValue(newList);
        return;
    }

    if (name == SVGNames::divisorAttr) {
        float divisor = value.toFloat();
        if (divisor)
            setDivisorBaseValue(divisor);
        else
            document().accessSVGExtensions()->reportWarning(
                "feConvolveMatrix: problem parsing divisor=\"" + value
                + "\". Filtered element will not be displayed.");
        return;
    }
    
    if (name == SVGNames::biasAttr) {
        setBiasBaseValue(value.toFloat());
        return;
    }

    if (name == SVGNames::targetXAttr) {
        setTargetXBaseValue(value.string().toUIntStrict());
        return;
    }

    if (name == SVGNames::targetYAttr) {
        setTargetYBaseValue(value.string().toUIntStrict());
        return;
    }

    if (name == SVGNames::kernelUnitLengthAttr) {
        float x, y;
        if (parseNumberOptionalNumber(value, x, y) && x > 0 && y > 0) {
            setKernelUnitLengthXBaseValue(x);
            setKernelUnitLengthYBaseValue(y);
        } else
            document().accessSVGExtensions()->reportWarning(
                "feConvolveMatrix: problem parsing kernelUnitLength=\"" + value
                + "\". Filtered element will not be displayed.");
        return;
    }

    if (name == SVGNames::preserveAlphaAttr) {
        if (value == "true")
            setPreserveAlphaBaseValue(true);
        else if (value == "false")
            setPreserveAlphaBaseValue(false);
        else
            document().accessSVGExtensions()->reportWarning(
                "feConvolveMatrix: problem parsing preserveAlphaAttr=\"" + value
                + "\". Filtered element will not be displayed.");
        return;
    }

    ASSERT_NOT_REACHED();
}