Changeset 206713 in webkit


Ignore:
Timestamp:
Oct 1, 2016 6:05:14 PM (8 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
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r206712 r206713  
     12016-10-01  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        * transitions/background-position-transitions-expected.txt: Added.
     9        * transitions/background-position-transitions.html: Added.
     10        * transitions/resources/transition-test-helpers.js:
     11        * transitions/svg-transitions-expected.txt:
     12
    1132016-10-01  Simon Fraser  <simon.fraser@apple.com>
    214
  • trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt

    r167132 r206713  
    2323PASS - "webkitShapeOutside" property for "circle-to-bottomright-using-keyword-box" element at 1s saw something close to: circle(35% at 75% 75%)
    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

    r167132 r206713  
    147147      ["circle-to-bottomright-using-keyword-anim",  1, "circle-to-bottomright-using-keyword-box", "webkitShapeOutside", "circle(35% at 75% 75%)", 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

    r200888 r206713  
    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/LayoutTests/transitions/svg-transitions-expected.txt

    r191551 r206713  
    1 CONSOLE MESSAGE: line 293: Failed to pause 'fill' transition on element 'rect7'
     1CONSOLE MESSAGE: line 368: Failed to pause 'fill' transition on element 'rect7'
    22Example
    33PASS - "fill-opacity" property for "rect1" element at 1s saw something close to: 0.6
  • trunk/Source/WebCore/ChangeLog

    r206712 r206713  
     12016-10-01  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        Make transitions between "background-position: 10px 20px" and "background-position: right 10px bottom 20px"
     9        work. We do this by by converting "right 10px" to "calc(100% - 10px)" when blending.
     10       
     11        Also improve logging of calculated lengths, and better animation logging for FillLayer properties.
     12
     13        Test: transitions/background-position-transitions.html
     14
     15        * page/animation/CSSPropertyAnimation.cpp:
     16        (WebCore::FillLayerAnimationPropertyWrapperBase::FillLayerAnimationPropertyWrapperBase): Keep the propertyID
     17        around so logging can use it.
     18        (WebCore::FillLayerAnimationPropertyWrapperBase::property):
     19        (WebCore::FillLayerPropertyWrapperGetter::FillLayerPropertyWrapperGetter):
     20        (WebCore::FillLayerPropertyWrapperGetter::value):
     21        (WebCore::FillLayerPropertyWrapper::FillLayerPropertyWrapper):
     22        (WebCore::createCalculatedLength):
     23        (WebCore::FillLayerPositionPropertyWrapper::FillLayerPositionPropertyWrapper):
     24        (WebCore::FillLayerRefCountedPropertyWrapper::FillLayerRefCountedPropertyWrapper):
     25        (WebCore::FillLayerStyleImagePropertyWrapper::FillLayerStyleImagePropertyWrapper):
     26        (WebCore::FillLayersPropertyWrapper::FillLayersPropertyWrapper):
     27        (WebCore::CSSPropertyAnimation::blendProperties): Blend then log, so that the logging
     28        can show the result.
     29        * platform/CalculationValue.cpp:
     30        (WebCore::CalcExpressionNumber::dump):
     31        (WebCore::CalcExpressionBinaryOperation::dump):
     32        (WebCore::CalcExpressionLength::dump):
     33        (WebCore::CalcExpressionBlendLength::dump):
     34        (WebCore::operator<<):
     35        * platform/CalculationValue.h:
     36        * platform/Length.cpp:
     37        (WebCore::operator<<):
     38
    1392016-10-01  Simon Fraser  <simon.fraser@apple.com>
    240
  • trunk/Source/WebCore/css/StyleBuilderConverter.h

    r206679 r206713  
    158158#endif
    159159
    160     static Length convertTo100PercentMinusLength(const Length&);
    161160    static Length convertPositionComponent(StyleResolver&, const CSSPrimitiveValue&);
    162161
     
    310309
    311310    return LengthSize(radiusWidth, radiusHeight);
    312 }
    313 
    314 inline Length StyleBuilderConverter::convertTo100PercentMinusLength(const Length& length)
    315 {
    316     if (length.isPercent())
    317         return Length(100 - length.value(), Percent);
    318    
    319     // Turn this into a calc expression: calc(100% - length)
    320     auto lhs = std::make_unique<CalcExpressionLength>(Length(100, Percent));
    321     auto rhs = std::make_unique<CalcExpressionLength>(length);
    322     auto op = std::make_unique<CalcExpressionBinaryOperation>(WTFMove(lhs), WTFMove(rhs), CalcSubtract);
    323     return Length(CalculationValue::create(WTFMove(op), ValueRangeAll));
    324311}
    325312
  • trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp

    r206690 r206713  
    4040#include "CSSPropertyNames.h"
    4141#include "CachedImage.h"
     42#include "CalculationValue.h"
    4243#include "ClipPathOperation.h"
    4344#include "FloatConversion.h"
     
    959960    WTF_MAKE_FAST_ALLOCATED;
    960961public:
    961     FillLayerAnimationPropertyWrapperBase()
    962     {
    963     }
     962    FillLayerAnimationPropertyWrapperBase(CSSPropertyID property)
     963        : m_property(property)
     964    {
     965    }
     966   
     967    CSSPropertyID property() const { return m_property; }
    964968
    965969    virtual ~FillLayerAnimationPropertyWrapperBase() { }
     
    967971    virtual bool equals(const FillLayer*, const FillLayer*) const = 0;
    968972    virtual void blend(const AnimationBase*, FillLayer*, const FillLayer*, const FillLayer*, double) const = 0;
     973
     974#if !LOG_DISABLED
     975    virtual void logBlend(const FillLayer* result, const FillLayer*, const FillLayer*, double) const = 0;
     976#endif
     977private:
     978    CSSPropertyID m_property;
    969979};
    970980
     
    974984    WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter);
    975985public:
    976     FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
    977         : m_getter(getter)
     986    FillLayerPropertyWrapperGetter(CSSPropertyID property, T (FillLayer::*getter)() const)
     987        : FillLayerAnimationPropertyWrapperBase(property)
     988        , m_getter(getter)
    978989    {
    979990    }
     
    988999    }
    9891000
     1001    T value(const FillLayer* layer) const
     1002    {
     1003        return (layer->*m_getter)();
     1004    }
     1005
     1006#if !LOG_DISABLED
     1007    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1008    {
     1009        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1010    }
     1011#endif
     1012
    9901013protected:
    9911014    T (FillLayer::*m_getter)() const;
     
    9961019    WTF_MAKE_FAST_ALLOCATED;
    9971020public:
    998     FillLayerPropertyWrapper(const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
    999         : FillLayerPropertyWrapperGetter<const T&>(getter)
     1021    FillLayerPropertyWrapper(CSSPropertyID property, const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
     1022        : FillLayerPropertyWrapperGetter<const T&>(property, getter)
    10001023        , m_setter(setter)
    10011024    {
    10021025    }
    10031026
    1004     virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
     1027    void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override
    10051028    {
    10061029        (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), progress));
    10071030    }
     1031
     1032#if !LOG_DISABLED
     1033    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1034    {
     1035        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(FillLayerPropertyWrapperGetter<const T&>::property())
     1036            << " from " << FillLayerPropertyWrapperGetter<const T&>::value(a)
     1037            << " to " << FillLayerPropertyWrapperGetter<const T&>::value(b)
     1038            << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << FillLayerPropertyWrapperGetter<const T&>::value(result));
     1039    }
     1040#endif
    10081041
    10091042protected:
     
    10111044};
    10121045
     1046class FillLayerPositionPropertyWrapper : public FillLayerPropertyWrapperGetter<const Length&> {
     1047    WTF_MAKE_FAST_ALLOCATED;
     1048public:
     1049    FillLayerPositionPropertyWrapper(CSSPropertyID property, const Length& (FillLayer::*lengthGetter)() const, void (FillLayer::*lengthSetter)(Length), Edge (FillLayer::*originGetter)() const, void (FillLayer::*originSetter)(Edge), Edge farEdge)
     1050        : FillLayerPropertyWrapperGetter<const Length&>(property, lengthGetter)
     1051        , m_lengthSetter(lengthSetter)
     1052        , m_originGetter(originGetter)
     1053        , m_originSetter(originSetter)
     1054        , m_farEdge(farEdge)
     1055    {
     1056    }
     1057
     1058    bool equals(const FillLayer* a, const FillLayer* b) const override
     1059    {
     1060        if (a == b)
     1061            return true;
     1062        if (!a || !b)
     1063            return false;
     1064
     1065        Length fromLength = (a->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1066        Length toLength = (b->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1067       
     1068        Edge fromEdge = (a->*m_originGetter)();
     1069        Edge toEdge = (b->*m_originGetter)();
     1070       
     1071        return fromLength == toLength && fromEdge == toEdge;
     1072    }
     1073
     1074    void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override
     1075    {
     1076        Length fromLength = (a->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1077        Length toLength = (b->*FillLayerPropertyWrapperGetter<const Length&>::m_getter)();
     1078       
     1079        Edge fromEdge = (a->*m_originGetter)();
     1080        Edge toEdge = (b->*m_originGetter)();
     1081       
     1082        if (fromEdge != toEdge) {
     1083            // Convert the right/bottom into a calc expression,
     1084            if (fromEdge == m_farEdge)
     1085                fromLength = convertTo100PercentMinusLength(fromLength);
     1086            else if (toEdge == m_farEdge) {
     1087                toLength = convertTo100PercentMinusLength(toLength);
     1088                (dst->*m_originSetter)(fromEdge); // Now we have a calc(100% - l), it's relative to the left/top edge.
     1089            }
     1090        }
     1091
     1092        (dst->*m_lengthSetter)(blendFunc(anim, fromLength, toLength, progress));
     1093    }
     1094
     1095#if !LOG_DISABLED
     1096    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1097    {
     1098        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1099    }
     1100#endif
     1101
     1102protected:
     1103    void (FillLayer::*m_lengthSetter)(Length);
     1104    Edge (FillLayer::*m_originGetter)() const;
     1105    void (FillLayer::*m_originSetter)(Edge);
     1106    Edge m_farEdge;
     1107};
     1108
    10131109template <typename T>
    10141110class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> {
    10151111    WTF_MAKE_FAST_ALLOCATED;
    10161112public:
    1017     FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<T>))
    1018         : FillLayerPropertyWrapperGetter<T*>(getter)
     1113    FillLayerRefCountedPropertyWrapper(CSSPropertyID property, T* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<T>))
     1114        : FillLayerPropertyWrapperGetter<T*>(property, getter)
    10191115        , m_setter(setter)
    10201116    {
    10211117    }
    10221118
    1023     virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
     1119    void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override
    10241120    {
    10251121        (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), progress));
    10261122    }
     1123
     1124#if !LOG_DISABLED
     1125    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1126    {
     1127        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(FillLayerPropertyWrapperGetter<T*>::property())
     1128            << " from " << FillLayerPropertyWrapperGetter<T*>::value(a)
     1129            << " to " << FillLayerPropertyWrapperGetter<T*>::value(b)
     1130            << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << FillLayerPropertyWrapperGetter<T*>::value(result));
     1131    }
     1132#endif
    10271133
    10281134protected:
     
    10331139    WTF_MAKE_FAST_ALLOCATED;
    10341140public:
    1035     FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<StyleImage>))
    1036         : FillLayerRefCountedPropertyWrapper<StyleImage>(getter, setter)
     1141    FillLayerStyleImagePropertyWrapper(CSSPropertyID property, StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<StyleImage>))
     1142        : FillLayerRefCountedPropertyWrapper<StyleImage>(property, getter, setter)
    10371143    {
    10381144    }
     
    10491155        return arePointingToEqualData(imageA, imageB);
    10501156    }
     1157
     1158#if !LOG_DISABLED
     1159    void logBlend(const FillLayer* result, const FillLayer* a, const FillLayer* b, double progress) const override
     1160    {
     1161        LOG_WITH_STREAM(Animations, stream << "  blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result));
     1162    }
     1163#endif
    10511164};
    10521165
     
    10571170    typedef FillLayer& (RenderStyle::*LayersAccessor)();
    10581171
    1059     FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter, LayersAccessor accessor)
    1060         : AnimationPropertyWrapperBase(prop)
     1172    FillLayersPropertyWrapper(CSSPropertyID property, LayersGetter getter, LayersAccessor accessor)
     1173        : AnimationPropertyWrapperBase(property)
    10611174        , m_layersGetter(getter)
    10621175        , m_layersAccessor(accessor)
    10631176    {
    1064         switch (prop) {
     1177        switch (property) {
    10651178        case CSSPropertyBackgroundPositionX:
    10661179        case CSSPropertyWebkitMaskPositionX:
    1067             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::xPosition, &FillLayer::setXPosition);
     1180            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPositionPropertyWrapper>(property, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::backgroundXOrigin, &FillLayer::setBackgroundXOrigin, Edge::Right);
    10681181            break;
    10691182        case CSSPropertyBackgroundPositionY:
    10701183        case CSSPropertyWebkitMaskPositionY:
    1071             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::yPosition, &FillLayer::setYPosition);
     1184            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPositionPropertyWrapper>(property, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::backgroundYOrigin, &FillLayer::setBackgroundYOrigin, Edge::Bottom);
    10721185            break;
    10731186        case CSSPropertyBackgroundSize:
    10741187        case CSSPropertyWebkitBackgroundSize:
    10751188        case CSSPropertyWebkitMaskSize:
    1076             m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
     1189            m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(property, &FillLayer::sizeLength, &FillLayer::setSizeLength);
    10771190            break;
    10781191        case CSSPropertyBackgroundImage:
    1079             m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(&FillLayer::image, &FillLayer::setImage);
     1192            m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(property, &FillLayer::image, &FillLayer::setImage);
    10801193            break;
    10811194        default:
     
    11201233
    11211234#if !LOG_DISABLED
    1122     void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final
    1123     {
    1124         // FIXME: better logging.
    1125         LOG_WITH_STREAM(Animations, stream << "  blending FillLayers at " << TextStream::FormatNumberRespectingIntegers(progress));
     1235    void logBlend(const RenderStyle* from, const RenderStyle* to, const RenderStyle* result, double progress) const final
     1236    {
     1237        const FillLayer* aLayer = (from->*m_layersGetter)();
     1238        const FillLayer* bLayer = (to->*m_layersGetter)();
     1239        const FillLayer* dstLayer = (result->*m_layersGetter)();
     1240
     1241        while (aLayer && bLayer && dstLayer) {
     1242            m_fillLayerPropertyWrapper->logBlend(dstLayer, aLayer, bLayer, progress);
     1243            aLayer = aLayer->next();
     1244            bLayer = bLayer->next();
     1245            dstLayer = dstLayer->next();
     1246        }
    11261247    }
    11271248#endif
     
    11661287
    11671288#if !LOG_DISABLED
    1168     void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final
    1169     {
    1170         // FIXME: better logging.
    1171         LOG_WITH_STREAM(Animations, stream << "  blending shorthand property " << getPropertyName(property()) << " at " << TextStream::FormatNumberRespectingIntegers(progress));
     1289    void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* dst, double progress) const final
     1290    {
     1291        for (auto& wrapper : m_propertyWrappers)
     1292            wrapper->logBlend(a, b, dst, progress);
    11721293    }
    11731294#endif
     
    15801701    AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop);
    15811702    if (wrapper) {
     1703        wrapper->blend(anim, dst, a, b, progress);
    15821704#if !LOG_DISABLED
    15831705        wrapper->logBlend(a, b, dst, progress);
    15841706#endif
    1585         wrapper->blend(anim, dst, a, b, progress);
    15861707        return !wrapper->animationIsAccelerated() || !anim->isAccelerated();
    15871708    }
  • trunk/Source/WebCore/platform/CalculationValue.cpp

    r206043 r206713  
    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

    r206043 r206713  
    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

    r206196 r206713  
    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

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

    r206043 r206713  
    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

    r206043 r206713  
    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.