示例#1
0
void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
{
    ASSERT(m_animationElement);
    ASSERT(m_contextElement);

    StyleColor fromStyleColor = m_animationElement->animationMode() == ToAnimation ? animated->color() : from->color();
    StyleColor toStyleColor = to->color();
    StyleColor toAtEndOfDurationStyleColor = toAtEndOfDuration->color();
    StyleColor& animatedStyleColor = animated->color();

    // Apply CSS inheritance rules.
    m_animationElement->adjustForInheritance<StyleColor>(parseColorFromString, m_animationElement->fromPropertyValueType(), fromStyleColor, m_contextElement);
    m_animationElement->adjustForInheritance<StyleColor>(parseColorFromString, m_animationElement->toPropertyValueType(), toStyleColor, m_contextElement);

    // Apply currentColor rules.
    Color fallbackColor = fallbackColorForCurrentColor(m_contextElement);
    Color fromColor = fromStyleColor.resolve(fallbackColor);
    Color toColor = toStyleColor.resolve(fallbackColor);
    Color toAtEndOfDurationColor = toAtEndOfDurationStyleColor.resolve(fallbackColor);
    Color animatedColor = animatedStyleColor.resolve(fallbackColor);

    float animatedRed = animatedColor.red();
    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed);

    float animatedGreen = animatedColor.green();
    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen);

    float animatedBlue = animatedColor.blue();
    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue);

    float animatedAlpha = animatedColor.alpha();
    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha);

    animatedStyleColor = StyleColor(makeRGBA(roundf(animatedRed), roundf(animatedGreen), roundf(animatedBlue), roundf(animatedAlpha)));
}
示例#2
0
void SVGColorProperty::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
{
    StyleColor fromStyleColor = toSVGColorProperty(fromValue)->m_styleColor;
    StyleColor toStyleColor = toSVGColorProperty(toValue)->m_styleColor;
    StyleColor toAtEndOfDurationStyleColor = toSVGColorProperty(toAtEndOfDurationValue)->m_styleColor;

    // Apply currentColor rules.
    ASSERT(contextElement);
    Color fallbackColor = fallbackColorForCurrentColor(contextElement);
    Color fromColor = fromStyleColor.resolve(fallbackColor);
    Color toColor = toStyleColor.resolve(fallbackColor);
    Color toAtEndOfDurationColor = toAtEndOfDurationStyleColor.resolve(fallbackColor);
    Color animatedColor = m_styleColor.resolve(fallbackColor);

    ASSERT(animationElement);
    float animatedRed = animatedColor.red();
    animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed);

    float animatedGreen = animatedColor.green();
    animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen);

    float animatedBlue = animatedColor.blue();
    animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue);

    float animatedAlpha = animatedColor.alpha();
    animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha);

    m_styleColor = StyleColor(makeRGBA(roundf(animatedRed), roundf(animatedGreen), roundf(animatedBlue), roundf(animatedAlpha)));
}
Color CSSColorInterpolationType::resolveInterpolableColor(const InterpolableValue& interpolableColor, const StyleResolverState& state, bool isVisited, bool isTextDecoration)
{
    const InterpolableList& list = toInterpolableList(interpolableColor);
    ASSERT(list.length() == InterpolableColorIndexCount);

    double red = toInterpolableNumber(list.get(Red))->value();
    double green = toInterpolableNumber(list.get(Green))->value();
    double blue = toInterpolableNumber(list.get(Blue))->value();
    double alpha = toInterpolableNumber(list.get(Alpha))->value();

    if (double currentcolorFraction = toInterpolableNumber(list.get(Currentcolor))->value()) {
        auto currentColorGetter = isVisited ? ColorPropertyFunctions::getVisitedColor : ColorPropertyFunctions::getUnvisitedColor;
        StyleColor currentStyleColor = StyleColor::currentColor();
        if (isTextDecoration)
            currentStyleColor = currentColorGetter(CSSPropertyWebkitTextFillColor, *state.style());
        if (currentStyleColor.isCurrentColor())
            currentStyleColor = currentColorGetter(CSSPropertyColor, *state.style());
        addPremultipliedColor(red, green, blue, alpha, currentcolorFraction, currentStyleColor.getColor());
    }
    const TextLinkColors& colors = state.document().textLinkColors();
    if (double webkitActivelinkFraction = toInterpolableNumber(list.get(WebkitActivelink))->value())
        addPremultipliedColor(red, green, blue, alpha, webkitActivelinkFraction, colors.activeLinkColor());
    if (double webkitLinkFraction = toInterpolableNumber(list.get(WebkitLink))->value())
        addPremultipliedColor(red, green, blue, alpha, webkitLinkFraction, isVisited ? colors.visitedLinkColor() : colors.linkColor());
    if (double quirkInheritFraction = toInterpolableNumber(list.get(QuirkInherit))->value())
        addPremultipliedColor(red, green, blue, alpha, quirkInheritFraction, colors.textColor());

    alpha = clampTo<double>(alpha, 0, 255);
    if (alpha == 0)
        return Color::transparent;

    return makeRGBA(
        round(red / alpha),
        round(green / alpha),
        round(blue / alpha),
        round(alpha));
}
示例#4
0
float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString)
{
    // FIXME: currentColor should be resolved
    ASSERT(m_contextElement);
    StyleColor from = SVGColor::colorFromRGBColorString(fromString);
    if (from.isCurrentColor())
        return -1;
    StyleColor to = SVGColor::colorFromRGBColorString(toString);
    if (to.isCurrentColor())
        return -1;
    return ColorDistance::distance(from.color(), to.color());
}
std::unique_ptr<InterpolableValue> CSSColorInterpolationType::createInterpolableColor(const StyleColor& color)
{
    if (color.isCurrentColor())
        return createInterpolableColorForIndex(Currentcolor);
    return createInterpolableColor(color.getColor());
}
bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const RenderStyle* style, const RenderStyle* rootStyle, FilterOperations& outOperations, StyleResolverState& state)
{
    ASSERT(outOperations.isEmpty());

    if (!inValue)
        return false;

    if (inValue->isPrimitiveValue()) {
        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inValue);
        if (primitiveValue->getValueID() == CSSValueNone)
            return true;
    }

    if (!inValue->isValueList())
        return false;

    float zoomFactor = (style ? style->effectiveZoom() : 1) * state.elementStyleResources().deviceScaleFactor();
    FilterOperations operations;
    for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
        CSSValue* currValue = i.value();
        if (!currValue->isCSSFilterValue())
            continue;

        CSSFilterValue* filterValue = static_cast<CSSFilterValue*>(i.value());
        FilterOperation::OperationType operationType = filterOperationForType(filterValue->operationType());

        if (operationType == FilterOperation::VALIDATED_CUSTOM) {
            // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
            ASSERT_NOT_REACHED();
            continue;
        }
        if (operationType == FilterOperation::CUSTOM) {
            RefPtr<CustomFilterOperation> operation = createCustomFilterOperation(filterValue, state);
            if (!operation)
                return false;

            operations.operations().append(operation);
            continue;
        }
        if (operationType == FilterOperation::REFERENCE) {
            if (filterValue->length() != 1)
                continue;
            CSSValue* argument = filterValue->itemWithoutBoundsCheck(0);

            if (!argument->isCSSSVGDocumentValue())
                continue;

            CSSSVGDocumentValue* svgDocumentValue = static_cast<CSSSVGDocumentValue*>(argument);
            KURL url = state.document()->completeURL(svgDocumentValue->url());

            RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), url.fragmentIdentifier(), operationType);
            if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), state.document())) {
                if (!svgDocumentValue->loadRequested())
                    state.elementStyleResources().addPendingSVGDocument(operation.get(), svgDocumentValue);
                else if (svgDocumentValue->cachedSVGDocument())
                    operation->setDocumentResourceReference(adoptPtr(new DocumentResourceReference(svgDocumentValue->cachedSVGDocument())));
            }
            operations.operations().append(operation);
            continue;
        }

        // Check that all parameters are primitive values, with the
        // exception of drop shadow which has a ShadowValue parameter.
        if (operationType != FilterOperation::DROP_SHADOW) {
            bool haveNonPrimitiveValue = false;
            for (unsigned j = 0; j < filterValue->length(); ++j) {
                if (!filterValue->itemWithoutBoundsCheck(j)->isPrimitiveValue()) {
                    haveNonPrimitiveValue = true;
                    break;
                }
            }
            if (haveNonPrimitiveValue)
                continue;
        }

        CSSPrimitiveValue* firstValue = filterValue->length() && filterValue->itemWithoutBoundsCheck(0)->isPrimitiveValue() ? toCSSPrimitiveValue(filterValue->itemWithoutBoundsCheck(0)) : 0;
        switch (filterValue->operationType()) {
        case CSSFilterValue::GrayscaleFilterOperation:
        case CSSFilterValue::SepiaFilterOperation:
        case CSSFilterValue::SaturateFilterOperation: {
            double amount = 1;
            if (filterValue->length() == 1) {
                amount = firstValue->getDoubleValue();
                if (firstValue->isPercentage())
                    amount /= 100;
            }

            operations.operations().append(BasicColorMatrixFilterOperation::create(amount, operationType));
            break;
        }
        case CSSFilterValue::HueRotateFilterOperation: {
            double angle = 0;
            if (filterValue->length() == 1)
                angle = firstValue->computeDegrees();

            operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType));
            break;
        }
        case CSSFilterValue::InvertFilterOperation:
        case CSSFilterValue::BrightnessFilterOperation:
        case CSSFilterValue::ContrastFilterOperation:
        case CSSFilterValue::OpacityFilterOperation: {
            double amount = (filterValue->operationType() == CSSFilterValue::BrightnessFilterOperation) ? 0 : 1;
            if (filterValue->length() == 1) {
                amount = firstValue->getDoubleValue();
                if (firstValue->isPercentage())
                    amount /= 100;
            }

            operations.operations().append(BasicComponentTransferFilterOperation::create(amount, operationType));
            break;
        }
        case CSSFilterValue::BlurFilterOperation: {
            Length stdDeviation = Length(0, Fixed);
            if (filterValue->length() >= 1)
                stdDeviation = convertToFloatLength(firstValue, style, rootStyle, zoomFactor);
            if (stdDeviation.isUndefined())
                return false;

            operations.operations().append(BlurFilterOperation::create(stdDeviation, operationType));
            break;
        }
        case CSSFilterValue::DropShadowFilterOperation: {
            if (filterValue->length() != 1)
                return false;

            CSSValue* cssValue = filterValue->itemWithoutBoundsCheck(0);
            if (!cssValue->isShadowValue())
                continue;

            ShadowValue* item = static_cast<ShadowValue*>(cssValue);
            IntPoint location(item->x->computeLength<int>(style, rootStyle, zoomFactor), item->y->computeLength<int>(style, rootStyle, zoomFactor));
            int blur = item->blur ? item->blur->computeLength<int>(style, rootStyle, zoomFactor) : 0;
            StyleColor shadowColor;
            if (item->color)
                shadowColor = state.document()->textLinkColors().colorFromPrimitiveValue(item->color.get());

            operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor.isValid() ? shadowColor.color() : Color::transparent, operationType));
            break;
        }
        case CSSFilterValue::UnknownFilterOperation:
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    outOperations = operations;
    return true;
}