Changeset 213603 in webkit


Ignore:
Timestamp:
Mar 8, 2017 3:50:43 PM (7 years ago)
Author:
Simon Fraser
Message:

Support transitions/animations of background-position with right/bottom-relative values
https://bugs.webkit.org/show_bug.cgi?id=162048

Reviewed by Dean Jackson.
Source/WebCore:

Make transitions between "background-position: 10px 20px" and "background-position: right 10px bottom 20px"
work. We do this by by converting "right 10px" to "calc(100% - 10px)" when blending.

Also improve logging of calculated lengths, and better animation logging for FillLayer properties.

Test: transitions/background-position-transitions.html

  • page/animation/CSSPropertyAnimation.cpp:

(WebCore::FillLayerAnimationPropertyWrapperBase::FillLayerAnimationPropertyWrapperBase): Keep the propertyID
around so logging can use it.
(WebCore::FillLayerAnimationPropertyWrapperBase::property):
(WebCore::FillLayerPropertyWrapperGetter::FillLayerPropertyWrapperGetter):
(WebCore::FillLayerPropertyWrapperGetter::value):
(WebCore::FillLayerPropertyWrapper::FillLayerPropertyWrapper):
(WebCore::createCalculatedLength):
(WebCore::FillLayerPositionPropertyWrapper::FillLayerPositionPropertyWrapper):
(WebCore::FillLayerRefCountedPropertyWrapper::FillLayerRefCountedPropertyWrapper):
(WebCore::FillLayerStyleImagePropertyWrapper::FillLayerStyleImagePropertyWrapper):
(WebCore::FillLayersPropertyWrapper::FillLayersPropertyWrapper):
(WebCore::CSSPropertyAnimation::blendProperties): Blend then log, so that the logging
can show the result.

  • platform/CalculationValue.cpp:

(WebCore::CalcExpressionNumber::dump):
(WebCore::CalcExpressionBinaryOperation::dump):
(WebCore::CalcExpressionLength::dump):
(WebCore::CalcExpressionBlendLength::dump):
(WebCore::operator<<):

  • platform/CalculationValue.h:
  • platform/Length.cpp:

(WebCore::operator<<):

LayoutTests:

  • transitions/background-position-transitions-expected.txt: Added.
  • transitions/background-position-transitions.html: Added.
  • transitions/resources/transition-test-helpers.js:
  • transitions/svg-transitions-expected.txt:
Location:
trunk
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r213600 r213603  
     12017-03-08  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Support transitions/animations of background-position with right/bottom-relative values
     4        https://bugs.webkit.org/show_bug.cgi?id=162048
     5
     6        Reviewed by Dean Jackson.
     7
     8        Re-landing r206713.
     9
     10        * transitions/background-position-transitions-expected.txt: Added.
     11        * transitions/background-position-transitions.html: Added.
     12        * transitions/resources/transition-test-helpers.js:
     13        * transitions/svg-transitions-expected.txt:
     14
    1152017-03-08  Simon Fraser  <simon.fraser@apple.com>
    216
  • trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt

    r209537 r213603  
    2323PASS - "webkitShapeOutside" property for "circle-to-bottomright-using-keyword-box" element at 1s saw something close to: circle(35% at calc((50% * 0.5) + ((100% - 0px) * 0.5)) calc((50% * 0.5) + ((100% - 0px) * 0.5)))
    2424PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-box" element at 1s saw something close to: circle(35% at 75% 75%)
    25 PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-box" element at 1s saw something close to: circle(35% at calc((50% * 0.5) + ((100% - 10%) * 0.5)) calc((50% * 0.5) + ((100% - 20px) * 0.5)))
    26 PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-2-box" element at 1s saw something close to: circle(35% at calc((50% * 0.5) + ((100% - 10%) * 0.5)) calc((50% * 0.5) + ((100% - 10px) * 0.5)))
     25PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-box" element at 1s saw something close to: circle(35% at 70% calc((50% * 0.5) + ((100% - 20px) * 0.5)))
     26PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-2-box" element at 1s saw something close to: circle(35% at 70% calc((50% * 0.5) + ((100% - 10px) * 0.5)))
    2727
  • trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation.html

    r209537 r213603  
    147147      ["circle-to-bottomright-using-keyword-anim",  1, "circle-to-bottomright-using-keyword-box", "webkitShapeOutside", "circle(35% at calc((50% * 0.5) + ((100% - 0px) * 0.5)) calc((50% * 0.5) + ((100% - 0px) * 0.5)))", 0.05],
    148148      ["circle-to-bottomright-extended-anim",  1, "circle-to-bottomright-extended-box", "webkitShapeOutside", "circle(35% at 75% 75%)", 0.05],
    149       ["circle-to-bottomright-extended-using-keyword-anim",  1, "circle-to-bottomright-extended-using-keyword-box", "webkitShapeOutside", "circle(35% at calc((50% * 0.5) + ((100% - 10%) * 0.5)) calc((50% * 0.5) + ((100% - 20px) * 0.5)))", 0.01],
    150       ["circle-to-bottomright-extended-using-keyword-2-anim",  1, "circle-to-bottomright-extended-using-keyword-2-box", "webkitShapeOutside", "circle(35% at calc((50% * 0.5) + ((100% - 10%) * 0.5)) calc((50% * 0.5) + ((100% - 10px) * 0.5)))", 0.01],
     149      ["circle-to-bottomright-extended-using-keyword-anim",  1, "circle-to-bottomright-extended-using-keyword-box", "webkitShapeOutside", "circle(35% at 70% calc((50% * 0.5) + ((100% - 20px) * 0.5)))", 0.01],
     150      ["circle-to-bottomright-extended-using-keyword-2-anim",  1, "circle-to-bottomright-extended-using-keyword-2-box", "webkitShapeOutside", "circle(35% at 70% calc((50% * 0.5) + ((100% - 10px) * 0.5)))", 0.01],
    151151    ];
    152152   
  • trunk/LayoutTests/transitions/resources/transition-test-helpers.js

    r206894 r213603  
    109109    window.console.log('failed to match ' + s);
    110110    return null;
     111}
     112
     113function hasFloatValue(value)
     114{
     115    switch (value.primitiveType) {
     116    case CSSPrimitiveValue.CSS_FR:
     117    case CSSPrimitiveValue.CSS_NUMBER:
     118    case CSSPrimitiveValue.CSS_PARSER_INTEGER:
     119    case CSSPrimitiveValue.CSS_PERCENTAGE:
     120    case CSSPrimitiveValue.CSS_EMS:
     121    case CSSPrimitiveValue.CSS_EXS:
     122    case CSSPrimitiveValue.CSS_CHS:
     123    case CSSPrimitiveValue.CSS_REMS:
     124    case CSSPrimitiveValue.CSS_PX:
     125    case CSSPrimitiveValue.CSS_CM:
     126    case CSSPrimitiveValue.CSS_MM:
     127    case CSSPrimitiveValue.CSS_IN:
     128    case CSSPrimitiveValue.CSS_PT:
     129    case CSSPrimitiveValue.CSS_PC:
     130    case CSSPrimitiveValue.CSS_DEG:
     131    case CSSPrimitiveValue.CSS_RAD:
     132    case CSSPrimitiveValue.CSS_GRAD:
     133    case CSSPrimitiveValue.CSS_TURN:
     134    case CSSPrimitiveValue.CSS_MS:
     135    case CSSPrimitiveValue.CSS_S:
     136    case CSSPrimitiveValue.CSS_HZ:
     137    case CSSPrimitiveValue.CSS_KHZ:
     138    case CSSPrimitiveValue.CSS_DIMENSION:
     139    case CSSPrimitiveValue.CSS_VW:
     140    case CSSPrimitiveValue.CSS_VH:
     141    case CSSPrimitiveValue.CSS_VMIN:
     142    case CSSPrimitiveValue.CSS_VMAX:
     143    case CSSPrimitiveValue.CSS_DPPX:
     144    case CSSPrimitiveValue.CSS_DPI:
     145    case CSSPrimitiveValue.CSS_DPCM:
     146        return true;
     147    }
     148    return false;
     149}
     150
     151function getNumericValue(cssValue)
     152{
     153    if (hasFloatValue(cssValue.primitiveType))
     154        return cssValue.getFloatValue(cssValue.primitiveType);
     155
     156    return -1;
     157}
     158
     159function isCalcPrimitiveValue(value)
     160{
     161    switch (value.primitiveType) {
     162    case 113: // CSSPrimitiveValue.CSS_CALC:
     163    case 114: // CSSPrimitiveValue.CSS_CALC_PERCENTAGE_WITH_NUMBER:
     164    case 115: // CSSPrimitiveValue.CSS_CALC_PERCENTAGE_WITH_LENGTH:
     165    return true;
     166    }
     167    return false;
     168}
     169
     170function extractNumbersFromCalcExpression(value, values)
     171{
     172    var calcRegexp = /^calc\((.+)\)$/;
     173    var result = calcRegexp.exec(value.cssText);
     174    var numberMatch = /([^\.\-0-9]*)(-?[\.0-9]+)/;
     175    var remainder = result[1];
     176    var match;
     177    while ((match = numberMatch.exec(remainder)) !== null) {
     178        var skipLength = match[1].length + match[2].length;
     179        values.push(parseFloat(match[2]))
     180        remainder = remainder.substr(skipLength + 1);
     181    }
    111182}
    112183
     
    195266            var values = [];
    196267            for (var i = 0; i < computedStyle.length; ++i) {
    197                 switch (computedStyle[i].cssValueType) {
     268                var styleValue = computedStyle[i];
     269                switch (styleValue.cssValueType) {
    198270                  case CSSValue.CSS_PRIMITIVE_VALUE:
    199                     values.push(computedStyle[i].getFloatValue(CSSPrimitiveValue.CSS_NUMBER));
     271                    if (hasFloatValue(styleValue))
     272                        values.push(styleValue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER));
     273                    else if (isCalcPrimitiveValue(styleValue))
     274                        extractNumbersFromCalcExpression(styleValue, values);
    200275                    break;
    201276                  case CSSValue.CSS_CUSTOM:
    202277                    // arbitrarily pick shadow-x and shadow-y
    203278                    if (isShadow) {
    204                       var shadowXY = getShadowXY(computedStyle[i]);
     279                      var shadowXY = getShadowXY(styleValue);
    205280                      values.push(shadowXY[0]);
    206281                      values.push(shadowXY[1]);
    207282                    } else
    208                       values.push(computedStyle[i].cssText);
     283                      values.push(styleValue.cssText);
    209284                    break;
    210285                }
    211286            }
    212287            computedValue = values.join(',');
    213             pass = true;
     288            pass = values.length > 0;
    214289            for (var i = 0; i < values.length; ++i)
    215290                pass &= isCloseEnough(values[i], expectedValue[i], tolerance);
  • trunk/Source/WebCore/ChangeLog

    r213601 r213603  
     12017-03-08  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Support transitions/animations of background-position with right/bottom-relative values
     4        https://bugs.webkit.org/show_bug.cgi?id=162048
     5
     6        Reviewed by Dean Jackson.
     7       
     8        Re-landing r206713.
     9       
     10        Make transitions between "background-position: 10px 20px" and "background-position: right 10px bottom 20px"
     11        work. We do this by by converting "right 10px" to "calc(100% - 10px)" when blending.
     12       
     13        Also improve logging of calculated lengths, and better animation logging for FillLayer properties.
     14
     15        Test: transitions/background-position-transitions.html
     16
     17        * page/animation/CSSPropertyAnimation.cpp:
     18        (WebCore::FillLayerAnimationPropertyWrapperBase::FillLayerAnimationPropertyWrapperBase): Keep the propertyID
     19        around so logging can use it.
     20        (WebCore::FillLayerAnimationPropertyWrapperBase::property):
     21        (WebCore::FillLayerPropertyWrapperGetter::FillLayerPropertyWrapperGetter):
     22        (WebCore::FillLayerPropertyWrapperGetter::value):
     23        (WebCore::FillLayerPropertyWrapper::FillLayerPropertyWrapper):
     24        (WebCore::createCalculatedLength):
     25        (WebCore::FillLayerPositionPropertyWrapper::FillLayerPositionPropertyWrapper):
     26        (WebCore::FillLayerRefCountedPropertyWrapper::FillLayerRefCountedPropertyWrapper):
     27        (WebCore::FillLayerStyleImagePropertyWrapper::FillLayerStyleImagePropertyWrapper):
     28        (WebCore::FillLayersPropertyWrapper::FillLayersPropertyWrapper):
     29        (WebCore::CSSPropertyAnimation::blendProperties): Blend then log, so that the logging
     30        can show the result.
     31        * platform/CalculationValue.cpp:
     32        (WebCore::CalcExpressionNumber::dump):
     33        (WebCore::CalcExpressionBinaryOperation::dump):
     34        (WebCore::CalcExpressionLength::dump):
     35        (WebCore::CalcExpressionBlendLength::dump):
     36        (WebCore::operator<<):
     37        * platform/CalculationValue.h:
     38        * platform/Length.cpp:
     39        (WebCore::operator<<):
     40
    1412017-03-08  Anders Carlsson  <andersca@apple.com>
    242
  • trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp

    r211741 r213603  
    4040#include "CSSPropertyNames.h"
    4141#include "CachedImage.h"
     42#include "CalculationValue.h"
    4243#include "ClipPathOperation.h"
    4344#include "FloatConversion.h"
     
    958959    WTF_MAKE_FAST_ALLOCATED;
    959960public:
    960     FillLayerAnimationPropertyWrapperBase()
    961     {
    962     }
     961    FillLayerAnimationPropertyWrapperBase(CSSPropertyID property)
     962        : m_property(property)
     963    {
     964    }
     965   
     966    CSSPropertyID property() const { return m_property; }
    963967
    964968    virtual ~FillLayerAnimationPropertyWrapperBase() { }
     
    966970    virtual bool equals(const FillLayer*, const FillLayer*) const = 0;
    967971    virtual void blend(const AnimationBase*, FillLayer*, const FillLayer*, const FillLayer*, double) const = 0;
     972
     973#if !LOG_DISABLED
     974    virtual void logBlend(const FillLayer* result, const FillLayer*, const FillLayer*, double) const = 0;
     975#endif
     976private:
     977    CSSPropertyID m_property;
    968978};
    969979
     
    973983    WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter);
    974984public:
    975     FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
    976         : m_getter(getter)
     985    FillLayerPropertyWrapperGetter(CSSPropertyID property, T (FillLayer::*getter)() const)
     986        : FillLayerAnimationPropertyWrapperBase(property)
     987        , m_getter(getter)
    977988    {
    978989    }
     
    987998    }
    988999
     1000    T value(const FillLayer* layer) const
     1001    {
     1002        return (layer->*m_getter)();
     1003    }
     1004
     1005#if !LOG_DISABLED
     1006    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1007    {
     1008        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1009    }
     1010#endif
     1011
    9891012protected:
    9901013    T (FillLayer::*m_getter)() const;
     
    9951018    WTF_MAKE_FAST_ALLOCATED;
    9961019public:
    997     FillLayerPropertyWrapper(const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
    998         : FillLayerPropertyWrapperGetter<const T&>(getter)
     1020    FillLayerPropertyWrapper(CSSPropertyID property, const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
     1021        : FillLayerPropertyWrapperGetter<const T&>(property, getter)
    9991022        , m_setter(setter)
    10001023    {
     
    10051028        (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), progress));
    10061029    }
     1030
     1031#if !LOG_DISABLED
     1032    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1033    {
     1034        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(FillLayerPropertyWrapperGetter<const T&>::property())
     1035            << " from " << FillLayerPropertyWrapperGetter<const T&>::value(a)
     1036            << " to " << FillLayerPropertyWrapperGetter<const T&>::value(b)
     1037            << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << FillLayerPropertyWrapperGetter<const T&>::value(result));
     1038    }
     1039#endif
    10071040
    10081041protected:
     
    10101043};
    10111044
     1045class FillLayerPositionPropertyWrapper : public FillLayerPropertyWrapperGetter<const Length&> {
     1046    WTF_MAKE_FAST_ALLOCATED;
     1047public:
     1048    FillLayerPositionPropertyWrapper(CSSPropertyID property, const Length& (FillLayer::*lengthGetter)() const, void (FillLayer::*lengthSetter)(Length), Edge (FillLayer::*originGetter)() const, void (FillLayer::*originSetter)(Edge), Edge farEdge)
     1049        : FillLayerPropertyWrapperGetter<const Length&>(property, lengthGetter)
     1050        , m_lengthSetter(lengthSetter)
     1051        , m_originGetter(originGetter)
     1052        , m_originSetter(originSetter)
     1053        , m_farEdge(farEdge)
     1054    {
     1055    }
     1056
     1057    bool equals(const FillLayer* a, const FillLayer* b) const override
     1058    {
     1059        if (a == b)
     1060            return true;
     1061        if (!a || !b)
     1062            return false;
     1063
     1064        Length fromLength = (a->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1065        Length toLength = (b->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1066       
     1067        Edge fromEdge = (a->*m_originGetter)();
     1068        Edge toEdge = (b->*m_originGetter)();
     1069       
     1070        return fromLength == toLength && fromEdge == toEdge;
     1071    }
     1072
     1073    void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override
     1074    {
     1075        Length fromLength = (a->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1076        Length toLength = (b->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1077       
     1078        Edge fromEdge = (a->*m_originGetter)();
     1079        Edge toEdge = (b->*m_originGetter)();
     1080       
     1081        if (fromEdge != toEdge) {
     1082            // Convert the right/bottom into a calc expression,
     1083            if (fromEdge == m_farEdge)
     1084                fromLength = convertTo100PercentMinusLength(fromLength);
     1085            else if (toEdge == m_farEdge) {
     1086                toLength = convertTo100PercentMinusLength(toLength);
     1087                (dst->*m_originSetter)(fromEdge); // Now we have a calc(100% - l), it's relative to the left/top edge.
     1088            }
     1089        }
     1090
     1091        (dst->*m_lengthSetter)(blendFunc(anim, fromLength, toLength, progress));
     1092    }
     1093
     1094#if !LOG_DISABLED
     1095    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1096    {
     1097        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1098    }
     1099#endif
     1100
     1101protected:
     1102    void (FillLayer::*m_lengthSetter)(Length);
     1103    Edge (FillLayer::*m_originGetter)() const;
     1104    void (FillLayer::*m_originSetter)(Edge);
     1105    Edge m_farEdge;
     1106};
     1107
    10121108template <typename T>
    10131109class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> {
    10141110    WTF_MAKE_FAST_ALLOCATED;
    10151111public:
    1016     FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<T>&&))
    1017         : FillLayerPropertyWrapperGetter<T*>(getter)
     1112    FillLayerRefCountedPropertyWrapper(CSSPropertyID property, T* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<T>&&))
     1113        : FillLayerPropertyWrapperGetter<T*>(property, getter)
    10181114        , m_setter(setter)
    10191115    {
     
    10241120        (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), progress));
    10251121    }
     1122
     1123#if !LOG_DISABLED
     1124    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1125    {
     1126        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(FillLayerPropertyWrapperGetter<T*>::property())
     1127            << " from " << FillLayerPropertyWrapperGetter<T*>::value(a)
     1128            << " to " << FillLayerPropertyWrapperGetter<T*>::value(b)
     1129            << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << FillLayerPropertyWrapperGetter<T*>::value(result));
     1130    }
     1131#endif
    10261132
    10271133protected:
     
    10321138    WTF_MAKE_FAST_ALLOCATED;
    10331139public:
    1034     FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<StyleImage>&&))
    1035         : FillLayerRefCountedPropertyWrapper<StyleImage>(getter, setter)
     1140    FillLayerStyleImagePropertyWrapper(CSSPropertyID property, StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<StyleImage>&&))
     1141        : FillLayerRefCountedPropertyWrapper<StyleImage>(property, getter, setter)
    10361142    {
    10371143    }
     
    10481154        return arePointingToEqualData(imageA, imageB);
    10491155    }
     1156
     1157#if !LOG_DISABLED
     1158    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1159    {
     1160        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1161    }
     1162#endif
    10501163};
    10511164
     
    10561169    typedef FillLayer& (RenderStyle::*LayersAccessor)();
    10571170
    1058     FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter, LayersAccessor accessor)
    1059         : AnimationPropertyWrapperBase(prop)
     1171    FillLayersPropertyWrapper(CSSPropertyID property, LayersGetter getter, LayersAccessor accessor)
     1172        : AnimationPropertyWrapperBase(property)
    10601173        , m_layersGetter(getter)
    10611174        , m_layersAccessor(accessor)
    10621175    {
    1063         switch (prop) {
     1176        switch (property) {
    10641177        case CSSPropertyBackgroundPositionX:
    10651178        case CSSPropertyWebkitMaskPositionX:
    1066             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::xPosition, &FillLayer::setXPosition);
     1179            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPositionPropertyWrapper>(property, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::backgroundXOrigin, &FillLayer::setBackgroundXOrigin, Edge::Right);
    10671180            break;
    10681181        case CSSPropertyBackgroundPositionY:
    10691182        case CSSPropertyWebkitMaskPositionY:
    1070             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::yPosition, &FillLayer::setYPosition);
     1183            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPositionPropertyWrapper>(property, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::backgroundYOrigin, &FillLayer::setBackgroundYOrigin, Edge::Bottom);
    10711184            break;
    10721185        case CSSPropertyBackgroundSize:
    10731186        case CSSPropertyWebkitBackgroundSize:
    10741187        case CSSPropertyWebkitMaskSize:
    1075             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
     1188            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(property, &FillLayer::sizeLength, &FillLayer::setSizeLength);
    10761189            break;
    10771190        case CSSPropertyBackgroundImage:
    1078             m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(&FillLayer::image, &FillLayer::setImage);
     1191            m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(property, &FillLayer::image, &FillLayer::setImage);
    10791192            break;
    10801193        default:
     
    11191232
    11201233#if !LOG_DISABLED
    1121     void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final
    1122     {
    1123         // FIXME: better logging.
    1124         LOG_WITH_STREAM(Animations, stream << "  blending FillLayers at " << TextStream::FormatNumberRespectingIntegers(progress));
     1234    void logBlend(const RenderStyle* from, const RenderStyle* to, const RenderStyle* result, double progress) const final
     1235    {
     1236        auto* aLayer = &(from->*m_layersGetter)();
     1237        auto* bLayer = &(to->*m_layersGetter)();
     1238        auto* dstLayer = &(result->*m_layersGetter)();
     1239
     1240        while (aLayer && bLayer && dstLayer) {
     1241            m_fillLayerPropertyWrapper->logBlend(dstLayer, aLayer, bLayer, progress);
     1242            aLayer = aLayer->next();
     1243            bLayer = bLayer->next();
     1244            dstLayer = dstLayer->next();
     1245        }
    11251246    }
    11261247#endif
     
    11651286
    11661287#if !LOG_DISABLED
    1167     void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final
    1168     {
    1169         // FIXME: better logging.
    1170         LOG_WITH_STREAM(Animations, stream << "  blending shorthand property " << getPropertyName(property()) << " at " << TextStream::FormatNumberRespectingIntegers(progress));
     1288    void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* dst, double progress) const final
     1289    {
     1290        for (auto& wrapper : m_propertyWrappers)
     1291            wrapper->logBlend(a, b, dst, progress);
    11711292    }
    11721293#endif
  • trunk/Source/WebCore/platform/CalculationValue.cpp

    r206894 r213603  
    3232#include "config.h"
    3333#include "CalculationValue.h"
     34#include "TextStream.h"
    3435
    3536#include <limits>
     
    4546{
    4647    return m_value;
     48}
     49
     50void CalcExpressionNumber::dump(TextStream& ts) const
     51{
     52    ts << TextStream::FormatNumberRespectingIntegers(m_value);
    4753}
    4854
     
    8793}
    8894
     95void CalcExpressionBinaryOperation::dump(TextStream& ts) const
     96{
     97    ts << *m_leftSide << " " << m_operator << " " << *m_rightSide;
     98}
     99
    89100float CalcExpressionLength::evaluate(float maxValue) const
    90101{
     
    95106{
    96107    return other.type() == CalcExpressionNodeLength && *this == toCalcExpressionLength(other);
     108}
     109
     110void CalcExpressionLength::dump(TextStream& ts) const
     111{
     112    ts << m_length;
    97113}
    98114
     
    107123}
    108124
     125void CalcExpressionBlendLength::dump(TextStream& ts) const
     126{
     127    ts << "blend(" << m_from << ", " << m_to << ", " << m_progress << ")";
     128}
     129
     130TextStream& operator<<(TextStream& ts, CalcOperator op)
     131{
     132    switch (op) {
     133    case CalcAdd: ts << "+"; break;
     134    case CalcSubtract: ts << "-"; break;
     135    case CalcMultiply: ts << "*"; break;
     136    case CalcDivide: ts << "/"; break;
     137    }
     138    return ts;
     139}
     140
     141TextStream& operator<<(TextStream& ts, const CalculationValue& value)
     142{
     143    ts << "calc(";
     144    ts << value.expression();
     145    ts << ")";
     146    return ts;
     147}
     148
     149TextStream& operator<<(TextStream& ts, const CalcExpressionNode& expressionNode)
     150{
     151    expressionNode.dump(ts);
     152    return ts;
     153}
     154
    109155} // namespace WebCore
  • trunk/Source/WebCore/platform/CalculationValue.h

    r206894 r213603  
    4040namespace WebCore {
    4141
     42class TextStream;
     43
    4244enum CalcOperator {
    4345    CalcAdd = '+',
     
    6567    virtual float evaluate(float maxValue) const = 0;
    6668    virtual bool operator==(const CalcExpressionNode&) const = 0;
     69    virtual void dump(TextStream&) const = 0;
    6770
    6871private:
     
    7982    float evaluate(float) const override;
    8083    bool operator==(const CalcExpressionNode&) const override;
     84    void dump(TextStream&) const override;
    8185
    8286    float m_value;
     
    9296    float evaluate(float maxValue) const override;
    9397    bool operator==(const CalcExpressionNode&) const override;
     98    void dump(TextStream&) const override;
    9499
    95100    Length m_length;
     
    107112    float evaluate(float maxValue) const override;
    108113    bool operator==(const CalcExpressionNode&) const override;
     114    void dump(TextStream&) const override;
    109115
    110116    std::unique_ptr<CalcExpressionNode> m_leftSide;
     
    124130    float evaluate(float maxValue) const override;
    125131    bool operator==(const CalcExpressionNode&) const override;
     132    void dump(TextStream&) const override;
    126133
    127134    Length m_from;
     
    233240}
    234241
     242TextStream& operator<<(TextStream&, const CalculationValue&);
     243TextStream& operator<<(TextStream&, const CalcExpressionNode&);
     244TextStream& operator<<(TextStream&, CalcOperator);
     245
    235246} // namespace WebCore
    236247
  • trunk/Source/WebCore/platform/Length.cpp

    r206894 r213603  
    285285}
    286286
     287Length convertTo100PercentMinusLength(const Length& length)
     288{
     289    if (length.isPercent())
     290        return Length(100 - length.value(), Percent);
     291   
     292    // Turn this into a calc expression: calc(100% - length)
     293    auto lhs = std::make_unique<CalcExpressionLength>(Length(100, Percent));
     294    auto rhs = std::make_unique<CalcExpressionLength>(length);
     295    auto op = std::make_unique<CalcExpressionBinaryOperation>(WTFMove(lhs), WTFMove(rhs), CalcSubtract);
     296    return Length(CalculationValue::create(WTFMove(op), ValueRangeAll));
     297}
     298
    287299static Length blendMixedTypes(const Length& from, const Length& to, double progress)
    288300{
     
    371383        break;
    372384    case Calculated:
    373         // FIXME: dump CalculationValue.
    374         ts << "calc(...)";
     385        ts << length.calculationValue();
    375386        break;
    376387    }
  • trunk/Source/WebCore/platform/Length.h

    r206894 r213603  
    416416}
    417417
     418Length convertTo100PercentMinusLength(const Length&);
     419
    418420TextStream& operator<<(TextStream&, Length);
    419421
  • trunk/Source/WebCore/rendering/style/BasicShapes.cpp

    r210758 r213603  
    5353        return;
    5454    }
     55
    5556    if (m_length.isUndefined()) {
    5657        m_computedLength = Length(100, Percent);
    5758        return;
    5859    }
    59 
    60     auto lhs = std::make_unique<CalcExpressionLength>(Length(100, Percent));
    61     auto rhs = std::make_unique<CalcExpressionLength>(m_length);
    62     auto op = std::make_unique<CalcExpressionBinaryOperation>(WTFMove(lhs), WTFMove(rhs), CalcSubtract);
    63     m_computedLength = Length(CalculationValue::create(WTFMove(op), ValueRangeAll));
     60   
     61    m_computedLength = convertTo100PercentMinusLength(m_length);
    6462}
    6563
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/CalculationValue.cpp

    r206894 r213603  
    2828#include <WebCore/CalculationValue.h>
    2929
     30namespace WebCore {
     31class TextStream;
     32};
     33
    3034namespace TestWebKitAPI {
    3135
     
    4145    float evaluate(float) const override { return 0; }
    4246    bool operator==(const CalcExpressionNode&) const override { ASSERT_NOT_REACHED(); return false; }
     47
     48private:
     49    void dump(WebCore::TextStream&) const override { };
    4350};
    4451
Note: See TracChangeset for help on using the changeset viewer.